/* ============================================================================
 * OFGPT — THEME: B² · Modern Light
 * ----------------------------------------------------------------------------
 *   · Warm off-white shell (#FAFAF9) + pure-white cards.
 *   · Single editorial-blue accent (#2A78D6, HSL 212/69/50).
 *   · Cream user bubble (#FBF5E9) with an amber left rule (#E0B65E).
 *   · Geist Sans (UI) + Geist Mono (data / code / labels).
 *   · Light viewer canvas with soft blue radial glow + hairline grid overlay.
 *   · Flat surfaces, hair borders, 5–6 px radii (small, precise).
 * ============================================================================ */

:root {
  /* ---------- SURFACES ---------- */
  --b2-bg:        #FAFAF9;        /* shell / viewer / rails — warm off-white */
  --b2-surface:   #FFFFFF;        /* messages / cards / inputs */
  --b2-sunken:    #F3F4F6;        /* hover / toolbar / group headers */
  --b2-raised:    #F8FAFC;        /* secondary hover */

  --b2-line:      #E5E7EB;
  --b2-line-2:    #D1D5DB;
  --b2-line-strong: #9CA3AF;

  /* ---------- INK (text) ---------- */
  --b2-ink:       #111216;
  --b2-ink-2:     #4B5563;
  --b2-ink-3:     #6B7280;
  --b2-ink-4:     #9CA3AF;
  --b2-ink-5:     #C2C7CE;

  /* ---------- SINGLE ACCENT (calm cool blue) ---------- */
  --b2-acc:       #2A78D6;        /* muted editorial blue, sits closer to cream */
  --b2-acc-ink:   #1E5AA8;        /* darker shade for text-on-soft-bg         */
  --b2-acc-hover: #1F61B8;        /* hover fill (one step darker)             */
  --b2-acc-soft:  rgba(42,120,214,0.10);
  --b2-acc-soft-2:rgba(42,120,214,0.18);
  --b2-acc-line:  rgba(42,120,214,0.28);
  --b2-acc-focus: rgba(42,120,214,0.22);

  /* ---------- USER BUBBLE (cream + amber rule) ---------- */
  --b2-user-bg:   #FBF5E9;
  --b2-user-rule: #E0B65E;
  --b2-user-code-bg: #FBF1E6;
  --b2-user-code-fg: #B55B00;

  /* ---------- SEMANTIC ---------- */
  --b2-ok:        #0E9F6E;
  --b2-err:       #DC2626;
  --b2-warn:      #B54708;

  /* ---------- FONTS ---------- */
  --f-sans:  'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --f-mono:  'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;

  /* ---------- re-map main.css tokens ---------- */
  --primary:          var(--b2-acc);
  --primary-dark:     var(--b2-acc-ink);
  --primary-bg:       var(--b2-acc-soft);
  --gradient-primary: var(--b2-acc);

  --primary-text:    var(--b2-ink);
  --secondary-text:  var(--b2-ink-3);
  --muted-text:      var(--b2-ink-4);

  --message-bg:      var(--b2-surface);
  --sidebar-bg:      var(--b2-bg);
  --border-light:    var(--b2-line);
  --border-lighter:  var(--b2-line);
  --white:           var(--b2-surface);
  --hover-bg:        var(--b2-sunken);

  --user-msg-bg:     var(--b2-user-bg);
  --user-msg-text:   var(--b2-ink);
  --ai-msg-bg:       var(--b2-surface);
  --ai-msg-text:     var(--b2-ink);

  --text-primary:    var(--b2-ink);
  --text-secondary:  var(--b2-ink-3);
  --bg-primary:      var(--b2-bg);
  --bg-secondary:    var(--b2-surface);
  --border-color:    var(--b2-line);
}

/* ============================================================================
 * Base
 * ========================================================================== */
html, body { background: var(--b2-bg); }
body {
  font-family: var(--f-sans) !important;
  color: var(--b2-ink) !important;
  font-size: 13px !important;
  line-height: 1.55 !important;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "ss01","cv11";
}

/* scrollbars — light, minimal */
::-webkit-scrollbar           { width: 9px; height: 9px; }
::-webkit-scrollbar-track     { background: transparent; }
::-webkit-scrollbar-thumb     { background: var(--b2-line-2); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--b2-ink-4); }

/* monospace surfaces */
.mono, .monospace,
.message-content code, .msg-text code,
.message-content pre, .msg-text pre,
.activity-chip .tool-chip-count,
.slice-position-value,
.slice-preview-info,
.slice-radio-label,
.file-tree-item .file-name,
.file-content-body pre,
.file-content-body code,
.conversation-meta,
.message-timestamp,
.case-id,
.msg-label,
.progress-step,
#trameColorbarTitle, #trameColorbarMin, #trameColorbarMid, #trameColorbarMax,
.trame-file-item .file-name,
.slice-label {
  font-family: var(--f-mono) !important;
  font-variant-numeric: tabular-nums;
}

/* headings in chrome */
.chat-header h1,
.chat-header button {
  font-family: var(--f-sans) !important;
  letter-spacing: -0.015em;
}

/* ============================================================================
 * Selection
 * ========================================================================== */
::selection       { background: var(--b2-acc-soft-2); color: var(--b2-acc-ink); }
::-moz-selection  { background: var(--b2-acc-soft-2); color: var(--b2-acc-ink); }

/* ============================================================================
 * Focus ring
 * ========================================================================== */
button:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: 2px solid var(--b2-acc-focus) !important;
  outline-offset: 1px !important;
}

/* kill rounded pills that don't match B² (small 5–6 px) */
.chat-header, .conv-item, .message, .new-chat-btn,
.history-sidebar, .slice-control-panel, .pdf-panel,
.conversation-item, .file-tree-item, .file-item {
  border-radius: 5px;
}

/* ============================================================================
 * App shell — the global containers
 * ========================================================================== */
.container { background: var(--b2-bg) !important; }
.chat-panel { background: var(--b2-bg) !important; }

/* ============================================================================
 * Left sidebar (history)
 * ========================================================================== */
.history-sidebar {
  background: var(--b2-bg) !important;
  border-right: 1px solid var(--b2-line) !important;
  padding: 0 !important;
  display: flex !important;
  flex-direction: column !important;
}

/* sidebar header — lock to 40 px so its bottom border aligns with .chat-header */
.sidebar-header {
  height: 40px !important;
  min-height: 40px !important;
  max-height: 40px !important;
  padding: 0 10px !important;
  border-bottom: 1px solid var(--b2-line) !important;
  background: var(--b2-bg) !important;
  display: flex !important;
  align-items: center !important;
  flex: 0 0 40px !important;
}
.sidebar-header .new-chat-btn {
  margin: 0 !important;
  height: 28px !important;
  min-height: 28px !important;
}
.conversation-list {
  flex: 1 1 auto !important;
  overflow-y: auto !important;
}

/* Top header in left + chat column */
.chat-header {
  background: var(--b2-bg) !important;
  border-bottom: 1px solid var(--b2-line) !important;
  height: 40px !important;
  padding: 0 16px !important;
}

.chat-header h1 {
  font-family: var(--f-sans) !important;
  font-weight: 600 !important;
  font-size: 14px !important;
  color: var(--b2-ink) !important;
  letter-spacing: -0.015em !important;
}

.chat-header button {
  background: transparent !important;
  border: 0 !important;
  color: var(--b2-ink-3) !important;
  font-size: 12px !important;
  padding: 6px 8px !important;
  border-radius: 4px !important;
  transition: color .12s !important;
}
.chat-header button:hover {
  color: var(--b2-ink) !important;
  background: var(--b2-sunken) !important;
}

/* column resizer */
.panel-resizer {
  background: transparent !important;
}
.panel-resizer::before { background: var(--b2-ink-4) !important; opacity: 0.35 !important; }
.panel-resizer:hover,
body.resizing .panel-resizer { background: var(--b2-acc) !important; }

/* ============================================================================
 * New chat button
 * ========================================================================== */
.new-chat-btn {
  width: 100% !important;
  padding: 6px 8px !important;
  border-radius: 6px !important;
  background: transparent !important;
  border: 1px solid var(--b2-acc-line) !important;
  color: var(--b2-acc) !important;
  font-family: var(--f-sans) !important;
  font-size: 11.5px !important;
  font-weight: 500 !important;
  letter-spacing: -0.005em !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 6px !important;
  transition: background .12s !important;
  box-shadow: none !important;
}
.new-chat-btn:hover {
  background: var(--b2-acc-soft) !important;
  color: var(--b2-acc-ink) !important;
}
.new-chat-btn svg { width: 12px; height: 12px; }

/* ============================================================================
 * Conversation list
 * ========================================================================== */
.conversation-list { padding: 4px 6px 18px !important; }

.conversation-item {
  padding: 5px 10px !important;
  border-radius: 5px !important;
  font-family: var(--f-sans) !important;
  font-size: 12px !important;
  color: var(--b2-ink) !important;
  letter-spacing: -0.005em !important;
  line-height: 1.5 !important;
  background: transparent !important;
  border: 1px solid transparent !important;
  box-shadow: none !important;
  transition: background .12s !important;
}

.conversation-item:hover       { background: var(--b2-sunken) !important; }
.conversation-item:focus       { outline: none !important; border-color: var(--b2-acc-line) !important; }
.conversation-item.active      {
  background: var(--b2-surface) !important;
  color: var(--b2-ink) !important;
  box-shadow: inset 2px 0 0 var(--b2-acc), 0 0 0 1px var(--b2-line) !important;
}

.conversation-title {
  color: inherit !important;
  font-family: inherit !important;
  font-weight: inherit !important;
}

.conversation-menu-btn {
  color: var(--b2-ink-3) !important;
  background: transparent !important;
}
.conversation-menu-btn:hover { color: var(--b2-ink) !important; background: var(--b2-sunken) !important; }

/* Session-history ⋯ menu — matched pixel-for-pixel to the Explorer
 * right-click popup (.file-ctx-menu, main.css): same b2-bg plate, 8px
 * radius, 4px padding, two-layer drop shadow, per-row 5px pills with a
 * left accent rail on hover. (User call 2026-08-09.) */
.conversation-menu {
  padding: 4px !important;
  background: var(--b2-bg) !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 8px !important;
  box-shadow: 0 1px 2px rgba(17,18,22,0.05), 0 12px 32px rgba(17,18,22,0.16) !important;
  min-width: 132px !important;
}
/* Same scale-in as .file-ctx-menu; anchored top-right (opens under the ⋯). */
.conversation-menu.active {
  animation: file-ctx-in 110ms cubic-bezier(0.16, 1, 0.3, 1) !important;
  transform-origin: top right !important;
}
.conversation-menu-item {
  position: relative !important;
  display: flex !important;
  align-items: center !important;
  gap: 8px !important;
  padding: 3px 12px 3px 10px !important;
  margin: 0 !important;
  border-radius: 5px !important;
  color: var(--b2-ink) !important;
  font-family: var(--f-sans) !important;
  font-size: 13px !important;
  line-height: 1.3 !important;
  white-space: nowrap !important;
  transition: background .1s ease-out, color .1s ease-out !important;
}
/* Drop main.css's first/last-child plate corners — every row is its own pill. */
.conversation-menu-item:first-child,
.conversation-menu-item:last-child { border-radius: 5px !important; }
/* Accent rail on the hovered row's left edge (same as .file-ctx-menu-item). */
.conversation-menu-item::before {
  content: "" !important;
  position: absolute !important;
  left: 2px !important; top: 4px !important; bottom: 4px !important;
  width: 2px !important; border-radius: 2px !important;
  background: transparent !important;
  transition: background .1s ease-out !important;
}
.conversation-menu-item:hover {
  background: var(--b2-acc-soft) !important;
  color: var(--b2-acc-ink) !important;
}
.conversation-menu-item:hover::before { background: var(--b2-acc) !important; }
.conversation-menu-item .mi-icon {
  margin: 0 !important;
  opacity: 1 !important;
  width: 14px !important; height: 14px !important; flex: 0 0 14px !important;
  color: var(--b2-ink-3) !important;
  transition: color .1s ease-out !important;
}
.conversation-menu-item:hover .mi-icon { color: var(--b2-acc) !important; }
.conversation-menu-item.delete { color: var(--b2-err) !important; }
.conversation-menu-item.delete .mi-icon { color: var(--b2-err) !important; }
.conversation-menu-item.delete:hover { background: rgba(220,38,38,0.08) !important; }
.conversation-menu-item.delete:hover::before { background: var(--b2-err) !important; }
.conversation-menu-item.delete:hover .mi-icon { color: var(--b2-err) !important; }

.conversation-hover-tooltip {
  background: #4A4A4A !important;  /* neutral mid-grey, no blue/slate tint */
  color: #FFFFFF !important;
  border: 0 !important;
  border-radius: 5px !important;
  font-family: var(--f-sans) !important;
  font-size: 11px !important;
  box-shadow: 0 6px 18px rgba(17,18,22,0.25) !important;
}

/* Date-group labels (Last 7 days, Last 30 days, …) */
.conversations-section-header,
.conv-section-header,
.time-section-header,
.conversations-time-group {
  padding: 12px 10px 5px !important;
  font-family: var(--f-mono) !important;
  font-size: 10px !important;
  font-weight: 500 !important;
  color: var(--b2-ink-4) !important;
  letter-spacing: 0.1em !important;
  text-transform: uppercase !important;
  background: transparent !important;
}

/* ============================================================================
 * Welcome message
 * ========================================================================== */
.welcome-message { background: transparent !important; }
.welcome-message h2,
.welcome-message .greeting-text {
  font-family: var(--f-sans) !important;
  font-weight: 600 !important;
  color: var(--b2-ink) !important;
  letter-spacing: -0.015em !important;
}
.welcome-message p,
.welcome-message .typewriter-subtitle,
.welcome-message .typewriter-hint {
  color: var(--b2-ink-3) !important;
  font-family: var(--f-sans) !important;
}
.welcome-message .welcome-icon { opacity: 0.7 !important; }

/* ============================================================================
 * Chat messages
 * ========================================================================== */
.chat-messages {
  background: var(--b2-bg) !important;
  padding: 22px 24px 24px !important;
  scroll-padding-bottom: 24px !important;
}

/* A-pro v3:
 *   · Wrapper fills chat column (no outer centering — kills side gutters).
 *   · AI white card spans full usable width inside container padding.
 *   · User right-aligned pill, self-capped at 78% so its right edge
 *     lines up with AI card's right edge.
 *   · 14.5px body, 1.62 line-height — identical typography both sides. */
.message {
  display: block !important;
  width: 100% !important;
  max-width: 100% !important;
  gap: 0 !important;
  margin: 0 0 18px 0 !important;
  padding: 0 !important;
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
  border-radius: 0 !important;
}
.message-avatar { display: none !important; }

/* every .message-content — normalise sizing, then the per-role rules below
 * override surface / border / font only. */
.message .message-content {
  display: block !important;
  max-width: 100% !important;
  width: 100% !important;
  margin: 0 !important;
  padding: 0 !important;
  border-radius: 0 !important;
  font-size: 14.5px !important;
  line-height: 1.62 !important;
  white-space: normal !important;
  word-wrap: break-word !important;
  box-shadow: none !important;
}

/* user bubble — cream pill, right-aligned, 78% max-width */
.message.message-user,
.message-user {
  background: transparent !important;
  border: 0 !important;
  padding: 0 !important;
  text-align: right !important;
}

.message.message-user .message-content,
.message-user .message-content {
  display: inline-block !important;
  background: var(--b2-user-bg) !important;
  color: var(--b2-ink) !important;
  border: 0 !important;
  border-radius: 12px !important;
  font-family: var(--f-sans) !important;
  font-size: 14.5px !important;
  line-height: 1.62 !important;
  white-space: pre-wrap !important;
  text-align: left !important;
  width: auto !important;
  max-width: 85% !important;
  padding: 10px 16px !important;
  margin: 0 !important;
}

.message.message-user code,
.message-user code {
  background: transparent !important;
  color: var(--b2-ink) !important;
  padding: 0 !important;
  font-family: var(--f-mono) !important;
}

/* AI bubble — warm paper-tone surface (not cool gray). The previous
   --b2-sunken (#F3F4F6) read as clinical/technical against the warm
   cream user bubble; #F5F3ED is a recycled-paper neutral that's
   warmer than the page off-white but cooler than the user's cream,
   so the two bubbles complement each other instead of competing on
   the warm-cool axis. The asymmetric 14/4 radius keeps the
   speech-tail pointing to the AI side; no border, just a soft drop
   shadow gives the bubble subtle elevation off the page. */
.message.message-assistant,
.message-assistant,
.message-bot {
  background: transparent !important;
  border: 0 !important;
  padding: 0 !important;
  text-align: left !important;
}

.message.message-assistant .message-content,
.message-assistant .message-content,
.message-bot .message-content {
  display: inline-block !important;
  background: #F6F4EE !important;
  color: #1A1B1F !important;
  border: 0 !important;
  border-radius: 14px 14px 14px 4px !important;
  padding: 14px 18px !important;
  font-family: var(--f-sans) !important;
  font-size: 14.5px !important;
  font-weight: 400 !important;
  line-height: 1.68 !important;
  letter-spacing: -0.003em !important;
  white-space: normal !important;
  width: auto !important;
  max-width: 85% !important;
  /* Three-layer depth: faint warm drop (paper resting on table),
     1-px crisp under-shadow (the page edge below), and a 1-px inset
     top highlight (the slightly bevelled top of a paper sheet under
     soft light). Keeps the bubble visually elevated without ever
     looking like a heavy card. */
  box-shadow:
    0 1px 3px rgba(82, 60, 30, 0.05),
    0 1px 1px rgba(82, 60, 30, 0.03),
    inset 0 1px 0 rgba(255, 255, 255, 0.4) !important;
}

/* Consecutive AI bubbles cozy up so an N-step agent stream reads as
   one grouped thought, not N disconnected pills. The pinch on the
   bottom-left only really makes sense on the LAST bubble of a chain,
   so non-final AI bubbles square that corner off and the next bubble
   squares its top-left to match — produces a continuous left edge
   for stacked replies. */
.message.message-assistant + .message.message-assistant,
.message-assistant + .message-assistant {
  margin-top: -12px !important;
}
.message-assistant:has(+ .message-assistant) .message-content {
  border-bottom-left-radius: 4px !important;
}
.message-assistant + .message-assistant .message-content {
  border-top-left-radius: 4px !important;
}

.message-content p { margin: 4px 0 !important; color: var(--b2-ink) !important; }
.message-content strong { color: var(--b2-ink) !important; font-weight: 600 !important; }

/* inline code — amber on cream */
.message-content code {
  font-family: var(--f-mono) !important;
  font-size: 12px !important;
  color: var(--b2-user-code-fg) !important;
  background: var(--b2-user-code-bg) !important;
  padding: 1px 5px !important;
  border-radius: 3px !important;
  border: 0 !important;
}
/* Numeric values in assistant output (summaries AND chat-process text) — gold,
 * matching the inline-code / filename colour so numbers share one accent.
 * Colour only (no bold). Wrapped by highlightNumbers() (chat-ui.js);
 * identifiers/code are skipped. */
.message-content .msg-num {
  color: var(--b2-user-code-fg) !important;
}
/* Status words — success → green ✓, failure → red ✗, caution → amber ⚠.
 * The glyph is a ::before so it never lands in copied text. Conservative word
 * list lives in highlightNumbers() (chat-ui.js). */
.message-content .msg-ok   { color: #15803D !important; }
.message-content .msg-bad  { color: #B91C1C !important; }
.message-content .msg-warn { color: #B45309 !important; }
.message-content .msg-ok::before   { content: '\2713\00a0'; }
.message-content .msg-bad::before  { content: '\2717\00a0'; }
.message-content .msg-warn::before { content: '\26A0\00a0'; }

.message-content pre {
  background: var(--b2-sunken) !important;
  color: var(--b2-ink) !important;
  border: 1px solid var(--b2-line) !important;
  padding: 10px 12px !important;
  border-radius: 5px !important;
  font-family: var(--f-mono) !important;
  font-size: 12px !important;
  line-height: 1.55 !important;
}

/* fenced ``` code blocks in chat — a framed card with a header (language label +
   copy button) and a highlighted body. The global .hljs-* token colors (shared
   with the file preview) show through the transparent inner <code>. */
.message-content .chat-code-wrap {
  margin: 10px 0 !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 7px !important;
  overflow: hidden !important;
  background: var(--b2-sunken) !important;
}
.message-content .chat-code-head {
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
  padding: 5px 10px !important;
  background: color-mix(in srgb, var(--b2-sunken) 60%, var(--b2-line)) !important;
  border-bottom: 1px solid var(--b2-line) !important;
}
.message-content .chat-code-lang {
  font-family: var(--f-mono) !important;
  font-size: 11.5px !important;
  font-weight: 600 !important;
  letter-spacing: 0 !important;
  text-transform: none !important;
  color: var(--b2-ink-4, #9a8f7a) !important;
}
.message-content .chat-code-copy {
  font-family: var(--f-sans) !important;
  font-size: 11px !important;
  line-height: 1 !important;
  color: var(--b2-ink-2, #6b6151) !important;
  background: transparent !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 5px !important;
  padding: 4px 9px !important;
  cursor: pointer !important;
  transition: background .12s, color .12s, border-color .12s !important;
}
.message-content .chat-code-copy:hover {
  background: var(--b2-raised, #fff) !important;
  color: var(--b2-ink) !important;
  border-color: var(--b2-ink-4, #b5a98f) !important;
}
.message-content .chat-code-copy.copied {
  color: #2e7d4f !important;
  border-color: #2e7d4f !important;
}
.message-content pre.chat-code {
  margin: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  overflow-x: auto !important;
  max-width: 100% !important;
  background: transparent !important;
  padding: 10px 12px !important;
}
.message-content pre.chat-code code,
.message-content pre.chat-code code.hljs {
  display: block !important;
  background: transparent !important;
  color: var(--b2-ink) !important;
  border: 0 !important;
  padding: 0 !important;
  border-radius: 0 !important;
  white-space: pre !important;
  font-family: var(--f-mono) !important;
  font-size: 12.5px !important;
  line-height: 1.55 !important;
}

.message-content ul { padding-left: 18px !important; margin: 8px 0 !important; }
.message-content li { margin: 4px 0 !important; color: var(--b2-ink-2) !important; }
.message-content li::marker { color: var(--b2-ink-4) !important; }

.message-content h3, .message-content h4 {
  color: var(--b2-ink) !important;
  font-family: var(--f-sans) !important;
  font-weight: 600 !important;
  letter-spacing: -0.01em !important;
}

.message-content blockquote {
  border-left: 2px solid var(--b2-line-2) !important;
  color: var(--b2-ink-3) !important;
  background: transparent !important;
  padding-left: 10px !important;
  margin: 8px 0 !important;
}

.message-content hr {
  border: 0 !important;
  border-top: 1px solid var(--b2-line) !important;
  margin: 14px 0 !important;
}

/* Table inside a message bubble — lives INSIDE the bubble surface,
   not as a separate white card on top of it. Transparent bg so it
   inherits the bubble color (sunken for AI, cream for user); the
   structure comes from a slightly-darker header tint and hairline
   row dividers, not from a competing solid panel. */
.message-content table {
  width: 100% !important;
  border-collapse: collapse !important;
  margin: 10px 0 !important;
  font-family: var(--f-mono) !important;
  font-size: 11.5px !important;
  border: 0 !important;
  border-radius: 0 !important;
  overflow: visible !important;
  background: transparent !important;
}
.message-content th {
  text-align: left !important;
  padding: 7px 12px !important;
  background: rgba(17, 18, 22, 0.05) !important;
  color: var(--b2-ink-3) !important;
  font-weight: 500 !important;
  font-size: 10.5px !important;
  letter-spacing: 0.06em !important;
  text-transform: uppercase !important;
  border-bottom: 1px solid rgba(17, 18, 22, 0.10) !important;
}
.message-content td {
  padding: 7px 12px !important;
  background: transparent !important;
  color: var(--b2-ink) !important;
  font-variant-numeric: tabular-nums !important;
  border-bottom: 1px solid rgba(17, 18, 22, 0.06) !important;
}
.message-content tr:last-child td { border-bottom: 0 !important; }
/* Subtle vertical divider between key columns and value columns so
   wide rows scan as a true two-column data layout, not a wrapped
   block of mono text. Only paints between columns, never on the
   outer edges. */
.message-content th:not(:last-child),
.message-content td:not(:last-child) {
  border-right: 1px solid rgba(17, 18, 22, 0.05) !important;
}

/* ============================================================================
 * Activity chips / thinking
 * ========================================================================== */
.activity-chip {
  background: var(--b2-sunken) !important;
  color: var(--b2-ink-2) !important;
  border: 1px solid var(--b2-line) !important;
  font-family: var(--f-mono) !important;
  font-size: 10.5px !important;
  border-radius: 4px !important;
  padding: 3px 8px !important;
}
.activity-chip.in-progress {
  background: var(--b2-acc-soft) !important;
  color: var(--b2-acc-ink) !important;
  border-color: var(--b2-acc-line) !important;
}
.activity-chip .tool-chip-status.done { color: var(--b2-ok) !important; }
.activity-chip .tool-chip-count {
  color: var(--b2-ink-4) !important;
  font-family: var(--f-mono) !important;
}

.msg-label {
  color: var(--b2-ink-4) !important;
  font-family: var(--f-mono) !important;
  font-size: 10px !important;
  letter-spacing: 0.08em !important;
  text-transform: uppercase !important;
}

.thinking-animation .dot { background: var(--b2-ink-4) !important; }

/* Streaming "thinking" block — collapsible reasoning (Claude-Code style) */
.thinking-block {
  background: var(--b2-sunken) !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 7px !important;
  padding: 0 !important;
  margin: 4px 0 10px !important;
  max-width: 680px !important;
  overflow: hidden !important;
}
.thinking-block .thinking-block-head {
  display: flex !important;
  align-items: center !important;
  gap: 7px !important;
  cursor: pointer !important;
  user-select: none !important;
  padding: 7px 11px !important;
  color: var(--b2-ink-4) !important;
  font-family: var(--f-sans) !important;
  font-size: 12.5px !important;
}
.thinking-block.expanded .thinking-block-head { border-bottom: 1px solid var(--b2-line) !important; }
.thinking-block .thinking-block-head:hover { color: var(--b2-ink-2) !important; }
.thinking-block .thinking-title { font-weight: 500 !important; }
.thinking-block .thinking-chevron { margin-left: auto !important; font-size: 11px !important; transition: transform .15s !important; }
.thinking-block:not(.expanded) .thinking-chevron { transform: rotate(-90deg) !important; }
.thinking-block .thinking-block-body {
  padding: 9px 13px !important;
  color: var(--b2-ink-3) !important;
  font-family: var(--f-sans) !important;
  font-size: 12.5px !important;
  line-height: 1.62 !important;
  white-space: pre-wrap !important;
  word-break: break-word !important;
  max-height: 260px !important;
  overflow-y: auto !important;
}
.thinking-block:not(.expanded) .thinking-block-body { display: none !important; }

/* Persistent reasoning block — <details class="chat-think"> rendered from the
   <thinking>…</thinking> marker in the stored message (survives reload). */
details.chat-think {
  background: var(--b2-sunken) !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 7px !important;
  margin: 4px 0 10px !important;
  max-width: 680px !important;
  overflow: hidden !important;
}
details.chat-think > summary.chat-think-summary {
  display: flex !important;
  align-items: center !important;
  gap: 7px !important;
  cursor: pointer !important;
  user-select: none !important;
  list-style: none !important;
  padding: 7px 11px !important;
  color: var(--b2-ink-4) !important;
  font-family: var(--f-sans) !important;
  font-size: 12.5px !important;
  font-weight: 500 !important;
}
details.chat-think > summary.chat-think-summary::-webkit-details-marker { display: none !important; }
details.chat-think > summary.chat-think-summary::marker { content: '' !important; }
details.chat-think > summary.chat-think-summary::after {
  content: '\2304' !important;  /* ⌄ */
  margin-left: auto !important;
  font-size: 11px !important;
  transition: transform .15s !important;
}
details.chat-think:not([open]) > summary.chat-think-summary::after { transform: rotate(-90deg) !important; }
details.chat-think[open] > summary.chat-think-summary { border-bottom: 1px solid var(--b2-line) !important; }
details.chat-think > summary.chat-think-summary:hover { color: var(--b2-ink-2) !important; }
/* Reasoning state glyph: pulsing dot while streaming, 💭 when done. Pulse (not a
   spin) because formatAssistantMessage rebuilds this element on every streamed
   delta — a restarting rotation looks janky, a restarting opacity pulse does not. */
details.chat-think .chat-think-spinner {
  width: 8px !important; height: 8px !important;
  border-radius: 50% !important;
  display: inline-block !important;
  flex: 0 0 auto !important;
}
details.chat-think.streaming .chat-think-spinner {
  background: var(--b2-ink-4) !important;
  animation: thinkpulse 1s ease-in-out infinite !important;
}
@keyframes thinkpulse { 0%, 100% { opacity: .25 !important; } 50% { opacity: 1 !important; } }
details.chat-think.done .chat-think-spinner { width: auto !important; height: auto !important; }
details.chat-think.done .chat-think-spinner::before { content: '\1F4AD' !important; font-size: 12px !important; opacity: .85 !important; }
details.chat-think.streaming .chat-think-title { color: var(--b2-ink-3) !important; }
details.chat-think .chat-think-body {
  padding: 9px 13px !important;
  color: var(--b2-ink-3) !important;
  font-family: var(--f-sans) !important;
  font-size: 12.5px !important;
  font-style: italic !important;
  line-height: 1.62 !important;
  word-break: break-word !important;
  max-height: 320px !important;
  overflow-y: auto !important;
}
details.chat-think .chat-think-body code { font-style: normal !important; }
.thinking-block .thinking-spinner {
  width: 11px !important; height: 11px !important;
  border: 2px solid var(--b2-line) !important;
  border-top-color: var(--b2-ink-4) !important;
  border-radius: 50% !important;
  display: inline-block !important;
  flex: 0 0 auto !important;
  animation: thinkingspin .7s linear infinite !important;
}
.thinking-block.done .thinking-spinner { display: none !important; }
@keyframes thinkingspin { to { transform: rotate(360deg); } }

/* Reasoning rendered OUTSIDE the cream answer bubble (above it, on the page bg).
   NOT the gray card — a light, non-boxed annotation (left accent + dim italic). */
/* Match the answer bubble width (.message-content is max-width:85%) so the
   reasoning lines up with the reply, same left edge + same width. */
.msg-thinking { max-width: 85% !important; margin: 2px 0 9px 0 !important; }
.msg-thinking .thinking-block {
  background: transparent !important;
  border: none !important;
  border-left: 2px solid var(--b2-line) !important;
  border-radius: 0 !important;
  margin: 0 !important;
  max-width: none !important;
}
.msg-thinking .thinking-block .thinking-block-head { padding: 2px 0 2px 12px !important; }
.msg-thinking .thinking-block.expanded .thinking-block-head { border-bottom: none !important; }
.msg-thinking .thinking-block .thinking-block-body { padding: 4px 0 4px 12px !important; max-height: none !important; }
/* A reasoning-only turn (thinking moved out, no answer text) leaves an empty
   cream answer bubble — hide it so there's no stray empty box. */
.message-assistant .message-content:empty { display: none !important; }

/* ============================================================================
 * Composer (input)
 * ========================================================================== */
.chat-input-container,
.composer {
  background: var(--b2-bg) !important;
  border-top: 1px solid var(--b2-line) !important;
  padding: 10px 22px 16px !important;
}

.input-wrapper {
  background: var(--b2-surface) !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 22px !important;
  padding: 6px 6px 6px 10px !important;
  transition: border-color .12s, box-shadow .12s !important;
  box-shadow: none !important;
}
.input-wrapper:focus-within {
  border-color: var(--b2-user-rule) !important;
  box-shadow: 0 1px 0 rgba(17,18,22,0.02) !important;
}

/* Chat composer textarea: never paint its own focus halo — the parent
   .input-wrapper already shows the focus state with an amber border. The
   global `:focus-visible` rule below would otherwise add a 3px blue glow
   (rgba(42,120,214,0.1) 0 0 0 3px) inside the wrapper, producing the
   ugly inner blue rectangle. */
.chat-input-container textarea:focus,
.chat-input-container textarea:focus-visible,
.chat-input-container input:focus,
.chat-input-container input:focus-visible,
.chat-input:focus,
.chat-input:focus-visible,
#chatInput:focus,
#chatInput:focus-visible {
  outline: 0 !important;
  border: 0 !important;
  box-shadow: none !important;
}

.chat-input-container textarea,
.chat-input-container input,
.chat-input {
  background: transparent !important;
  border: 0 !important;
  outline: 0 !important;
  resize: none !important;
  color: var(--b2-ink) !important;
  font-family: var(--f-sans) !important;
  font-size: 13px !important;
  line-height: 1.5 !important;
  padding: 7px 4px !important;
  min-height: 18px !important;
  max-height: 180px !important;
}
.chat-input-container textarea::placeholder,
.chat-input::placeholder { color: var(--b2-ink-4) !important; }

.send-button, button.send-button, .send-btn {
  width: 30px !important;
  height: 30px !important;
  border-radius: 50% !important;
  background: transparent !important;
  border: 1px solid var(--b2-line-2) !important;
  color: var(--b2-ink-3) !important;
  display: grid !important;
  place-items: center !important;
  transition: all .12s !important;
  padding: 0 !important;
}
.send-button:hover, button.send-button:hover, .send-btn:hover {
  background: var(--b2-ink) !important;
  border-color: var(--b2-ink) !important;
  color: #FFFFFF !important;
}

.attachment-btn, .upload-btn {
  width: 30px !important;
  height: 30px !important;
  border-radius: 50% !important;
  background: transparent !important;
  border: 0 !important;
  color: var(--b2-ink-3) !important;
  display: grid !important;
  place-items: center !important;
  transition: background .12s, color .12s !important;
}
.attachment-btn:hover, .upload-btn:hover { color: var(--b2-ink) !important; background: var(--b2-sunken) !important; }

/* ============================================================================
 * PDF panel + View toggle
 * ========================================================================== */
.pdf-panel, #pdfPanel {
  background: var(--b2-bg) !important;
  border-left: 1px solid var(--b2-line) !important;
  color: var(--b2-ink) !important;
}

/* .pdf-header is the wrapper that holds .pdf-title → .view-toggle.
 * Lock the wrapper to 40 px, kill inner borders (only the wrapper draws one)
 * so the bottom line matches .chat-header and .sidebar-header exactly.         */
.pdf-header {
  height: 40px !important;
  min-height: 40px !important;
  max-height: 40px !important;
  padding: 0 !important;
  background: var(--b2-bg) !important;
  color: var(--b2-ink) !important;
  border-bottom: 1px solid var(--b2-line) !important;
  display: flex !important;
  align-items: stretch !important;
  overflow: hidden !important;
}
.pdf-title {
  height: 40px !important;
  min-height: 40px !important;
  max-height: 40px !important;
  padding: 0 !important;
  background: transparent !important;
  border: 0 !important;
  border-bottom: 0 !important;
  color: var(--b2-ink) !important;
  font-family: var(--f-sans) !important;
  font-weight: 600 !important;
  font-size: 12px !important;
  display: flex !important;
  align-items: center !important;
  flex: 1 1 auto !important;
}

.view-toggle {
  height: 40px !important;
  min-height: 40px !important;
  max-height: 40px !important;
  padding: 0 !important;
  background: transparent !important;
  border: 0 !important;
  border-bottom: 0 !important;
  display: flex !important;
  align-items: stretch !important;
  gap: 0 !important;
  flex: 1 1 auto !important;
}
.view-toggle button {
  background: transparent !important;
  color: var(--b2-ink-3) !important;
  border: 0 !important;
  font-family: var(--f-sans) !important;
  font-size: 13px !important;
  padding: 0 12px !important;
  height: 40px !important;
  min-height: 40px !important;
  max-height: 40px !important;
  position: relative !important;
  transition: color .12s !important;
  display: inline-flex !important;
  align-items: center !important;
  gap: 6px !important;
}
.view-toggle button:hover:not(.active) { color: var(--b2-ink) !important; }
.view-toggle button.active {
  color: var(--b2-ink) !important;
  background: transparent !important;
}
.view-toggle button.active::after {
  content: "" !important;
  position: absolute !important;
  left: 10px !important; right: 10px !important; bottom: 0 !important;
  height: 1px !important; background: var(--b2-acc) !important;
}
.view-toggle button.unavailable { opacity: 0.45 !important; color: var(--b2-ink-4) !important; }

.pdf-controls {
  background: var(--b2-bg) !important;
  border-bottom: 1px solid var(--b2-line) !important;
}
.pdf-controls button {
  background: transparent !important;
  color: var(--b2-ink-3) !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 5px !important;
  font-family: var(--f-mono) !important;
}
.pdf-controls button:hover:not(:disabled) {
  background: var(--b2-sunken) !important;
  color: var(--b2-ink) !important;
}
.pdf-controls button:disabled { opacity: 0.4 !important; }

.pdf-content-area, #pdfContainer {
  background: var(--b2-bg) !important;
}
.pdf-all-pages { background: var(--b2-bg) !important; }

.file-upload-area {
  background: var(--b2-surface) !important;
  border: 1px dashed var(--b2-line-2) !important;
  color: var(--b2-ink-3) !important;
}

.file-list { background: var(--b2-bg) !important; }
.file-item {
  background: var(--b2-surface) !important;
  border: 1px solid var(--b2-line) !important;
  color: var(--b2-ink) !important;
}
.file-item button {
  background: transparent !important;
  color: var(--b2-ink-3) !important;
  border: 0 !important;
}
.file-item button:hover {
  color: var(--b2-ink) !important;
  background: var(--b2-sunken) !important;
}

/* ============================================================================
 * File browser
 * ========================================================================== */
.file-browser-container { background: var(--b2-bg) !important; }
.file-tree {
  background: transparent !important;
  padding: 4px 0 !important;
}
.file-tree-item {
  color: var(--b2-ink) !important;
  font-family: var(--f-mono) !important;
  font-size: 11px !important;
  padding: 3px 10px !important;
  border-radius: 4px !important;
}
.file-tree-item:hover   { background: var(--b2-sunken) !important; }
.file-tree-item.selected{
  background: var(--b2-acc-soft) !important;
  color: var(--b2-acc-ink) !important;
  position: relative !important;
}
.file-tree-item.selected::before {
  content: "" !important;
  position: absolute !important;
  left: 0 !important; top: 2px !important; bottom: 2px !important;
  /* amber, not accent-blue: the selected row's background is the cream
     --b2-user-bg, and cream+amber is the theme's pair (chat user bubble).
     A blue bar on a cream row was the leftover half of an old blue-soft
     selection style (user call 2026-07-16). */
  width: 2px !important; background: var(--b2-user-rule) !important;
}
.file-tree-item .file-name { color: var(--b2-ink) !important; }
.file-tree-item.directory .file-name { color: var(--b2-ink) !important; }
.file-tree-toggle { color: var(--b2-ink-4) !important; }
.file-tree-item.version-folder { color: var(--b2-ink-3) !important; }
.file-tree-item.version-folder.version-current { color: var(--b2-acc) !important; }

.file-content-viewer { background: var(--b2-bg) !important; }
.file-content-header {
  /* Match .file-tree-panel > .file-tree-title (40px) so the divider line
   * under both panels lines up perfectly. main.css gives this header a
   * 12-14px symmetric padding which, combined with the toolbar buttons,
   * naturally grows it to ~57px — pin it. */
  flex: 0 0 40px !important;
  height: 40px !important;
  min-height: 40px !important;
  padding: 0 14px !important;
  background: var(--b2-bg) !important;
  border-bottom: 1px solid var(--b2-line) !important;
  color: var(--b2-ink) !important;
  font-family: var(--f-sans) !important;
  gap: 8px !important;
  overflow: hidden !important;
}
.file-content-header .file-header-main {
  font-size: 12px !important;
  font-weight: 500 !important;
  color: var(--b2-ink-2, var(--b2-ink)) !important;
}
.file-content-header .file-header-actions {
  flex-wrap: nowrap !important;
  gap: 4px !important;
  min-width: 0 !important;
  overflow-x: auto !important;
  scrollbar-width: none !important;
}
.file-content-header .file-header-actions::-webkit-scrollbar { display: none !important; }
.file-content-header .file-pdf-toolbar {
  flex-wrap: nowrap !important;
  gap: 4px !important;
  align-items: center !important;
}
.file-content-header .file-pdf-toolbar button {
  height: 24px !important;
  padding: 0 8px !important;
  font-size: 11px !important;
  border-radius: 4px !important;
  border: 1px solid var(--b2-line) !important;
  background: transparent !important;
  color: var(--b2-ink-3, var(--b2-ink)) !important;
  min-width: 24px !important;
  line-height: 1 !important;
}
.file-content-header .file-pdf-toolbar button:hover {
  background: var(--b2-sunken) !important;
  color: var(--b2-ink) !important;
}
.file-content-header .file-pdf-open-btn {
  /* main.css forces 120px min-width which blows the 40px header on narrow
   * panes; let it size to its label instead. */
  min-width: 0 !important;
  padding: 0 10px !important;
}
.file-content-header .file-pdf-toolbar-sep {
  color: var(--b2-line-2, var(--b2-line)) !important;
  font-size: 11px !important;
  padding: 0 2px !important;
}
.file-content-header .file-pdf-zoom-label {
  font-size: 11px !important;
  color: var(--b2-ink-3, var(--b2-ink)) !important;
  min-width: 38px !important;
}
.file-content-header .file-header-refresh-btn {
  width: 24px !important;
  height: 24px !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 4px !important;
  background: transparent !important;
  color: var(--b2-ink-3, var(--b2-ink)) !important;
  font-size: 13px !important;
}
/* pdf.js render mode: warm paper backdrop matching the rest of the shell
 * instead of main.css's chilly #eef2f7 grey. The pdf.js canvases still
 * sit on white pages — this fills the gutter around them. */
.file-content-body.pdf-render-mode {
  background: var(--b2-bg) !important;
  padding: 12px !important;
}
.file-content-body, .file-content-body pre, .file-content-body code {
  background: var(--b2-surface) !important;
  color: var(--b2-ink) !important;
  font-family: var(--f-mono) !important;
  font-size: 12px !important;
  line-height: 1.55 !important;
}

/* ============================================================================
 * Report case sidebar
 * ========================================================================== */
.report-case-sidebar {
  background: var(--b2-bg) !important;
  border-right: 1px solid var(--b2-line) !important;
}
.report-version-item {
  color: var(--b2-ink) !important;
  background: transparent !important;
  font-family: var(--f-sans) !important;
  border-radius: 4px !important;
}
.report-version-item:hover { background: var(--b2-sunken) !important; }
.report-version-item.active {
  background: var(--b2-surface) !important;
  box-shadow: inset 2px 0 0 var(--b2-acc), 0 0 0 1px var(--b2-line) !important;
}
.report-version-item.no-report { color: var(--b2-ink-4) !important; }

.report-file-content { background: var(--b2-bg) !important; }
.report-file-content-header {
  background: var(--b2-bg) !important;
  border-bottom: 1px solid var(--b2-line) !important;
  color: var(--b2-ink) !important;
}
.report-file-content-header button {
  background: transparent !important;
  color: var(--b2-ink-3) !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 5px !important;
}
.report-file-content-header button:hover {
  background: var(--b2-sunken) !important;
  color: var(--b2-ink) !important;
}
.report-file-content-body, .report-file-content-body pre {
  background: var(--b2-surface) !important;
  color: var(--b2-ink) !important;
}

.trame-case-list {
  background: var(--b2-bg) !important;
  color: var(--b2-ink) !important;
}

/* ============================================================================
 * VTK / Trame viewer
 * ========================================================================== */
#vtkjsContainer, #trameContainer, .vtk-container,
.viewer-panel, .trame-panel, #trameViewer,
.trame-viewer-container {
  background: var(--b2-bg) !important;
  position: relative !important;
  overflow: hidden !important;
}

/* soft blue radial glow — scoped to #vtkjsContainer so it never leaks into
 * the right rail (which is a flex sibling inside .trame-viewer-container). */
#vtkjsContainer::before,
#trameViewer::before {
  content: "" !important;
  position: absolute !important;
  inset: 0 !important;
  pointer-events: none !important;
  z-index: 0 !important;
  background:
    radial-gradient(ellipse at 50% 40%, rgba(42,120,214,0.08) 0%, transparent 55%),
    radial-gradient(ellipse at 50% 100%, rgba(224,182,94,0.06) 0%, transparent 50%) !important;
}

/* Grid overlay removed — canvas reads cleaner without it.                  */
#vtkjsContainer::after,
#trameViewer::after {
  content: none !important;
  display: none !important;
}

#vtkjsContainer { position: relative !important; z-index: 0 !important; }
#vtkjsContainer canvas { position: relative !important; z-index: 1 !important; background: transparent !important; }

/* colorbar — paper-tinted glass card.
 * Was rgba(255,255,255,0.85) (cold white) sitting on #FAFAF9 paper —
 * looked like a foreign rectangle. Switched to the same paper hue at
 * low alpha so the card has a soft warm glass feel, with a faint
 * hairline border + subtle saturate to keep edges legible against any
 * 3D content behind it. */
#trameColorbar {
  background: rgba(250, 250, 249, 0.55) !important;
  -webkit-backdrop-filter: blur(4px) saturate(110%) !important;
          backdrop-filter: blur(4px) saturate(110%) !important;
  border: 1px solid rgba(229, 231, 235, 0.45) !important;
  border-radius: 6px !important;
  padding: 6px 8px 6px 6px !important;
  color: var(--b2-ink) !important;
  box-shadow: none !important;
}
#trameColorbarTitle {
  color: var(--b2-ink) !important;
  font-family: var(--f-sans) !important;
  font-size: 11px !important;
  font-weight: 500 !important;
  text-shadow: 0 0 2px rgba(250, 250, 249, 0.9), 0 0 2px rgba(250, 250, 249, 0.9) !important;
}
#trameColorbarMin, #trameColorbarMid, #trameColorbarMax {
  color: var(--b2-ink-3) !important;
  font-family: var(--f-mono) !important;
  font-size: 9.5px !important;
  font-variant-numeric: tabular-nums !important;
  text-shadow: 0 0 2px rgba(250, 250, 249, 0.85) !important;
}

/* timestep control bar */
#trameTimestepControls,
.trame-timestep-controls,
.timestep-controls {
  background: var(--b2-bg) !important;
  border-bottom: 1px solid var(--b2-line) !important;
  color: var(--b2-ink) !important;
  font-family: var(--f-sans) !important;
}
#trameTimestepControls label,
.trame-timestep-controls label {
  color: var(--b2-ink-3) !important;
  font-family: var(--f-mono) !important;
  font-size: 10.5px !important;
}

#trameTimestepControls select,
.trame-timestep-controls select,
#trameTimestepSelector {
  background: var(--b2-surface) !important;
  color: var(--b2-ink) !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 5px !important;
  font-family: var(--f-mono) !important;
  font-size: 11px !important;
  padding: 4px 22px 4px 8px !important;
}

/* right rail selects */
#trameFieldSelector, #trameColormapSelector,
#trameRangeMin, #trameRangeMax,
.trame-field-row select,
.trame-color-row select,
.trame-range-row input {
  background: var(--b2-surface) !important;
  color: var(--b2-ink) !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 5px !important;
  font-family: var(--f-mono) !important;
  font-size: 11px !important;
  padding: 4px 8px !important;
}
#trameFieldSelector:focus, #trameColormapSelector:focus,
#trameRangeMin:focus, #trameRangeMax:focus {
  border-color: var(--b2-acc-line) !important;
  outline: none !important;
}

/* right-rail (files list + headings) — opaque + its own stacking context so
 * the viewer radial/grid never shows through. */
.trame-file-list {
  background: var(--b2-bg) !important;
  border-left: 1px solid var(--b2-line) !important;
  color: var(--b2-ink) !important;
  position: relative !important;
  z-index: 2 !important;
  flex: 0 0 240px !important;
}
.trame-file-list-header {
  background: var(--b2-bg) !important;
  border-bottom: 1px solid var(--b2-line) !important;
  padding: 10px 12px !important;
}
/* CASES group header → match the VTU FILES section bar above. It's a
 * .file-tree-item by default (rounded box, 6px radius, smaller padding, hover
 * highlight); flatten it into the same full-width header bar. */
/* Zero ALL of #sceneTree's padding: side padding so the CASES bar + rows sit
 * flush to the edges like VTU; top/bottom so there's no grey gap above CASES
 * (right under the DISPLAY header) or below Results (right before VTU FILES). */
#sceneTree { padding: 0 !important; }
/* .file-tree-item has `margin: 1px 6px` — that 6px side margin insets every row
 * (incl. the selected case row's blue) and leaves white on both sides. Drop the
 * horizontal margin so rows sit flush; keep the 1px vertical row spacing. */
#sceneTree .file-tree-item { margin-left: 0 !important; margin-right: 0 !important; }
#sceneTree .scene-group-row {
  padding: 10px 12px !important;
  margin: 0 !important;
  border-radius: 0 !important;
  border-bottom: 1px solid var(--b2-line) !important;
  background: var(--b2-bg) !important;
  cursor: default !important;
}
#sceneTree .scene-group-row:hover { background: var(--b2-bg) !important; }
/* NOTE: the original .scene-group-label (mono / 10px / 0.16em / uppercase)
 * already matches the VTU FILES h3's *effective* cascade (theme:2144/2507),
 * so we intentionally do NOT restyle the label font here. */
.trame-file-list-header h3 {
  color: var(--b2-ink) !important;
  font-family: var(--f-sans) !important;
  font-weight: 600 !important;
  font-size: 12px !important;
}
.trame-file-list-header span {
  color: var(--b2-ink-4) !important;
  font-family: var(--f-mono) !important;
  font-size: 10.5px !important;
}
.trame-file-tree { background: transparent !important; padding: 4px 0 !important; }
.trame-file-item {
  color: var(--b2-ink) !important;
  font-family: var(--f-mono) !important;
  font-size: 11px !important;
  border-radius: 4px !important;
}
.trame-file-item:hover { background: var(--b2-sunken) !important; }
.trame-file-item.selected {
  background: var(--b2-acc-soft) !important;
  color: var(--b2-acc-ink) !important;
}
.trame-visibility-btn { background: transparent !important; color: var(--b2-acc) !important; }
.trame-visibility-btn:hover { background: var(--b2-sunken) !important; }
.trame-visibility-btn.hidden .eye-icon { color: var(--b2-ink-4) !important; }
.trame-file-item.trame-hidden { color: var(--b2-ink-4) !important; }
.trame-file-item.trame-hidden .file-name { color: var(--b2-ink-4) !important; }

/* ============================================================================
 * Slice controls
 * ========================================================================== */
.slice-control-bar {
  background: var(--b2-bg) !important;
  border-top: 1px solid var(--b2-line) !important;
}
.slice-controls select {
  background: var(--b2-surface) !important;
  color: var(--b2-ink) !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 5px !important;
  font-family: var(--f-mono) !important;
  font-size: 11px !important;
}
.slice-controls input[type="range"] {
  accent-color: var(--b2-acc) !important;
}

.slice-control-panel {
  background: var(--b2-bg) !important;
  border: 0 !important;
  border-top: 1px solid var(--b2-line) !important;
}
.slice-panel-header:hover { background: var(--b2-sunken) !important; }
.slice-panel-title {
  color: var(--b2-ink-2) !important;
  font-family: var(--f-mono) !important;
  font-size: 10.5px !important;
  font-weight: 600 !important;
  letter-spacing: 0.14em !important;
  text-transform: uppercase !important;
}
.slice-panel-title svg { color: var(--b2-acc) !important; }
.slice-panel-toggle { color: var(--b2-ink-3) !important; }
.slice-divider { background: var(--b2-line) !important; }
.slice-label {
  color: var(--b2-ink-3) !important;
  font-family: var(--f-mono) !important;
  font-size: 10.5px !important;
}
.slice-position-value {
  color: var(--b2-ink) !important;
  font-family: var(--f-mono) !important;
  font-variant-numeric: tabular-nums !important;
}

/* X Y Z direction — 3-col grid of equal-width pills; native radio hidden. */
.slice-direction-group,
.slice-radio-group {
  display: grid !important;
  grid-template-columns: 1fr 1fr 1fr !important;
  gap: 3px !important;
  width: 100% !important;
}
.slice-radio {
  position: relative !important;
  display: block !important;
  margin: 0 !important;
  cursor: pointer !important;
}
.slice-radio input[type="radio"] {
  position: absolute !important;
  opacity: 0 !important;
  pointer-events: none !important;
  width: 0 !important; height: 0 !important;
  margin: 0 !important;
}
.slice-radio-label {
  display: block !important;
  text-align: center !important;
  color: var(--b2-ink-2) !important;
  background: var(--b2-surface) !important;
  border: 1px solid var(--b2-line) !important;
  font-family: var(--f-mono) !important;
  font-size: 11px !important;
  border-radius: 6px !important;
  padding: 4px 0 !important;
  transition: all .12s !important;
  line-height: 1.2 !important;
}
.slice-radio input[type="radio"]:checked + .slice-radio-label {
  background: var(--b2-acc-soft) !important;
  color: var(--b2-acc) !important;
  border-color: var(--b2-acc-line) !important;
}
.slice-radio:hover .slice-radio-label {
  color: var(--b2-ink) !important;
  border-color: var(--b2-line-2) !important;
}

.slice-slider {
  -webkit-appearance: none !important;
  appearance: none !important;
  height: 3px !important;
  background: var(--b2-line) !important;
  border-radius: 2px !important;
  outline: none !important;
}
.slice-slider::-webkit-slider-thumb {
  -webkit-appearance: none !important;
  appearance: none !important;
  width: 12px !important; height: 12px !important;
  border-radius: 50% !important;
  background: var(--b2-acc) !important;
  cursor: pointer !important;
  border: 2px solid var(--b2-surface) !important;
  box-shadow: 0 1px 2px rgba(17,18,22,0.15) !important;
}
.slice-slider::-moz-range-thumb {
  width: 12px !important; height: 12px !important;
  border-radius: 50% !important;
  background: var(--b2-acc) !important;
  border: 2px solid var(--b2-surface) !important;
  cursor: pointer !important;
}

/* Informational readout — NOT a button. Quiet sub-caption, ink-3 mono.    */
.slice-preview-info {
  display: inline-flex !important;
  align-items: center !important;
  gap: 6px !important;
  padding: 0 !important;
  margin-top: 8px !important;
  border-radius: 0 !important;
  background: transparent !important;
  border: 0 !important;
  font-family: var(--f-mono) !important;
  font-size: 10.5px !important;
  letter-spacing: 0.04em !important;
  color: var(--b2-ink-3) !important;
}
.slice-preview-info svg,
.slice-preview-info [class*="icon"] {
  color: var(--b2-ink-4) !important;
  opacity: 0.7 !important;
}

/* Slice action buttons — mirror the X/Y/Z direction-pill chrome so the
 * entire Cross-Section panel reads as one family.
 * Primary (Generate) = pill "active" state (soft 10% blue fill + blue text)
 * Secondary (Clear)  = pill "inactive" state (white fill + grey text)     */
.slice-btn {
  padding: 5px 8px !important;
  border: 1px solid var(--b2-line-2) !important;
  background: var(--b2-surface) !important;
  color: var(--b2-ink-2) !important;
  font-family: var(--f-mono) !important;
  font-size: 11px !important;
  font-weight: 500 !important;
  letter-spacing: 0.01em !important;
  border-radius: 6px !important;
  transition: all .12s !important;
}
.slice-btn-primary {
  background: var(--b2-acc-soft) !important;         /* same 10% as active pill */
  color: var(--b2-acc) !important;                   /* same blue as active pill */
  border: 1px solid var(--b2-acc-line) !important;
  box-shadow: none !important;
}
.slice-btn-primary:hover:not(:disabled) {
  background: var(--b2-acc) !important;
  color: #FFFFFF !important;
  border-color: var(--b2-acc) !important;
  box-shadow: 0 2px 6px rgba(42,120,214, 0.18) !important;
  transform: translateY(-0.5px) !important;
}
.slice-btn-primary svg {
  /* Leave fill as-is (inline fill="none" stays) — outlined triangle is lighter */
  color: var(--b2-acc) !important;
  opacity: 0.85 !important;
  transition: color 160ms ease-out, opacity 160ms ease-out !important;
}
.slice-btn-primary:hover:not(:disabled) svg {
  color: #FFFFFF !important;
  opacity: 1 !important;
}
.slice-btn-secondary {
  background: var(--b2-surface) !important;
  color: var(--b2-ink-2) !important;
  border: 1px solid var(--b2-line-2) !important;
}
.slice-btn-secondary:hover:not(:disabled) {
  color: var(--b2-ink) !important;
  border-color: var(--b2-ink-4) !important;
}
.slice-btn-secondary svg {
  color: var(--b2-ink-3) !important;
}

.slice-status {
  font-family: var(--f-mono) !important;
  font-size: 10.5px !important;
  border-radius: 4px !important;
}
.slice-status.success { background: rgba(14,159,110,0.10) !important; color: var(--b2-ok) !important; border: 1px solid rgba(14,159,110,0.26) !important; }
.slice-status.error   { background: rgba(220,38,38,0.08) !important; color: var(--b2-err) !important; border: 1px solid rgba(220,38,38,0.24) !important; }
.slice-status.loading { background: rgba(181,71,8,0.08) !important; color: var(--b2-warn) !important; border: 1px solid rgba(181,71,8,0.22) !important; }

/* Patch visibility eye — outlined glyph via CSS mask, matches folder/file
 * aesthetic (thin stroke, theme token). Override the inline solid fill by
 * hiding the inner paths and painting a background-color through a mask.  */
.eye-icon {
  display: inline-block !important;
  width: 14px !important;
  height: 14px !important;
  flex: 0 0 14px !important;
  color: var(--b2-acc) !important;
  background-color: currentColor !important;
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M1.5 12S5.5 5 12 5s10.5 7 10.5 7-4 7-10.5 7S1.5 12 1.5 12z'/><circle cx='12' cy='12' r='3'/></svg>") !important;
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M1.5 12S5.5 5 12 5s10.5 7 10.5 7-4 7-10.5 7S1.5 12 1.5 12z'/><circle cx='12' cy='12' r='3'/></svg>") !important;
  -webkit-mask-repeat: no-repeat !important;
          mask-repeat: no-repeat !important;
  -webkit-mask-position: center !important;
          mask-position: center !important;
  -webkit-mask-size: contain !important;
          mask-size: contain !important;
  transition: color 140ms ease-out, opacity 140ms ease-out !important;
}
/* Hide the underlying <path> so only our masked shape is visible.            */
.eye-icon > * { display: none !important; }

/* Hidden / invisible patch — eye-off outline (diagonal slash through eye).
 * JS switches the inner <path> fill between #2563eb (visible) and #93c5fd
 * (hidden); match the hidden state via :has().                              */
.eye-icon:has(path[fill="#93c5fd"]),
.trame-file-item.hidden .eye-icon,
.trame-file-item[data-visible="false"] .eye-icon,
.eye-icon.eye-hidden,
.eye-icon.hidden {
  color: var(--b2-ink-4) !important;
  opacity: 0.6 !important;
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-7-11-7a19.79 19.79 0 0 1 4.06-5.94m4 -1.57A9 9 0 0 1 12 5c7 0 11 7 11 7a18 18 0 0 1-2.16 3.19'/><path d='M9.88 9.88a3 3 0 1 0 4.24 4.24'/><line x1='2' y1='2' x2='22' y2='22'/></svg>") !important;
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-7-11-7a19.79 19.79 0 0 1 4.06-5.94m4 -1.57A9 9 0 0 1 12 5c7 0 11 7 11 7a18 18 0 0 1-2.16 3.19'/><path d='M9.88 9.88a3 3 0 1 0 4.24 4.24'/><line x1='2' y1='2' x2='22' y2='22'/></svg>") !important;
}
/* Hover — slightly brighter.                                                 */
.trame-file-item:hover .eye-icon {
  color: var(--b2-acc-hover) !important;
  opacity: 1 !important;
}

/* ============================================================================
 * Progress indicators
 * ========================================================================== */
.progress-container { background: transparent !important; color: var(--b2-ink) !important; }
.progress-step { color: var(--b2-ink-3) !important; font-family: var(--f-mono) !important; font-size: 10.5px !important; }
.progress-step.active    { color: var(--b2-acc) !important; }
.progress-step.completed { color: var(--b2-ok) !important; }
.progress-step::before   { background: var(--b2-line) !important; border: 2px solid var(--b2-line) !important; }
.progress-step.active::before {
  background: var(--b2-acc) !important;
  border-color: var(--b2-acc) !important;
  box-shadow: 0 0 0 3px var(--b2-acc-soft) !important;
}
.progress-step.completed::before {
  background: var(--b2-ok) !important;
  border-color: var(--b2-ok) !important;
}
.progress-step:not(:last-child)::after {
  background: var(--b2-line) !important;
}
.progress-step.completed:not(:last-child)::after {
  background: var(--b2-ok) !important;
}
.progress-bar {
  background: var(--b2-sunken) !important;
  border-radius: 2px !important;
}
.progress-bar-fill {
  background: var(--b2-acc) !important;
}

/* ============================================================================
 * Login / Provisioning / Modals
 * --------------------------------------------------------------------------
 * Base rules live in main.css and already use the B² tokens declared above,
 * so this theme file does not need to override them. Variable reassignment
 * (e.g. swapping --b2-ink / --b2-surface) is enough to retheme the modal.
 * ========================================================================== */

/* ============================================================================
 * Toasts
 * ========================================================================== */
.toast {
  background: var(--b2-surface) !important;
  color: var(--b2-ink) !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 6px !important;
  box-shadow: 0 8px 20px rgba(17,18,22,0.10) !important;
  font-family: var(--f-sans) !important;
  font-size: 13px !important;
}
.toast.toast-success { border-left: 3px solid var(--b2-ok) !important; }
.toast.toast-error   { border-left: 3px solid var(--b2-err) !important; }
.toast.toast-warning { border-left: 3px solid var(--b2-warn) !important; }
.toast.toast-info    { border-left: 3px solid var(--b2-acc) !important; }

/* ============================================================================
 * Misc panels / overlays (unified light surfaces)
 * ========================================================================== */
.batch-mode,
.batch-panel,
.batch-config,
.batch-preview,
.parameter-sweep,
.case-families,
.library-modal,
.library-container,
.stl-library,
.file-drop-overlay,
.command-dropdown,
.dropdown-content,
.popover,
.qa-panel,
.help-panel,
.examples-panel {
  background: var(--b2-surface) !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 6px !important;
  color: var(--b2-ink) !important;
  box-shadow: 0 6px 20px rgba(17,18,22,0.08) !important;
}
.library-modal-backdrop { background: rgba(17,18,22,0.30) !important; }

/* ============================================================================
 * ROUND 1 — DETAIL PASS (typography fixes, micro-interactions, rhythm)
 * Goal: tighten the refined-minimalism aesthetic. No maximalism — every
 * addition is a small, precise choice.
 * ========================================================================== */

/* 1. Global motion curve — 120 ms ease-out on interactive surfaces.
 *    Unifies the visual rhythm without adding loud transitions anywhere.     */
.new-chat-btn,
.conversation-item,
.conversation-menu-btn,
.chat-header button,
.view-toggle button,
.pdf-controls button,
.send-button, .send-btn, button.send-button,
.attachment-btn, .upload-btn,
.login-button,
.provisioning-btn-retry, .provisioning-btn-cancel,
.slice-radio-label,
.slice-btn, .slice-btn-primary, .slice-btn-secondary,
#trameFieldSelector, #trameColormapSelector,
#trameRangeMin, #trameRangeMax,
#trameTimestepSelector,
.trame-file-item,
.file-tree-item,
.report-version-item,
.trame-visibility-btn {
  transition:
    background-color 120ms ease-out,
    border-color     120ms ease-out,
    color            120ms ease-out,
    transform        120ms ease-out,
    box-shadow       120ms ease-out !important;
}

/* 2. Fix send-button font cascade — it was reporting font-family:Arial
 *    because of a UA default on bare <button>. Force inheritance so Geist
 *    wins and the button aligns with the rest of the composer.              */
.send-button, .send-btn, button.send-button,
.attachment-btn, .upload-btn,
.chat-header button,
.pdf-controls button,
.view-toggle button,
.conversation-menu-btn {
  font-family: var(--f-sans) !important;
}

/* 3. Date-group label in the sidebar.
 *    The actual class is .time-group-title, which contains a 🕐 emoji
 *    inline. Style the container as mono-uppercase, hide any emoji/icon
 *    child, and keep things quiet.                                           */
.time-group-title,
.conversations-section-header,
.conv-section-header,
.time-section-header,
.conversations-time-group {
  padding: 14px 10px 6px !important;
  font-family: var(--f-mono) !important;
  font-size: 10px !important;
  font-weight: 500 !important;
  color: var(--b2-ink-4) !important;
  letter-spacing: 0.12em !important;
  text-transform: uppercase !important;
  background: transparent !important;
  border: 0 !important;
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
}
/* suppress emoji/icon children — keep the label textual and quiet */
.time-group-title > svg,
.time-group-title > i,
.time-group-title > img {
  display: none !important;
}
/* if the emoji is inline text (not a child), this still works: a subtle
 * text-indent trick would mangle layout, so leave the emoji visible but
 * its ink muted via the parent color token.                                 */

/* 4. Conversation item — a little more breathing room, honest truncation,
 *    a hairline that only appears on hover as a soft surface.
 *    Truncation lives on .conversation-title so the context menu (absolutely
 *    positioned inside the item) is not clipped.                            */
.conversation-item {
  padding: 6px 10px !important;
  min-height: 26px !important;
}
.conversation-item:hover {
  background: var(--b2-sunken) !important;
}
.conversation-item.active {
  background: var(--b2-surface) !important;
  box-shadow: inset 2px 0 0 var(--b2-acc), 0 0 0 1px var(--b2-line) !important;
}

/* 5. New-chat button — slightly firmer at rest, blue-soft on hover.
 *    Press state presses down 0.5 px.                                       */
.new-chat-btn {
  background: var(--b2-surface) !important;
  height: 28px !important;
  line-height: 1 !important;
}
.new-chat-btn:hover {
  background: var(--b2-acc-soft) !important;
  border-color: var(--b2-acc-line) !important;
  color: var(--b2-acc-ink) !important;
}
.new-chat-btn:active { transform: translateY(0.5px) !important; }

/* 6. Rail header counter — was reporting width 0 because the <span> had
 *    no content rule. Ensure it sits at the right with tabular-nums.       */
.trame-file-list-header {
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
  gap: 8px !important;
}
.trame-file-list-header h3 {
  margin: 0 !important;
  letter-spacing: -0.005em !important;
}
.trame-file-list-header span {
  color: var(--b2-ink-4) !important;
  font-family: var(--f-mono) !important;
  font-size: 10.5px !important;
  font-variant-numeric: tabular-nums !important;
  white-space: nowrap !important;
  display: inline-block !important;
}

/* 7. Send-button gains presence — round, dark ink on hover, subtle lift.   */
.send-button:hover, button.send-button:hover, .send-btn:hover {
  background: var(--b2-ink) !important;
  border-color: var(--b2-ink) !important;
  color: #FFFFFF !important;
  transform: translateY(-0.5px) !important;
  box-shadow: 0 2px 6px rgba(17,18,22,0.12) !important;
}
.send-button:active, button.send-button:active, .send-btn:active {
  transform: translateY(0) !important;
  box-shadow: none !important;
}

/* 8. Composer ring — refine so it's a hair softer at rest and a touch
 *    tighter on focus (3 px → 2 px glow + 1 px line).                      */
.input-wrapper {
  box-shadow: 0 1px 0 rgba(17,18,22,0.02) !important;
}
.input-wrapper:focus-within {
  border-color: var(--b2-user-rule) !important;
  box-shadow: 0 1px 0 rgba(17,18,22,0.02) !important;
}

/* 9. Column resizer — visible but restrained, crisp on interaction.        */
.panel-resizer {
  width: 4px !important;
  background: transparent !important;
  position: relative !important;
}
.panel-resizer::before {
  content: "" !important;
  position: absolute !important;
  left: 50% !important; top: 50% !important;
  width: 1px !important; height: 24px !important;
  background: var(--b2-line) !important;
  transform: translate(-50%, -50%) !important;
  opacity: 0 !important;
  transition: opacity 120ms ease-out !important;
}
.panel-resizer:hover::before,
body.resizing .panel-resizer::before { opacity: 1 !important; background: var(--b2-ink-4) !important; }
.panel-resizer:hover, body.resizing .panel-resizer { background: transparent !important; }

/* 10. Active conversation — accent its left rule slightly more clearly.    */
.conversation-item.active {
  font-weight: 500 !important;
}

/* 11. Focus rings — crisper and brand-consistent everywhere.
 *     Replace the generic 2-px outline with a 3-px acc-soft glow + line.   */
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
a:focus-visible,
[tabindex]:focus-visible {
  outline: none !important;
  border-color: var(--b2-acc) !important;
  box-shadow: 0 0 0 3px var(--b2-acc-soft) !important;
  transition:
    border-color 120ms ease-out,
    box-shadow 120ms ease-out !important;
}

/* 12. Slice direction pills — gentle hover + pressed feedback.             */
.slice-radio-label:hover { background: var(--b2-sunken) !important; }
.slice-radio:active .slice-radio-label { transform: translateY(0.5px) !important; }

/* 13. View toggle underline motion — slide in/out instead of snap.         */
.view-toggle button::after {
  transform: scaleX(0) !important;
  transform-origin: center !important;
  transition: transform 160ms ease-out !important;
}
.view-toggle button.active::after { transform: scaleX(1) !important; }

/* 14. Primary slice button — a touch of warmth on hover.                  */
.slice-btn-primary {
  box-shadow: 0 1px 0 rgba(17,18,22,0.04) !important;
}
.slice-btn-primary:hover:not(:disabled) {
  transform: translateY(-0.5px) !important;
  box-shadow: 0 3px 10px rgba(17,18,22,0.18) !important;
  filter: none !important;
}
.slice-btn-primary:active:not(:disabled) {
  transform: translateY(0) !important;
  box-shadow: 0 1px 0 rgba(17,18,22,0.04) !important;
}

/* 15. Tabular numerals everywhere numeric — the hallmark of a CFD tool.    */
.conversation-meta,
.message-timestamp,
.slice-position-value,
.slice-preview-info,
#trameColorbarMin, #trameColorbarMid, #trameColorbarMax,
#trameRangeMin, #trameRangeMax,
.rail-row input,
.file-tree-item .file-name,
.trame-file-item .file-name {
  font-variant-numeric: tabular-nums !important;
}

/* 16. Subtle hairline separators inside sidebar — divide the date groups. */
.time-group-title { position: relative !important; }
.time-group-title::before {
  content: "" !important;
  position: absolute !important;
  left: 10px; right: 10px; top: 0 !important;
  height: 1px !important;
  background: var(--b2-line) !important;
  opacity: 0.6 !important;
}
.time-group-title:first-child::before { display: none !important; }

/* 17. Welcome headline — a small display-font moment. Keep restrained.     */
.welcome-message h2,
.welcome-message .greeting-text {
  font-size: 22px !important;
  letter-spacing: -0.02em !important;
  line-height: 1.2 !important;
}
.welcome-message p,
.welcome-message .typewriter-subtitle,
.welcome-message .typewriter-hint {
  font-size: 13px !important;
  line-height: 1.55 !important;
  color: var(--b2-ink-3) !important;
}

/* 18. Title gets a hair more letter-spacing discipline.                    */
.chat-header h1 {
  font-weight: 600 !important;
  letter-spacing: -0.018em !important;
  color: var(--b2-ink) !important;
}

/* 19. Sign Out button — restrained hover motion.                           */
.chat-header button:hover {
  background: var(--b2-sunken) !important;
  color: var(--b2-ink) !important;
}

/* 20. Scrollbar refinement — a hair thinner for desktop elegance.          */
::-webkit-scrollbar           { width: 8px; height: 8px; }
::-webkit-scrollbar-thumb     { background: var(--b2-line-2); border-radius: 4px; border: 2px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background: var(--b2-ink-4); background-clip: padding-box; }

/* ============================================================ */
/* ROUND 2 — REFINEMENT PASS                                    */
/* Depth, motion, typography polish, state clarity.             */
/* ============================================================ */

/* 21. Entrance motion — single orchestrated reveal on first paint.         */
/*     Refined minimalism means ONE well-tuned sequence, not many.          */
@keyframes b2-rise {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes b2-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.sidebar            { animation: b2-fade 280ms ease-out both; }
.chat-header,
.pdf-header         { animation: b2-fade 320ms ease-out 60ms both; }
.trame-viewer-container,
.pdf-viewer-content { animation: b2-fade 360ms ease-out 120ms both; }
.chat-input-container { animation: b2-rise 360ms ease-out 180ms both; }
.message            { animation: b2-rise 280ms ease-out both; }

/* 22. Composer — framed with the lightest surface lift so it reads as      */
/*     "where you compose", not as the page background.                     */
.chat-input-container {
  border-top: 1px solid var(--b2-line) !important;
  background: var(--b2-bg) !important;
  padding: 14px 22px 18px !important;
}
.chat-input-wrapper,
.chat-input-form    {
  background: var(--b2-surface) !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 10px !important;
  box-shadow: 0 1px 2px rgba(17, 18, 22, 0.03), inset 0 0 0 1px rgba(255,255,255,0.6) !important;
  transition: border-color 160ms ease-out, box-shadow 160ms ease-out !important;
}
.chat-input-wrapper:focus-within,
.chat-input-form:focus-within {
  border-color: var(--b2-acc) !important;
  box-shadow: 0 0 0 3px var(--b2-acc-soft), 0 1px 2px rgba(17, 18, 22, 0.04) !important;
}
#chatInput {
  font-family: var(--f-mono) !important;
  font-size: 12.5px !important;
  line-height: 1.6 !important;
  color: var(--b2-ink) !important;
}
#chatInput::placeholder {
  color: var(--b2-ink-4) !important;
  font-family: var(--f-sans) !important;
  font-style: normal !important;
}

/* 23. Send button — matches .attach-btn paperclip: neutral black-and-white,
 *     ghost square, ink icon, sunken-grey hover. No blue accent fill.     */
.send-btn {
  width: 28px !important;
  height: 28px !important;
  padding: 0 !important;
  border: 0 !important;
  border-radius: 6px !important;
  background: transparent !important;
  color: var(--b2-ink-3) !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  cursor: pointer !important;
  transition: color 120ms ease-out, background 120ms ease-out !important;
}
.send-btn svg {
  width: 16px !important;
  height: 16px !important;
  fill: none !important;
  color: currentColor !important;
}
.send-btn:hover:not(:disabled) {
  color: var(--b2-ink) !important;
  background: var(--b2-sunken) !important;
}
.send-btn:not(:disabled):not(.disabled) {
  color: var(--b2-ink-2) !important;
}
.send-btn:not(:disabled):not(.disabled):hover {
  color: var(--b2-ink) !important;
  background: var(--b2-sunken) !important;
}
.send-btn:disabled,
.send-btn.disabled {
  opacity: 0.5 !important;
  cursor: not-allowed !important;
}
.attach-btn {
  color: var(--b2-ink-4) !important;
  transition: color 140ms ease-out !important;
}
.attach-btn:hover { color: var(--b2-ink-2) !important; }

/* 24. Messages — three-layer paper elevation.
       Faint warm drop + tight under-shadow + 1-px inset top highlight =
       the subtle bevel of a paper sheet under soft light. Defined here
       (not earlier) because this round-24 patch is the last cascade
       point with the same selector specificity as the base AI bubble
       rule, so anything in the bubble rule needs to be repeated here
       to stick. Keep this and the base rule synced. */
.message.message-assistant .message-content {
  box-shadow:
    0 1px 3px rgba(82, 60, 30, 0.05),
    0 1px 1px rgba(82, 60, 30, 0.03),
    inset 0 1px 0 rgba(255, 255, 255, 0.4) !important;
  transition: border-color 140ms ease-out, box-shadow 140ms ease-out !important;
}
.message.message-assistant:hover .message-content {
  box-shadow:
    0 2px 6px rgba(82, 60, 30, 0.07),
    0 1px 2px rgba(82, 60, 30, 0.04),
    inset 0 1px 0 rgba(255, 255, 255, 0.5) !important;
}
.message.message-user .message-content {
  box-shadow: inset 0 1px 0 rgba(224, 182, 94, 0.08) !important;
}

/* 25. Viewer — frame depth via inner shadow. Scoped to vtk area only.      */
#vtkjsContainer {
  box-shadow:
    inset 0 0 0 1px rgba(17, 18, 22, 0.04),
    inset 0 24px 48px -24px rgba(17, 18, 22, 0.04),
    inset 0 -24px 48px -24px rgba(42,120,214, 0.04) !important;
}

/* 26. Rescale button (↔) — was inheriting UA default chrome.               */
#trameRescaleBtn {
  width: 24px !important;
  height: 24px !important;
  font-size: 11px !important;
  font-family: var(--f-mono) !important;
  border: 1px solid var(--b2-line-2) !important;
  border-radius: 5px !important;
  background: var(--b2-surface) !important;
  color: var(--b2-ink-3) !important;
  cursor: pointer !important;
  transition: all 140ms ease-out !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
}
#trameRescaleBtn:hover {
  border-color: var(--b2-acc) !important;
  color: var(--b2-acc) !important;
  background: var(--b2-acc-soft) !important;
}

/* 27. Generate button — switch to brand accent. Dark-on-cream feels off.   */
#trameGenerateBtn,
button#trameGenerateBtn,
.trame-generate-btn,
button.trame-generate-btn {
  background: var(--b2-acc) !important;
  color: #FFFFFF !important;
  border: 1px solid var(--b2-acc) !important;
  border-radius: 6px !important;
  font-family: var(--f-sans) !important;
  font-size: 12.5px !important;
  font-weight: 500 !important;
  letter-spacing: -0.005em !important;
  padding: 7px 14px !important;
  box-shadow: 0 1px 2px rgba(42,120,214, 0.18) !important;
  transition: all 160ms ease-out !important;
}
#trameGenerateBtn:hover,
.trame-generate-btn:hover {
  background: var(--b2-acc-hover) !important;
  border-color: var(--b2-acc-hover) !important;
  box-shadow: 0 2px 6px rgba(42,120,214, 0.22), 0 0 0 3px var(--b2-acc-soft) !important;
  transform: translateY(-0.5px) !important;
}
#trameGenerateBtn svg,
.trame-generate-btn svg { color: #FFFFFF !important; fill: #FFFFFF !important; }

/* 28. Select/dropdown — custom chevron, hairline border, mono numerics.    */
.trame-file-list select,
#trameTimestepSelector,
#trameFieldSelector,
#trameColormapSelector {
  appearance: none !important;
  -webkit-appearance: none !important;
  background-color: var(--b2-surface) !important;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 10 10'><path d='M2 3.5l3 3 3-3' stroke='%239CA3AF' stroke-width='1.2' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>") !important;
  background-repeat: no-repeat !important;
  background-position: right 8px center !important;
  padding: 5px 24px 5px 10px !important;
  font-family: var(--f-mono) !important;
  font-size: 11px !important;
  color: var(--b2-ink) !important;
  border: 1px solid var(--b2-line-2) !important;
  border-radius: 5px !important;
  transition: all 140ms ease-out !important;
}
.trame-file-list select:hover { border-color: var(--b2-ink-4) !important; }
.trame-file-list select:focus-visible {
  border-color: var(--b2-acc) !important;
  outline: none !important;
  box-shadow: 0 0 0 3px var(--b2-acc-soft) !important;
}

/* 29. Range inputs (Min/Max) — consistent with select, tabular numerics.
 *     Width is now driven by the .trame-range-inputs flex row (flex: 1 1 0)
 *     so long values like "-1131.96" fit without clipping. 11 px mono keeps
 *     max character headroom before hitting the 94 px input boundary.       */
#trameRangeMin, #trameRangeMax {
  font-family: var(--f-mono) !important;
  font-size: 11px !important;
  font-variant-numeric: tabular-nums !important;
  color: var(--b2-ink) !important;
  border: 1px solid var(--b2-line-2) !important;
  border-radius: 5px !important;
  padding: 4px 6px !important;
  transition: all 140ms ease-out !important;
}
#trameRangeMin:focus, #trameRangeMax:focus {
  border-color: var(--b2-acc) !important;
  outline: none !important;
  box-shadow: 0 0 0 3px var(--b2-acc-soft) !important;
}
#trameRangeMin::placeholder, #trameRangeMax::placeholder {
  color: var(--b2-ink-5) !important;
  font-family: var(--f-sans) !important;
}

/* 30. Slice / opacity value readout — subtle tabular text, NOT a pill.
 *     (The blue pill competed with Generate and felt noisy. Keep it quiet.) */
.slice-position-pill,
[class*="slice-position"] {
  background: transparent !important;
  color: var(--b2-ink) !important;
  border: 0 !important;
  border-radius: 0 !important;
  font-family: var(--f-mono) !important;
  font-size: 11px !important;
  font-weight: 500 !important;
  font-variant-numeric: tabular-nums !important;
  letter-spacing: 0.01em !important;
  padding: 0 2px !important;
}

/* 31. Direction pills — firmer active state, softer inactive.             */
.slice-radio-label {
  background: var(--b2-surface) !important;
  border: 1px solid var(--b2-line-2) !important;
  border-radius: 6px !important;
  padding: 5px 0 !important;
  font-family: var(--f-mono) !important;
  font-size: 11px !important;
  font-weight: 500 !important;
  color: var(--b2-ink-3) !important;
  transition: all 140ms ease-out !important;
  cursor: pointer !important;
}
.slice-radio-label:hover {
  border-color: var(--b2-ink-4) !important;
  color: var(--b2-ink) !important;
}
.slice-radio input[type="radio"]:checked + .slice-radio-label,
.slice-radio-label.active {
  background: var(--b2-acc-soft) !important;
  border-color: var(--b2-acc) !important;
  color: var(--b2-acc) !important;
  font-weight: 600 !important;
}

/* 32. Conversation list items — hover micro-shift, consistent rhythm.      */
.conversation-item {
  transition: background 140ms ease-out, color 140ms ease-out, transform 140ms ease-out !important;
}
.conversation-item:hover:not(.active) {
  background: var(--b2-sunken) !important;
  color: var(--b2-ink) !important;
}
.conversation-item.active::before {
  /* scoped 2px accent rule (replaces inset box-shadow for crisper edge) */
  content: none !important;
}

/* 33. Empty states — quieter, more confident typography.                   */
.trame-empty-state,
[class*="empty-state"] {
  color: var(--b2-ink-4) !important;
}
.trame-empty-state-title,
[class*="empty-state"] [class*="title"],
.trame-empty-state > *:first-child {
  font-family: var(--f-sans) !important;
  font-size: 13px !important;
  font-weight: 500 !important;
  color: var(--b2-ink-2) !important;
  letter-spacing: -0.005em !important;
}
.trame-empty-state-text,
[class*="empty-state"] p {
  font-family: var(--f-mono) !important;
  font-size: 11px !important;
  color: var(--b2-ink-4) !important;
  letter-spacing: 0.01em !important;
  margin-top: 6px !important;
}

/* 34. App title — refined cross-font rhythm.                               */
.app-title {
  font-family: var(--f-mono) !important;
  font-size: 13px !important;
  font-weight: 500 !important;
  letter-spacing: -0.005em !important;
  color: var(--b2-ink) !important;
}

/* 35. New Simulation button — ghost outline with accent-on-hover.          */
.new-chat-btn {
  /* Typography intentionally mirrors the chat-header h1 "Agentic-AI Engineer":
     Geist Sans 14px, weight 600, letter-spacing -0.015em, ink color. */
  background: var(--b2-surface) !important;
  border: 1px solid var(--b2-line-2) !important;
  color: var(--b2-ink) !important;
  font-family: var(--f-sans) !important;
  font-size: 14px !important;
  font-weight: 600 !important;
  letter-spacing: -0.015em !important;
  border-radius: 6px !important;
  transition: all 160ms ease-out !important;
}
.new-chat-btn:hover {
  background: var(--b2-sunken) !important;
  border-color: var(--b2-ink-4) !important;
  color: var(--b2-ink) !important;
  transform: translateY(-0.5px) !important;
  box-shadow: 0 1px 3px rgba(17,18,22,0.06) !important;
}

/* 36. Rail section headers — unified mono caps (one type-system, one voice).
 *     Header + count share family/tracking so they read as a pair.          */
.trame-file-list-header > *:first-child,
.trame-file-list-header h3 {
  font-family: var(--f-mono) !important;
  font-size: 10.5px !important;
  font-weight: 600 !important;
  letter-spacing: 0.14em !important;
  text-transform: uppercase !important;
  color: var(--b2-ink-2) !important;
  line-height: 1.2 !important;
}
.trame-file-list-header > *:last-child,
.trame-file-list-header > span,
.trame-file-list-header .count {
  font-family: var(--f-mono) !important;
  font-size: 10px !important;
  font-weight: 500 !important;
  font-variant-numeric: tabular-nums !important;
  letter-spacing: 0.14em !important;
  text-transform: uppercase !important;
  color: var(--b2-ink-4) !important;
}

/* 37. Labels — Time:/Field:/Color:/Range: — unified mono-uppercase.        */
.trame-file-list label,
.trame-file-list > div > label {
  font-family: var(--f-mono) !important;
  font-size: 10px !important;
  font-weight: 500 !important;
  letter-spacing: 0.08em !important;
  text-transform: uppercase !important;
  color: var(--b2-ink-4) !important;
}

/* 38. Section dividers in right rail — hairline with breathing room.       */
/*     Scoped to top-level top-panel sections only to avoid nested bleed.   */
.trame-file-list > .trame-top-panel > div + div,
.trame-file-list > .trame-vtu-panel > div + div {
  border-top: 1px solid var(--b2-line) !important;
  padding-top: 14px !important;
  margin-top: 14px !important;
}
/* Slice rows share the SAME left/right edge as the Field/Color/Range controls
 * above (no extra inset), so labels line up and the slider value, X/Y/Z, and
 * dropdowns all end on one right edge. The panel's own padding keeps the
 * thumb inside; no per-row inset needed. */
.slice-control-row {
  min-width: 0 !important;
  max-width: 100% !important;
  padding: 0 !important;
  gap: 8px !important;
  box-sizing: border-box !important;
}
.slice-slider-container {
  flex: 1 1 auto !important;
  min-width: 0 !important;
  max-width: none !important;
}
.slice-slider {
  flex: 1 1 auto !important;
  min-width: 0 !important;
  max-width: 100% !important;
  width: 100% !important;
}
.slice-position-value {
  flex: 0 0 auto !important;
  font-size: 10.5px !important;
  min-width: 28px !important;
  text-align: right !important;
}

/* 39. Layer rows (inlet/outlet/walls) — consistent vertical rhythm.        */
.trame-file-list [class*="layer"] {
  font-family: var(--f-mono) !important;
  font-size: 12px !important;
  color: var(--b2-ink-2) !important;
  padding: 4px 0 !important;
}
.trame-file-list svg[class*="eye"],
.trame-file-list [class*="visibility"] svg {
  color: var(--b2-acc) !important;
  opacity: 0.85 !important;
  transition: opacity 140ms ease-out !important;
}
.trame-file-list svg[class*="eye"]:hover,
.trame-file-list [class*="visibility"]:hover svg {
  opacity: 1 !important;
}

/* 40. Global focus-visible baseline — keyboard users never lose the thread */
*:focus-visible:not(input):not(textarea):not(select) {
  outline: none !important;
  box-shadow: 0 0 0 3px var(--b2-acc-soft) !important;
  border-radius: 4px !important;
}
input:focus-visible,
textarea:focus-visible {
  outline: none !important;
}

/* ============================================================================
 * ROUND 3 — Sidebar refinement
 * ----------------------------------------------------------------------------
 *   Goal: strip the accent chrome from the conversation list, tighten the
 *   vertical rhythm, and let typography + cream warmth do the work.
 *
 *   · No blue rule on active. Active = subtle cream fill + medium weight.
 *   · Denser items: one-line rows, hover menu button, compact padding.
 *   · Group headers quieter, with a softer hairline and less breathing room.
 * ========================================================================== */

/* 41. Conversation item — single-line density, no accent chrome anywhere.
 *     (Transition is narrowed to `color` only — a bug in Chrome can freeze
 *     background-color transitions with fill:backwards on first paint,
 *     leaving the active state stuck transparent. Paint background instantly.) */
.conversation-item {
  padding: 5px 10px !important;
  margin: 0 0 3px !important;
  border: 0 !important;
  border-radius: 6px !important;
  min-height: 28px !important;
  display: flex !important;
  align-items: center !important;
  gap: 6px !important;
  line-height: 1.4 !important;
  color: var(--b2-ink-2) !important;
  box-shadow: none !important;
  transition: color 140ms ease-out !important;
}

/* 42. Hover — softest tint, no movement. Menu button surfaces here.          */
.conversation-item:hover:not(.active) {
  background: var(--b2-sunken) !important;
  color: var(--b2-ink) !important;
  box-shadow: none !important;
  border: 0 !important;
}

/* 43. Active — cream fill ties to the user bubble. Weight carries the state. */
.conversation-item.active,
.conversation-item.active:hover {
  background: var(--b2-user-bg) !important;
  color: var(--b2-ink) !important;
  font-weight: 500 !important;
  border: 0 !important;
  box-shadow: none !important;
}
.conversation-item.active::before,
.conversation-item.active::after {
  content: none !important;
  display: none !important;
  background: transparent !important;
  box-shadow: none !important;
}

/* 44. Conversation title — inherits item weight; tighter tracking.           */
.conversation-title {
  font-family: var(--f-sans) !important;
  font-size: 12.5px !important;
  font-weight: inherit !important;
  color: inherit !important;
  letter-spacing: -0.005em !important;
  line-height: 1.4 !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  white-space: nowrap !important;
  flex: 1 1 auto !important;
  min-width: 0 !important;
}

/* 45. Menu button — hidden at rest, surfaces on hover/active.                */
.conversation-menu-btn {
  opacity: 0 !important;
  width: 20px !important;
  height: 20px !important;
  padding: 0 !important;
  margin: 0 !important;
  font-size: 13px !important;
  line-height: 1 !important;
  border: 0 !important;
  border-radius: 4px !important;
  color: var(--b2-ink-4) !important;
  background: transparent !important;
  flex: 0 0 auto !important;
  transition: opacity 120ms ease-out, background-color 120ms ease-out, color 120ms ease-out !important;
}
.conversation-item:hover .conversation-menu-btn,
.conversation-item.active .conversation-menu-btn,
.conversation-menu-btn:focus-visible {
  opacity: 1 !important;
}
.conversation-menu-btn:hover {
  background: rgba(17,18,22,0.06) !important;
  color: var(--b2-ink) !important;
}

/* 46. Date-group label — quieter, tighter, hairline inset to the title.      */
.time-group-title,
.conversations-section-header,
.conv-section-header,
.time-section-header,
.conversations-time-group {
  padding: 14px 10px 4px !important;
  margin: 0 !important;
  font-family: var(--f-mono) !important;
  font-size: 9.5px !important;
  font-weight: 500 !important;
  letter-spacing: 0.14em !important;
  text-transform: uppercase !important;
  color: var(--b2-ink-4) !important;
}
.time-group-title::before {
  left: 10px !important;
  right: 10px !important;
  top: 6px !important;
  height: 1px !important;
  background: var(--b2-line) !important;
  opacity: 0.55 !important;
}

/* 47. Time-group container — collapse the oversized 20 px bottom gap.        */
.time-group,
.conversations-time-group > .time-group {
  margin: 0 0 6px !important;
}

/* 48. Conversation list container — a touch more air at the top, no more.   */
.conversation-list,
.conversations-list {
  padding: 2px 6px 20px !important;
}

/* ============================================================================
 * ROUND 4 — View canvas atmosphere + Files layout flip
 * ----------------------------------------------------------------------------
 *   A. Canvas radial glow + visible grid (3D model earns a "stage")
 *   B. Floating case-info card (top-left of canvas)
 *   C. Rail section dividers — editorial chapter markers
 *   D. Colormap dropdown with a real gradient swatch preview
 *   Files flip:  tree → left, content → right (conventional)
 *   Files tree:  12 px type, sunken hover, cream active
 *   Log files:   mono + amber left rule — distinct from directories
 * ========================================================================== */

/* ---------------------------------------------------------------- View : A */
/* Canvas "stage": warm off-white floor + soft radial glow + quiet grid.
 * Kept intentionally cheap — no masks, no ::before grid, no backdrop-filter
 * (they cause frame stalls on a 1.6 M-pixel canvas).                        */
.trame-viewer-container {
  background: var(--b2-bg) !important;
}
#vtkjsContainer {
  background:
    radial-gradient(ellipse 60% 45% at 50% 45%, rgba(42,120,214,0.06), rgba(42,120,214,0) 72%),
    linear-gradient(to bottom, #FAFAF9 0%, #F3F2EF 100%) !important;
  position: relative !important;
}

/* ---------------------------------------------------------------- View : B */
/* Floating case-info card at the top-left of the canvas.
 * Editorial tone: mono caps label, sans serif case name, mono tabular data. */
.vtk-case-card {
  position: absolute !important;
  top: 16px !important;
  left: 16px !important;
  z-index: 20 !important;
  min-width: 220px !important;
  padding: 12px 14px 10px !important;
  background: rgba(255,255,255,0.94) !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 8px !important;
  box-shadow:
    0 1px 2px rgba(17,18,22,0.05),
    0 8px 24px -12px rgba(17,18,22,0.12) !important;
  pointer-events: auto !important;
  font-family: var(--f-sans) !important;
  color: var(--b2-ink) !important;
}
@keyframes b2-rise {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.vtk-case-card-label {
  font-family: var(--f-mono) !important;
  font-size: 9.5px !important;
  font-weight: 500 !important;
  letter-spacing: 0.16em !important;
  text-transform: uppercase !important;
  color: var(--b2-ink-4) !important;
  margin-bottom: 4px !important;
}
.vtk-case-card-name {
  font-family: var(--f-sans) !important;
  font-size: 14px !important;
  font-weight: 600 !important;
  letter-spacing: -0.01em !important;
  line-height: 1.25 !important;
  color: var(--b2-ink) !important;
  padding-bottom: 8px !important;
  margin-bottom: 8px !important;
  border-bottom: 1px solid var(--b2-line) !important;
  max-width: 280px !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  white-space: nowrap !important;
}
.vtk-case-card-meta {
  display: flex !important;
  align-items: center !important;
  gap: 10px !important;
  font-family: var(--f-mono) !important;
  font-size: 10.5px !important;
  font-variant-numeric: tabular-nums !important;
  color: var(--b2-ink-2) !important;
}
.vtk-case-card-row {
  display: inline-flex !important;
  align-items: baseline !important;
  gap: 5px !important;
}
.vtk-case-card-key {
  color: var(--b2-ink-4) !important;
  letter-spacing: 0.08em !important;
  text-transform: uppercase !important;
  font-size: 9.5px !important;
}
.vtk-case-card-val {
  color: var(--b2-ink) !important;
  font-weight: 500 !important;
}
.vtk-case-card-sep {
  width: 1px !important;
  height: 10px !important;
  background: var(--b2-line) !important;
}

/* ---------------------------------------------------------------- View : C */
/* Rail section headers — editorial chapter markers.
 * Each section (Cases / Geometry / VTU Files / Cross-Section / Layers) earns
 * a firm mono-caps label over a hairline divider.                            */
.trame-file-list {
  background: var(--b2-bg) !important;
  border-left: 1px solid var(--b2-line) !important;
  padding: 0 !important;
}
.trame-file-list-header {
  position: relative !important;
  padding: 16px 14px 8px !important;
  margin: 0 !important;
  display: flex !important;
  align-items: baseline !important;
  justify-content: space-between !important;
  gap: 8px !important;
  border-bottom: 0 !important;
}
.trame-file-list-header::before {
  content: "" !important;
  position: absolute !important;
  top: 0 !important;
  left: 14px !important;
  right: 14px !important;
  height: 1px !important;
  background: var(--b2-line) !important;
  opacity: 0.7 !important;
}
.trame-file-list > *:first-child .trame-file-list-header::before,
.trame-file-list > .trame-file-list-header:first-child::before {
  display: none !important;
}
.trame-file-list-header h3 {
  margin: 0 !important;
  font-family: var(--f-mono) !important;
  font-size: 10px !important;
  font-weight: 600 !important;
  letter-spacing: 0.16em !important;
  text-transform: uppercase !important;
  color: var(--b2-ink-2) !important;
}
.trame-file-list-header > span,
.trame-file-list-header .count {
  font-family: var(--f-mono) !important;
  font-size: 9.5px !important;
  font-weight: 500 !important;
  font-variant-numeric: tabular-nums !important;
  letter-spacing: 0.06em !important;
  text-transform: uppercase !important;
  color: var(--b2-ink-4) !important;
}

/* ---------------------------------------------------------------- View : D */
/* Colormap selector — a real gradient swatch painted into the left padding. */
#trameColormapSelector {
  padding: 5px 24px 5px 10px !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 6px !important;
  font-family: var(--f-mono) !important;
  font-size: 11px !important;
  color: var(--b2-ink) !important;
  appearance: none !important;
  -webkit-appearance: none !important;
  background:
    linear-gradient(45deg, transparent 50%, var(--b2-ink-3) 50%) right 10px top 50% / 4px 4px no-repeat,
    linear-gradient(-45deg, transparent 50%, var(--b2-ink-3) 50%) right 6px top 50% / 4px 4px no-repeat,
    var(--b2-bg) !important;
}

/* ---------------------------------------------------------------- Files layout flip */
/* Move the file tree to the LEFT, content viewer to the RIGHT.
 * Use row-reverse so we don't need to touch the DOM order.                  */
.file-browser-container {
  flex-direction: row-reverse !important;
  display: flex !important;
}
/* Give the tree a firmer width (~280 px) and sunken surface.                */
.file-browser-container > .file-tree {
  flex: 0 0 280px !important;
  background: var(--b2-bg) !important;
  border-right: 1px solid var(--b2-line) !important;
  border-left: 0 !important;
  padding: 8px 0 12px !important;
}
.file-browser-container > .file-content-viewer {
  flex: 1 1 auto !important;
  min-width: 0 !important;
  background: var(--b2-surface) !important;
  border-left: 0 !important;
}

/* ---------- Tree panel (wraps title bar + tree) ---------- */
/* Mirrors .file-tree's order: 3 so row-reverse still keeps it on the LEFT.
 * Width is now user-resizable via #explorerResizer (panels/panel-resize.js):
 * the 280 px below is a fallback; the JS writes inline `style.width` from
 * localStorage on init and on every drag, which wins by specificity (no
 * !important on the width rule). Floor / ceiling enforced via min/max +
 * a JS clamp that also accounts for the right pane's MIN_FILE_CONTENT_WIDTH. */
.file-browser-container > .file-tree-panel {
  order: 3 !important;
  flex: 0 0 auto !important;
  width: 280px;
  min-width: 180px !important;
  max-width: 60vw !important;
  background: var(--b2-bg) !important;
  border-right: 1px solid var(--b2-line) !important;
  border-left: 0 !important;
  display: flex !important;
  flex-direction: column !important;
  min-height: 0 !important;
}
.file-tree-panel > .file-tree-title {
  flex: 0 0 40px !important;
  height: 40px !important;
  padding: 0 10px 0 14px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
  background: var(--b2-bg) !important;
  border-bottom: 1px solid var(--b2-line) !important;
}
.file-tree-title .file-tree-title-label {
  font-family: var(--f-sans) !important;
  font-size: 11px !important;
  font-weight: 500 !important;
  color: var(--b2-ink-3) !important;
  letter-spacing: 0.06em !important;
  text-transform: uppercase !important;
}
.file-tree-panel > .file-tree {
  flex: 1 1 auto !important;
  /* Override main.css's width: fit-content / min-width: 200px / max-width: 50% */
  width: 100% !important;
  min-width: 0 !important;
  max-width: 100% !important;
  min-height: 0 !important;
  overflow-y: auto !important;
  overflow-x: auto !important;
  padding: 8px 0 12px !important;
  border: 0 !important;
  background: transparent !important;
}
.tree-refresh-btn {
  width: 24px !important;
  height: 24px !important;
  padding: 0 !important;
  border: 0 !important;
  border-radius: 4px !important;
  background: transparent !important;
  color: var(--b2-ink-3) !important;
  font-family: var(--f-sans) !important;
  font-size: 15px !important;
  line-height: 1 !important;
  cursor: pointer !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  transition: background 120ms ease-out, color 120ms ease-out !important;
}
.tree-refresh-btn:not(:disabled):hover {
  background: var(--b2-sunken) !important;
  color: var(--b2-ink) !important;
}
.tree-refresh-btn:disabled {
  opacity: 0.35 !important;
  cursor: not-allowed !important;
}
.tree-refresh-btn.is-loading {
  opacity: 0.65 !important;
}

/* Hide the entire legacy file-content-header (title + actions). The JS still
 * manages #fileRefreshBtn inside it for state; we only hide it visually.
 * The MutationObserver + click forwarder in index.html keep the tree-title
 * refresh button in sync.                                                    */
#fileContentHeader {
  display: none !important;
}

/* PDF preview re-enables the header so its zoom / page-nav toolbar is visible. */
.file-browser-container.pdf-mode #fileContentHeader {
  display: flex !important;
}

/* ============================================================================
 * Viewport floating quickbar (top-right of 3D canvas)
 *   · Mirrors gnomon's 10 px edge offset but opposite corner for balance.
 *   · Frosted-glass pill, hairline border, theme-token colors.
 *   · Icon-only buttons with tooltip + aria-pressed for toggle state.
 * ========================================================================== */
.viewport-toolbar {
  position: absolute !important;
  top: 10px !important;
  right: 10px !important;
  z-index: 1100 !important;
  display: inline-flex !important;
  align-items: center !important;
  gap: 2px !important;
  padding: 4px !important;
  background: rgba(255, 255, 255, 0.85) !important;
  -webkit-backdrop-filter: blur(8px) !important;
  backdrop-filter: blur(8px) !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 8px !important;
  box-shadow: 0 2px 6px rgba(17, 18, 22, 0.04) !important;
  pointer-events: auto !important;
  /* Fallback for browsers without backdrop-filter support */
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .viewport-toolbar {
    background: rgba(255, 255, 255, 0.94) !important;
  }
}
.viewport-toolbar-btn {
  width: 28px !important;
  height: 28px !important;
  padding: 0 !important;
  border: 0 !important;
  border-radius: 5px !important;
  background-color: transparent !important;
  color: var(--b2-ink-3) !important;
  cursor: pointer !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  transition: background-color 120ms ease-out, color 120ms ease-out !important;
}
.viewport-toolbar-btn:hover {
  background-color: var(--b2-sunken) !important;
  color: var(--b2-ink) !important;
}
.viewport-toolbar-btn:focus-visible {
  outline: 2px solid var(--b2-acc-focus) !important;
  outline-offset: 1px !important;
}
.viewport-toolbar-btn[aria-pressed="true"] {
  background-color: var(--b2-acc-soft-2) !important;
  color: var(--b2-acc-ink) !important;
}
.viewport-toolbar-btn[aria-pressed="true"]:hover {
  background-color: rgba(42, 120, 214, 0.26) !important;
}
.viewport-toolbar-btn svg {
  width: 17px !important;
  height: 17px !important;
  fill: none !important;
  stroke: currentColor !important;
  stroke-width: 1.8 !important;
  stroke-linecap: round !important;
  stroke-linejoin: round !important;
}
/* Hide on very narrow viewports */
@media (max-width: 480px) {
  .viewport-toolbar { display: none !important; }
}

/* ============================================================================
 * Inline 3D viewer — #trameViewer renders INSIDE the Files content area
 * (beside the explorer, which keeps its position) instead of on a separate
 * page. Clicking a renderable file (.vtu/.vtp/.vtk/.pvd/.stl/lagrangian …)
 * shows the 3D canvas here; text/PDF/image still render in #fileContentBody.
 * The controls rail floats as a card over the canvas; the View/Files toggle
 * is retired (the file tree is the selector).
 * ========================================================================== */
.pdf-header { display: none !important; }   /* View/Files toggle retired */

#trameViewer.trame-in-content {
  flex: 1 1 0% !important;
  min-height: 0 !important;
  height: auto !important;
}
.trame-in-content .trame-viewer-container { position: relative !important; }

/* Controls rail → floating, scrollable card pinned top-right over the canvas.
 * The section order (Field/Color/Range → Slice → Opacity → Boundaries →
 * Particles) is preserved automatically because the whole rail is reused. */
.trame-in-content .trame-file-list {
  position: absolute !important;
  /* top/right are NOT !important so the drag's inline top/left can reposition
   * it freely; these only set the initial (top-right) resting position.
   * top:10px matches the viewport toolbar (edges/reset) on the left, so the
   * DISPLAY header lines up with it and is the same height when collapsed. */
  top: 10px;
  right: 12px;
  /* width NOT !important so the edge-drag's inline width sticks; just initial.
   * Height stays content-sized (no vertical resize — the user wants width). */
  width: 228px;
  min-width: 188px;
  max-width: 60%;
  height: auto !important;     /* override base height:100% — size to content, no dead space */
  max-height: 74% !important;  /* cap + scroll only when content is genuinely tall */
  flex: 0 0 auto !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 11px !important;
  box-shadow: 0 6px 22px rgba(17, 18, 22, 0.14) !important;
  background: rgba(255, 255, 255, 0.95) !important;
  -webkit-backdrop-filter: blur(6px) !important;
  backdrop-filter: blur(6px) !important;
  overflow: auto !important;
  /* Above the canvas loading overlay (#vtkLoadingOverlay, z-index 50) so the
   * DISPLAY panel stays fixed/visible while geometry loads (was 30 → the
   * overlay covered it and it appeared to vanish during loading). */
  z-index: 60 !important;
}
/* Keep the edges/reset quickbar clear of the floated rail (rail = 240+12 px). */
.trame-in-content #viewportToolbar { right: 264px !important; }

/* Draggable left/right edge handles for width-resizing the floating DISPLAY
 * panel. Anchored in .trame-viewer-container (not the scrolling rail) and
 * positioned by JS (panel-views.js syncHandles). A thin invisible hit-strip
 * with a faint accent line on hover. */
.trame-in-content .trame-rail-resize {
  position: absolute !important;
  width: 7px !important;
  cursor: ew-resize !important;
  z-index: 61 !important;            /* above the rail (z-index 60) */
  background: transparent;
}
.trame-in-content .trame-rail-resize::after {
  content: "";
  position: absolute;
  top: 8px; bottom: 8px;
  left: 50%;
  width: 2px;
  transform: translateX(-50%);
  border-radius: 2px;
  background: transparent;
  transition: background-color 120ms ease-out;
}
.trame-in-content .trame-rail-resize:hover::after,
.trame-in-content .trame-rail-resize:active::after {
  background: var(--b2-acc);
}

/* Tighten the BOUNDARIES list rows — the default spacing was too airy. */
.trame-in-content .boundary-toggle-list { gap: 1px !important; padding-bottom: 8px !important; }
.trame-in-content .boundary-row { padding: 2px 8px !important; }
.trame-in-content .boundary-row-header { min-height: 22px !important; }
/* BOUNDARIES eye → blue (accent) when the patch is visible; hidden rows keep
 * their grey via the existing .boundary-row.hidden rule. */
.trame-in-content .boundary-row:not(.hidden) .boundary-eye { color: var(--b2-acc) !important; }

/* CASES rows (the case + the files inside it) → match BOUNDARIES' font size
 * (11px) and tight vertical spacing (2px). Excludes the CASES header bar
 * (.scene-group-row), which keeps its VTU-matched 10px/12px padding. */
#sceneTree .file-tree-item:not(.scene-group-row) {
  padding-top: 2px !important;
  padding-bottom: 2px !important;
}
/* Top-level uploads (一级) read larger: a STEP assembly header AND a
 * single-body STL/OBJ row (also a leaf, but top-level). Only the per-part
 * leaves INSIDE an assembly (二级, .scene-part-row) are smaller — so two
 * separate uploads always match. */
#sceneTree .scene-case-row,
#sceneTree .scene-case-row .file-name,
#sceneTree .scene-leaf-row:not(.scene-part-row),
#sceneTree .scene-leaf-row:not(.scene-part-row) .file-name { font-size: 12px !important; }
#sceneTree .scene-part-row,
#sceneTree .scene-part-row .file-name { font-size: 10px !important; }
/* Eye toggles track the same hierarchy. */
#sceneTree .scene-case-row .eye-icon,
#sceneTree .scene-leaf-row:not(.scene-part-row) .eye-icon {
  width: 12px !important; height: 12px !important; flex: 0 0 12px !important;
}
#sceneTree .scene-part-row .eye-icon {
  width: 11px !important; height: 11px !important; flex: 0 0 11px !important;
}
#sceneTree .trame-visibility-btn { padding: 1px !important; }

/* Cases rows: square the highlight. The base .file-tree-item has
 * border-radius:6px, so the blue (selected) / sunken (hover) background was
 * rounded and showed the rail behind it at the corners. Use a flush rectangle. */
#sceneTree .scene-case-row { border-radius: 0 !important; }

/* --- floating-panel refinements --- */
/* Drop the legacy "Geometry · Uploads" section. The unified scene tree
 * (#sceneTree) STAYS — it carries the "Cases" group — but its Uploads group is
 * skipped in renderSceneTree() (uploads are selected from the file explorer). */
.trame-in-content #geometryFilesSection { display: none !important; }

/* Collapse / expand header for the floating controls (injected by
 * panel-views.js ensureTrameInContent). Lets the user tuck the rail away. */
.trame-in-content .trame-rail-collapse {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 7px 10px;
  background: rgba(255, 255, 255, 0.97);
  border-bottom: 1px solid var(--b2-line);
  cursor: move;
  user-select: none;
}
.trame-in-content .trame-rail-collapse .trc-title {
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--b2-ink-3);
}
.trame-in-content .trame-rail-collapse .trc-toggle {
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  border: 1px solid var(--b2-line);
  border-radius: 6px;
  background: #fff;
  color: var(--b2-ink-2);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* Collapsed → shrink to just the header pill. */
/* Collapsed → fold UP into the top header bar (keep the panel width; only the
 * body collapses), rather than shrinking into a corner pill. */
.trame-in-content .trame-file-list.is-collapsed {
  max-height: none !important;
}
.trame-in-content .trame-file-list.is-collapsed > *:not(.trame-rail-collapse) {
  display: none !important;
}
.trame-in-content .trame-file-list.is-collapsed .trame-rail-collapse {
  border-bottom: none;
}

/* Align the control rows: uniform label width + side padding so the Field /
 * Color / Time / Slice selects all share one left edge. */
.trame-in-content .trame-field-controls,
.trame-in-content #trameTimestepControls {
  padding: 10px 12px !important;
}
/* Tight label column for the top rows: short labels (Time / Field / Color)
 * sit close to their control instead of across a wide gap. */
.trame-in-content .trame-field-controls label,
.trame-in-content #trameTimestepControls label {
  min-width: 38px !important;
  flex: 0 0 38px !important;
}
/* Slice-section labels (Direction / Position / Opacity) are natural-width and
 * flush-left; their controls fill to the shared right edge (see below). */
.trame-in-content .slice-label {
  min-width: 0 !important;
  flex: 0 0 auto !important;
  white-space: nowrap !important;
}
/* Let the selects shrink instead of widening to fit a long field/option name
 * (e.g. PVD cases with long field labels) — a flex <select> defaults to
 * min-width:auto (= widest option), which overflows the row and breaks
 * alignment. min-width:0 lets it shrink; the option text just truncates. */
.trame-in-content .trame-field-controls select,
.trame-in-content #trameTimestepControls select {
  min-width: 0 !important;
  max-width: 100% !important;
  /* Shrink the option text + side padding so "-- Select Field --" (dashes kept)
   * fits without narrowing the aligned 64px label or clipping "Direction". */
  font-size: 11px !important;
  padding: 4px 6px !important;
}

/* ============================================================================
 * Range inputs (colormap min/max) — two-row layout so full numeric values fit.
 *   Row 1: "Range:" label + rescale button (left-aligned, compact).
 *   Row 2: Min / Max inputs expand to fill the rail; mono numbers, right
 *   aligned, clear focus ring.
 * ========================================================================== */
.trame-field-controls .trame-range-row {
  display: flex !important;
  align-items: center !important;
  gap: 8px !important;
  margin-top: 10px !important;
}
.trame-field-controls .trame-range-label {
  font-family: var(--f-sans) !important;
  font-size: 11px !important;
  font-weight: 500 !important;
  letter-spacing: 0.04em !important;
  text-transform: uppercase !important;
  color: var(--b2-ink-3) !important;
  min-width: 40px !important;
}
/* Rescale button — text + icon, fills the remainder of row 1 so it reads as a
 * first-class action (ParaView "Rescale" style), not a stranded 28 px icon.   */
.trame-field-controls .trame-rescale-btn {
  flex: 1 1 auto !important;
  height: 26px !important;
  padding: 0 12px !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 5px !important;
  background-color: var(--b2-surface) !important;
  color: var(--b2-ink-2) !important;
  font-family: var(--f-sans) !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  letter-spacing: -0.005em !important;
  line-height: 1 !important;
  cursor: pointer !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 6px !important;
  transition: background-color 120ms ease-out, border-color 120ms ease-out, color 120ms ease-out, box-shadow 120ms ease-out !important;
}
.trame-field-controls .trame-rescale-btn:hover {
  background-color: var(--b2-sunken) !important;
  border-color: var(--b2-line-2) !important;
  color: var(--b2-ink) !important;
}
.trame-field-controls .trame-rescale-btn:active {
  background-color: var(--b2-raised) !important;
  transform: translateY(0.5px) !important;
}
.trame-field-controls .trame-rescale-btn:focus-visible {
  outline: none !important;
  border-color: var(--b2-acc) !important;
  box-shadow: 0 0 0 2px var(--b2-acc-focus) !important;
}
.trame-field-controls .trame-rescale-icon {
  width: 20px !important;
  height: 10px !important;
  fill: none !important;
  stroke: currentColor !important;
  stroke-width: 1 !important;
  stroke-linecap: round !important;
  stroke-linejoin: round !important;
  flex: 0 0 20px !important;
  display: inline-block !important;
}
.trame-field-controls .trame-rescale-label {
  font-family: var(--f-sans) !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  color: inherit !important;
}
.trame-field-controls .trame-range-inputs {
  display: flex !important;
  align-items: center !important;
  gap: 6px !important;
  margin-top: 6px !important;
}
.trame-field-controls .trame-range-input {
  flex: 1 1 0 !important;
  min-width: 0 !important;
  padding: 4px 6px !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 4px !important;
  font-family: var(--f-mono) !important;
  font-size: 12px !important;
  background-color: var(--b2-surface) !important;
  color: var(--b2-ink) !important;
  text-align: right !important;
  -moz-appearance: textfield !important;
  appearance: textfield !important;
}
.trame-field-controls .trame-range-input::-webkit-outer-spin-button,
.trame-field-controls .trame-range-input::-webkit-inner-spin-button {
  -webkit-appearance: none !important;
  margin: 0 !important;
}
.trame-field-controls .trame-range-input:focus {
  outline: none !important;
  border-color: var(--b2-acc) !important;
  box-shadow: 0 0 0 2px var(--b2-acc-focus) !important;
}
.trame-field-controls .trame-range-sep {
  flex: 0 0 auto !important;
  font-family: var(--f-mono) !important;
  font-size: 12px !important;
  color: var(--b2-ink-4) !important;
  padding: 0 2px !important;
}

/* ---------------------------------------------------------------- Files tree typography */
.file-tree {
  font-family: var(--f-sans) !important;
}
.file-tree-item {
  padding: 5px 10px !important;
  margin: 1px 6px !important;
  border-radius: 5px !important;
  font-size: 13px !important;
  color: var(--b2-ink-2) !important;
  line-height: 1.5 !important;
  cursor: pointer !important;
  transition: background 120ms ease-out, color 120ms ease-out !important;
  gap: 6px !important;
}
.file-tree-item:hover {
  background: var(--b2-sunken) !important;
  color: var(--b2-ink) !important;
}
.file-tree-item.active,
.file-tree-item.selected {
  background: var(--b2-user-bg) !important;
  color: var(--b2-ink) !important;
  font-weight: 500 !important;
}
.file-tree-item.directory {
  color: var(--b2-ink) !important;
  font-weight: 500 !important;
}
.file-tree-toggle {
  color: var(--b2-ink-4) !important;
  transition: transform 120ms ease-out, color 120ms ease-out !important;
}
.file-tree-item:hover .file-tree-toggle {
  color: var(--b2-ink-2) !important;
}
/* Non-directory file-tree items (files) — mono face.                        */
.file-tree-item:not(.directory):not(.trame-file-item) {
  font-family: var(--f-mono) !important;
  font-size: 13px !important;
  color: var(--b2-ink-2) !important;
  letter-spacing: -0.005em !important;
}
/* Log files — distinct color only; the amber left rule was removed.         */
.file-tree .file-tree-item.log-file {
  color: var(--b2-ink-2) !important;
}

/* ---------------------------------------------------------------- Files content area */
.file-content-header {
  padding: 14px 20px !important;
  background: var(--b2-surface) !important;
  border-bottom: 1px solid var(--b2-line) !important;
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
  gap: 12px !important;
}
.file-header-main {
  font-family: var(--f-sans) !important;
  font-size: 14px !important;
  font-weight: 500 !important;
  letter-spacing: -0.01em !important;
  color: var(--b2-ink) !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  white-space: nowrap !important;
}
.file-header-refresh-btn {
  width: 28px !important;
  height: 28px !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 6px !important;
  background: var(--b2-surface) !important;
  color: var(--b2-ink-3) !important;
  font-size: 14px !important;
  cursor: pointer !important;
  transition: all 120ms ease-out !important;
}
.file-header-refresh-btn:not(:disabled):hover {
  background: var(--b2-acc-soft) !important;
  border-color: var(--b2-acc) !important;
  color: var(--b2-acc-ink) !important;
  transform: rotate(45deg) !important;
}

/* ============================================================================
 * ROUND 5 — File-tree glyph system
 * ----------------------------------------------------------------------------
 *   Goal: replace the cartoon emoji (📁 📄) with thin-stroke monochrome
 *   glyphs that inherit the ink tokens. The editorial voice wants crisp,
 *   minimal marks — the emoji were the single loudest visual in this panel.
 *
 *   Technique: hide the emoji in `.file-icon` with font-size:0 and draw our
 *   own glyph into `.file-icon::before` via CSS mask-image + inline SVG.
 *   mask-image lets us set color via `background-color` so the glyph
 *   follows the theme tokens (ink-3 for dirs, ink-4 for files, amber for
 *   log files).
 * ========================================================================== */

/* Hide the emoji but keep the icon box for layout alignment.                */
.file-tree-item .file-icon {
  font-size: 0 !important;
  line-height: 0 !important;
  width: 14px !important;
  height: 14px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  color: var(--b2-ink-4) !important;
  flex: 0 0 14px !important;
}

/* Folder glyph — simple two-part folder outline.                            */
.file-tree-item.directory .file-icon::before {
  content: "" !important;
  display: block !important;
  width: 12px !important;
  height: 10px !important;
  background-color: var(--b2-ink-3) !important;
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 10' fill='none' stroke='black' stroke-width='1.1' stroke-linejoin='round'><path d='M1 2.5V8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H6L5 2H2a1 1 0 0 0-1 .5z'/></svg>") !important;
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 10' fill='none' stroke='black' stroke-width='1.1' stroke-linejoin='round'><path d='M1 2.5V8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H6L5 2H2a1 1 0 0 0-1 .5z'/></svg>") !important;
  -webkit-mask-repeat: no-repeat !important;
          mask-repeat: no-repeat !important;
  -webkit-mask-position: center !important;
          mask-position: center !important;
  -webkit-mask-size: contain !important;
          mask-size: contain !important;
}

/* File glyph — simple doc with folded corner.                               */
.file-tree-item:not(.directory) .file-icon::before {
  content: "" !important;
  display: block !important;
  width: 10px !important;
  height: 12px !important;
  background-color: var(--b2-ink-4) !important;
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 12' fill='none' stroke='black' stroke-width='1' stroke-linejoin='round'><path d='M2 .5h4.5L9 3v8a.5.5 0 0 1-.5.5h-7A.5.5 0 0 1 1 11V1a.5.5 0 0 1 .5-.5z'/><path d='M6.5 .5v2.5L9 3'/></svg>") !important;
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 12' fill='none' stroke='black' stroke-width='1' stroke-linejoin='round'><path d='M2 .5h4.5L9 3v8a.5.5 0 0 1-.5.5h-7A.5.5 0 0 1 1 11V1a.5.5 0 0 1 .5-.5z'/><path d='M6.5 .5v2.5L9 3'/></svg>") !important;
  -webkit-mask-repeat: no-repeat !important;
          mask-repeat: no-repeat !important;
  -webkit-mask-position: center !important;
          mask-position: center !important;
  -webkit-mask-size: contain !important;
          mask-size: contain !important;
}

/* Hover / active darkens the glyph.                                         */
.file-tree-item:hover .file-icon::before                              { background-color: var(--b2-ink-2) !important; }
.file-tree-item.active .file-icon::before,
.file-tree-item.selected .file-icon::before                            { background-color: var(--b2-ink) !important; }

/* Toggle chevron — crisp CSS arrow (hide the Unicode glyph).                */
.file-tree-toggle {
  font-size: 0 !important;
  line-height: 0 !important;
  width: 14px !important;
  height: 14px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  color: var(--b2-ink-4) !important;
  flex: 0 0 14px !important;
  transition: transform 160ms ease-out, color 160ms ease-out !important;
}
.file-tree-toggle::before {
  content: "" !important;
  display: block !important;
  width: 0 !important;
  height: 0 !important;
  border-left: 4px solid currentColor !important;
  border-top: 3px solid transparent !important;
  border-bottom: 3px solid transparent !important;
}
.file-tree-toggle.expanded {
  transform: rotate(90deg) !important;
}
.file-tree-item:hover .file-tree-toggle {
  color: var(--b2-ink-2) !important;
}

/* Tree guide-lines — a whisper of vertical structure per nesting level.
 * Aligned to the parent chevron's center column (3 px into child container:
 * chevron center = 6px row margin + 6px row padding + 8px half-toggle = 20px,
 * minus the 16px .file-tree-children indent). */
.file-tree-children {
  position: relative !important;
}
.file-tree-children::before {
  content: "" !important;
  position: absolute !important;
  top: 2px !important;
  bottom: 2px !important;
  left: 3px !important;
  width: 1px !important;
  background: var(--b2-line) !important;
  opacity: 0.55 !important;
  pointer-events: none !important;
}
/* File glyph — slightly stronger tone so files don't fade on white bg.      */
.file-tree-item:not(.directory) .file-icon::before {
  background-color: var(--b2-ink-3) !important;
}

/* Item rhythm — slightly tighter, the glyph system lets us breathe easier.
 * Left padding 6px (not 10): with the 6px row margin the first content pixel
 * sits 12px off the panel edge (user call 2026-08-09). */
.file-tree .file-tree-item {
  padding: 4px 10px 4px 6px !important;
  min-height: 24px !important;
}

/* Root case directory — long case_id names get to wrap to two lines so the
 * full identifier is legible instead of ellipsed. Children stay single-line. */
.file-tree > .file-tree-item.directory:first-child {
  align-items: flex-start !important;
  padding-top: 6px !important;
  padding-bottom: 6px !important;
  min-height: auto !important;
}
.file-tree > .file-tree-item.directory:first-child .file-tree-toggle,
.file-tree > .file-tree-item.directory:first-child .file-icon {
  margin-top: 2px !important;
}
.file-tree > .file-tree-item.directory:first-child .file-name {
  white-space: normal !important;
  word-break: break-all !important;
  overflow: visible !important;
  text-overflow: clip !important;
  line-height: 1.3 !important;
  font-size: 11.5px !important;
}

/* ============================================================================
 * ROUND 6 — Rail form controls blend in
 * ----------------------------------------------------------------------------
 *   The Time / Field / Color / Range / Boundary sections had inline-styled
 *   controls with cold greys (#f8f9fa bg, #ccc border, #666 label ink) that
 *   stood out against the warm B² Light shell. Unify them:
 *
 *   · Section background → transparent (blends into the rail)
 *   · Hairline separators → --b2-line (#E5E7EB)
 *   · All selects / inputs / buttons → 6 px radius, hairline border, mono text
 *   · All labels → mono-uppercase 10 px, ink-4, tracked for editorial voice
 * ========================================================================== */

/* Section containers — unified hairline at the TOP of each section.
 * Using only border-top (not bottom) eliminates the double-line problem at
 * boundaries where one section's bottom-border met the next's top-border.  */
#trameTimestepControls,
.trame-field-controls,
#boundaryVisibilitySection,
.trame-file-list > .slice-control-panel,
.trame-file-list > .trame-file-tree {
  background: transparent !important;
  border-bottom: 0 !important;
  border-top: 1px solid var(--b2-line) !important;
  padding: 12px 14px !important;
}
/* Neutralize Cross-Section's previous border-top if set elsewhere.          */
.trame-file-list > .slice-control-panel {
  padding: 0 !important;  /* panel has its own internal padding; keep that  */
}
/* File tree (patches / VTU files list) — hairline above, tighter padding.   */
.trame-file-list > .trame-file-tree {
  padding: 8px 0 10px !important;
}
/* The section HEADER itself lives inside its container; it carries its own
 * divider via ::before. Remove any redundant divider on the header so only
 * the section container's top border shows.                                 */
.trame-file-list .trame-file-list-header::before {
  display: none !important;
}
/* The very first visible section gets no divider line.                      */
.trame-file-list > #trameCaseSection:first-child ~ *:first-of-type,
.trame-file-list > *:first-child {
  border-top: 0 !important;
}

/* Labels (Time: / Field: / Color: / Range:) — editorial mono caps.           */
#trameTimestepControls label,
.trame-field-controls label,
#boundaryVisibilitySection label,
.trame-file-list .trame-top-panel label,
.trame-file-list .trame-vtu-panel label {
  font-family: var(--f-mono) !important;
  font-size: 10px !important;
  font-weight: 500 !important;
  letter-spacing: 0.12em !important;
  text-transform: uppercase !important;
  color: var(--b2-ink-4) !important;
  min-width: 44px !important;
}

/* All selects & inputs in the rail — unified 6 px form chrome.               */
.trame-file-list select,
.trame-file-list input[type="number"],
.trame-file-list input[type="text"],
#trameTimestepSelector,
#trameFieldSelector,
#trameRangeMin,
#trameRangeMax {
  padding: 5px 8px !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 6px !important;
  background: var(--b2-surface) !important;
  color: var(--b2-ink) !important;
  font-family: var(--f-mono) !important;
  font-size: 11px !important;
  font-variant-numeric: tabular-nums !important;
  transition: border-color 120ms ease-out, box-shadow 120ms ease-out !important;
}
.trame-file-list select:focus,
.trame-file-list input:focus {
  outline: none !important;
  border-color: var(--b2-acc) !important;
  box-shadow: 0 0 0 3px var(--b2-acc-soft) !important;
}
.trame-file-list select:hover:not(:focus),
.trame-file-list input:hover:not(:focus) {
  border-color: var(--b2-ink-4) !important;
}

/* Time selector — plain chevron, no colormap swatch.                         */
#trameTimestepSelector,
#trameFieldSelector {
  appearance: none !important;
  -webkit-appearance: none !important;
  padding-right: 24px !important;
  background:
    linear-gradient(45deg, transparent 50%, var(--b2-ink-3) 50%) right 10px top 50% / 4px 4px no-repeat,
    linear-gradient(-45deg, transparent 50%, var(--b2-ink-3) 50%) right 6px top 50% / 4px 4px no-repeat,
    var(--b2-surface) !important;
}

/* Rescale button — now a text+icon button that fills the row past the
 * "Range:" label. First-class action, not a stranded 28 px icon.             */
#trameRescaleBtn {
  flex: 1 1 auto !important;
  width: auto !important;
  min-width: 0 !important;
  height: 26px !important;
  padding: 0 12px !important;
  gap: 6px !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 5px !important;
  background: var(--b2-surface) !important;
  color: var(--b2-ink-2) !important;
  font-family: var(--f-sans) !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  letter-spacing: -0.005em !important;
  line-height: 1 !important;
  cursor: pointer !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  transition: background-color 120ms ease-out, border-color 120ms ease-out, color 120ms ease-out, box-shadow 120ms ease-out !important;
}
#trameRescaleBtn:hover {
  background: var(--b2-sunken) !important;
  border-color: var(--b2-line-2) !important;
  color: var(--b2-ink) !important;
}
#trameRescaleBtn:active {
  background: var(--b2-raised) !important;
}
#trameRescaleBtn:focus-visible {
  outline: none !important;
  border-color: var(--b2-acc) !important;
  box-shadow: 0 0 0 2px var(--b2-acc-focus) !important;
}

/* Range "—" separator between Min and Max.                                   */
#trameRangeMin + span,
.trame-file-list .range-separator,
.trame-field-controls span:where([style*="color"]) {
  font-family: var(--f-mono) !important;
  font-size: 11px !important;
  color: var(--b2-ink-4) !important;
}

/* Range inputs — flex-share the remaining row width, min so they shrink.    */
#trameRangeMin,
#trameRangeMax {
  flex: 1 1 0 !important;
  width: auto !important;
  min-width: 0 !important;
  padding: 4px 6px !important;
}

/* Row rhythm inside sections — consistent vertical space.                    */
.trame-field-controls > div,
#trameTimestepControls > div {
  gap: 8px !important;
}

/* Playback deck — re-point the --pb-* tokens to B² Light: quiet gray play
 * button (#DCE1E8: between --b2-line and --b2-line-2 — anything lighter
 * disappears against the #F3F4F6 sunken control strip the deck sits on),
 * progress fill + focus carry the accent, cached-frames layer one hairline
 * step darker than the track. Light button ⇒ hover darkens, not brightens. */
#tramePlaybackBar {
  --pb-play-bg: #DCE1E8;
  --pb-play-fg: var(--b2-ink);
  --pb-play-hover: brightness(0.94);
  --pb-step-fg: var(--b2-ink-3);
  --pb-step-fg-hover: var(--b2-ink);
  --pb-step-line: var(--b2-line);
  --pb-step-line-hover: var(--b2-line-2);
  --pb-hover-bg: var(--b2-sunken);
  --pb-frames-fg: var(--b2-ink);
  --pb-dim-fg: var(--b2-ink-4);
  --pb-track-bg: var(--b2-line);
  --pb-cached-bg: var(--b2-line-2);
  --pb-fill-bg: var(--b2-acc);
  --pb-knob-bg: var(--b2-surface);
  --pb-knob-ring: rgba(17, 18, 22, 0.22);
  --pb-pulse: rgba(42, 120, 214, 0.45);
}
/* Animation-export popover rides the same palette. */
#trameExportPop {
  --xp-surface: var(--b2-surface);
  --xp-line: var(--b2-line-2);
  --xp-ink: var(--b2-ink);
  --xp-muted: var(--b2-ink-3);
  --xp-dim: var(--b2-ink-4);
  --xp-sel-bg: var(--b2-ink);
  --xp-sel-fg: #FFFFFF;
  --xp-acc: var(--b2-acc);
  --xp-track: var(--b2-line);
}
.trame-field-controls > div + div {
  margin-top: 10px !important;
}

/* Hide the floating case-info card on the viewer.                           */
.vtk-case-card,
#vtkCaseCard {
  display: none !important;
}

/* Colormap dropdown — match the warm rail shell (#FAFAF9) instead of pure
 * white, so the control blends with its surroundings. The rainbow swatch
 * stays on top; only the "after-swatch" fill changes.                       */
/* Colormap selector — plain dropdown, no rainbow swatch (deliberately quiet) */
#trameColormapSelector {
  padding: 5px 24px 5px 10px !important;
  background:
    linear-gradient(45deg, transparent 50%, var(--b2-ink-3) 50%) right 10px top 50% / 4px 4px no-repeat,
    linear-gradient(-45deg, transparent 50%, var(--b2-ink-3) 50%) right 6px top 50% / 4px 4px no-repeat,
    var(--b2-bg) !important;
  border-color: var(--b2-line) !important;
}

/* ============================================================================
 * highlight.js — B² token palette for Files-tab code preview.
 * Syntax colours come from existing theme tokens only (no new hues):
 *   keyword   → --b2-acc           (blue  #2A78D6)
 *   string    → --b2-ok            (green #0E9F6E)
 *   number    → --b2-warn          (amber-brown #B54708)
 *   comment   → --b2-ink-4         (muted grey)
 *   function  → --b2-user-code-fg  (amber #B55B00)
 *   constant  → --b2-err           (red #DC2626)
 *   type      → --b2-acc-ink       (deep blue #1E5AA8)
 * ========================================================================== */

.file-content-body pre.file-content-code {
  background: transparent !important;
  color: var(--b2-ink) !important;
  font-family: var(--f-mono) !important;
  font-size: 13px !important;
  line-height: 1.55 !important;
  padding: 16px 18px !important;
  margin: 0 !important;
  overflow: auto !important;
}
.file-content-body code.hljs,
.file-content-body pre code {
  background: transparent !important;
  color: var(--b2-ink) !important;
  font-family: var(--f-mono) !important;
  font-size: 13px !important;
  line-height: 1.55 !important;
  padding: 0 !important;
}
/* Keywords — control flow, declarations */
.hljs-keyword,
.hljs-selector-tag,
.hljs-doctag {
  color: var(--b2-acc) !important;
  font-weight: 500 !important;
}
/* Strings + regex */
.hljs-string,
.hljs-regexp,
.hljs-symbol,
.hljs-template-tag,
.hljs-template-variable {
  color: var(--b2-ok) !important;
}
/* Numbers + literals (true/false/null) */
.hljs-number,
.hljs-literal {
  color: var(--b2-warn) !important;
}
/* Comments */
.hljs-comment,
.hljs-quote {
  color: var(--b2-ink-4) !important;
  font-style: italic !important;
}
/* Functions / titles / class names */
.hljs-title,
.hljs-title.class_,
.hljs-title.function_,
.hljs-function .hljs-title,
.hljs-name {
  color: var(--b2-user-code-fg) !important;
  font-weight: 500 !important;
}
/* Types / built-ins */
.hljs-type,
.hljs-built_in,
.hljs-class .hljs-title {
  color: var(--b2-acc-ink) !important;
}
/* Variables / properties / attributes */
.hljs-variable,
.hljs-params,
.hljs-property,
.hljs-attribute {
  color: var(--b2-ink) !important;
}
/* Preprocessor / meta / tags */
.hljs-meta,
.hljs-meta .hljs-keyword,
.hljs-tag,
.hljs-selector-id,
.hljs-selector-class {
  color: var(--b2-ink-3) !important;
}
/* Operators / punctuation */
.hljs-operator,
.hljs-punctuation {
  color: var(--b2-ink-2) !important;
}
/* Destructive / error accents */
.hljs-deletion,
.hljs-bullet {
  color: var(--b2-err) !important;
}
/* Markdown emphasis */
.hljs-emphasis  { font-style: italic !important; }
.hljs-strong    { font-weight: 600 !important; }


/* ============================================================================
 * Attach button + upload menu — align with theme typography / icon system.
 * ========================================================================== */
.attach-btn {
  width: 28px !important;
  height: 28px !important;
  padding: 0 !important;
  border: 0 !important;
  background: transparent !important;
  color: var(--b2-ink-3) !important;
  border-radius: 6px !important;
  cursor: pointer !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  transition: color 120ms ease-out, background 120ms ease-out !important;
}
.attach-btn:hover {
  color: var(--b2-ink) !important;
  background: var(--b2-sunken) !important;
}
.attach-btn svg {
  width: 16px !important;
  height: 16px !important;
  fill: none !important;
}

.upload-menu {
  background: var(--b2-surface) !important;
  border: 1px solid var(--b2-line) !important;
  border-radius: 8px !important;
  box-shadow: 0 6px 20px -8px rgba(17,18,22,0.18), 0 2px 4px rgba(17,18,22,0.04) !important;
  padding: 4px !important;
  min-width: 180px !important;
  margin-bottom: 8px !important;
  font-family: var(--f-sans) !important;
}
.upload-menu button {
  display: flex !important;
  align-items: center !important;
  gap: 10px !important;
  width: 100% !important;
  padding: 8px 10px !important;
  border: 0 !important;
  background: transparent !important;
  color: var(--b2-ink-2) !important;
  font-family: var(--f-sans) !important;
  font-size: 13px !important;
  font-weight: 500 !important;
  letter-spacing: -0.005em !important;
  text-align: left !important;
  white-space: nowrap !important;
  border-radius: 5px !important;
  cursor: pointer !important;
  transition: background 120ms ease-out, color 120ms ease-out !important;
}
.upload-menu button:hover {
  background: var(--b2-sunken) !important;
  color: var(--b2-ink) !important;
}
.upload-menu button svg {
  width: 16px !important;
  height: 16px !important;
  color: var(--b2-ink-4) !important;
  flex: 0 0 16px !important;
  fill: none !important;
  transition: color 120ms ease-out !important;
}
.upload-menu button:hover svg {
  color: var(--b2-acc) !important;
}

/* ============================================================================
 * Sidebar typography — per user: labels 11 px, items 14 px / 19 px leading.
 * ========================================================================== */
.time-group-title,
.conversations-section-header,
.conv-section-header,
.time-section-header,
.conversations-time-group {
  font-size: 11px !important;
}
.conversation-item {
  font-size: 12px !important;
  line-height: 19px !important;
  min-height: 30px !important;
}
.conversation-item .conversation-title {
  font-size: 12px !important;
  line-height: 19px !important;
}

/* ============================================================================
 * File-type icons (mixed) — Line outlines for documents/geometry/images,
 * filled Duotone for the 3D result data (stl, vtu/vtk/vtp, pvd) where solid
 * shapes read better. file-browser.js tags each row `ext-<extension>`;
 * folders + `log-file` get their own marks. Overrides the monochrome mask
 * above via background-image (placed AFTER it to win at equal specificity).
 * ========================================================================== */
.file-tree-item.ext-pdf .file-icon::before,
.file-tree-item.ext-docx .file-icon::before,
.file-tree-item.ext-xlsx .file-icon::before,
.file-tree-item.ext-pptx .file-icon::before,
.file-tree-item.ext-csv .file-icon::before,
.file-tree-item.ext-dat .file-icon::before,
.file-tree-item.ext-py .file-icon::before,
.file-tree-item.ext-json .file-icon::before,
.file-tree-item.ext-yaml .file-icon::before,
.file-tree-item.ext-yml .file-icon::before,
.file-tree-item.ext-step .file-icon::before,
.file-tree-item.ext-stp .file-icon::before,
.file-tree-item.ext-stl .file-icon::before,
.file-tree-item.ext-obj .file-icon::before,
.file-tree-item.ext-pvd .file-icon::before,
.file-tree-item.ext-vtm .file-icon::before,
.file-tree-item.ext-vtu .file-icon::before,
.file-tree-item.ext-vtk .file-icon::before,
.file-tree-item.ext-vtp .file-icon::before,
.file-tree-item.ext-png .file-icon::before,
.file-tree-item.ext-jpg .file-icon::before,
.file-tree-item.ext-jpeg .file-icon::before,
.file-tree-item.ext-gif .file-icon::before,
.file-tree-item.ext-svg .file-icon::before,
.file-tree-item.ext-webp .file-icon::before,
.file-tree-item.ext-bmp .file-icon::before,
.file-tree-item.ext-ico .file-icon::before,
.file-tree-item.ext-tif .file-icon::before,
.file-tree-item.ext-tiff .file-icon::before,
.file-tree-item.ext-zip .file-icon::before,
.file-tree-item.ext-gz .file-icon::before,
.file-tree-item.ext-tar .file-icon::before,
.file-tree-item.ext-tgz .file-icon::before,
.file-tree-item.ext-7z .file-icon::before,
.file-tree-item.ext-rar .file-icon::before,
.file-tree-item.ext-bz2 .file-icon::before,
.file-tree-item.ext-xz .file-icon::before,
.file-tree-item.ext-zst .file-icon::before,
.file-tree-item.log-file .file-icon::before,
.file-tree-item.directory .file-icon::before {
  -webkit-mask: none !important; mask: none !important;
  background-color: transparent !important;
  background-repeat: no-repeat !important; background-position: center !important;
  background-size: contain !important; width: 14px !important; height: 14px !important;
}
.file-tree-item.ext-pdf .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><g fill='none' stroke='%23DC2626' stroke-width='1.7' stroke-linejoin='round'><path d='M6.5 2.5h6.5l5 5v12a1.5 1.5 0 0 1-1.5 1.5h-10A1.5 1.5 0 0 1 5 19.5V4A1.5 1.5 0 0 1 6.5 2.5z'/><path d='M13 2.5v5h5'/></g><text x='11.3' y='17.6' font-family='Arial' font-size='4.6' font-weight='700' fill='%23DC2626' text-anchor='middle'>PDF</text></svg>") !important; }
.file-tree-item.ext-docx .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><g fill='none' stroke='%232B579A' stroke-width='1.7' stroke-linejoin='round'><path d='M6.5 2.5h6.5l5 5v12a1.5 1.5 0 0 1-1.5 1.5h-10A1.5 1.5 0 0 1 5 19.5V4A1.5 1.5 0 0 1 6.5 2.5z'/><path d='M13 2.5v5h5'/></g><text x='11.3' y='18' font-family='Arial' font-size='7' font-weight='700' fill='%232B579A' text-anchor='middle'>W</text></svg>") !important; }
.file-tree-item.ext-xlsx .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><g fill='none' stroke='%2315803D' stroke-width='1.7' stroke-linejoin='round'><path d='M6.5 2.5h6.5l5 5v12a1.5 1.5 0 0 1-1.5 1.5h-10A1.5 1.5 0 0 1 5 19.5V4A1.5 1.5 0 0 1 6.5 2.5z'/><path d='M13 2.5v5h5'/></g><text x='11.3' y='18' font-family='Arial' font-size='7' font-weight='700' fill='%2315803D' text-anchor='middle'>X</text></svg>") !important; }
.file-tree-item.ext-pptx .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><g fill='none' stroke='%23C2410C' stroke-width='1.7' stroke-linejoin='round'><path d='M6.5 2.5h6.5l5 5v12a1.5 1.5 0 0 1-1.5 1.5h-10A1.5 1.5 0 0 1 5 19.5V4A1.5 1.5 0 0 1 6.5 2.5z'/><path d='M13 2.5v5h5'/></g><text x='11.3' y='18' font-family='Arial' font-size='7' font-weight='700' fill='%23C2410C' text-anchor='middle'>P</text></svg>") !important; }
.file-tree-item.ext-csv .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23059669' stroke-width='1.6'><rect x='3.5' y='4.5' width='17' height='15' rx='1.5'/><path d='M3.5 9.5h17M3.5 14.5h17M9.5 4.5v15M15 4.5v15'/></svg>") !important; }
.file-tree-item.ext-dat .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23059669' stroke-width='1.6'><rect x='3.5' y='4.5' width='17' height='15' rx='1.5'/><path d='M3.5 9.5h17M3.5 14.5h17M9.5 4.5v15M15 4.5v15'/></svg>") !important; }
.file-tree-item.ext-py .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 255'><path fill='%233776AB' d='M126.916.072c-64.832 0-60.784 28.115-60.784 28.115l.072 29.128h61.868v8.745H41.631S.145 61.355.145 126.77c0 65.417 36.21 63.097 36.21 63.097h21.61v-30.356s-1.165-36.21 35.632-36.21h61.362s34.475.557 34.475-33.319V33.97S231.247.072 126.916.072zM92.802 19.66a11.12 11.12 0 0 1 11.13 11.13 11.12 11.12 0 0 1-11.13 11.13 11.12 11.12 0 0 1-11.13-11.13 11.12 11.12 0 0 1 11.13-11.13z'/><path fill='%23FFD43B' d='M128.757 254.126c64.832 0 60.784-28.115 60.784-28.115l-.072-29.127H127.6v-8.745h86.441s41.486 4.705 41.486-60.711c0-65.416-36.21-63.096-36.21-63.096h-21.61v30.355s1.165 36.21-35.632 36.21h-61.362s-34.475-.557-34.475 33.32v56.013s-5.235 33.897 99.096 33.897zm34.114-19.586a11.12 11.12 0 0 1-11.13-11.13 11.12 11.12 0 0 1 11.13-11.131 11.12 11.12 0 0 1 11.13 11.13 11.12 11.12 0 0 1-11.13 11.13z'/></svg>") !important; }
.file-tree-item.ext-json .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23D97706' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M8 3C6 3 6 6 6 7.5S6 11 4 12c2 1 2 3.5 2 4.5S6 21 8 21'/><path d='M16 3c2 0 2 3 2 4.5S18 11 20 12c-2 1-2 3.5-2 4.5S18 21 16 21'/></svg>") !important; }
.file-tree-item.ext-yaml .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23D97706' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M8 3C6 3 6 6 6 7.5S6 11 4 12c2 1 2 3.5 2 4.5S6 21 8 21'/><path d='M16 3c2 0 2 3 2 4.5S18 11 20 12c-2 1-2 3.5-2 4.5S18 21 16 21'/></svg>") !important; }
.file-tree-item.ext-yml .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23D97706' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M8 3C6 3 6 6 6 7.5S6 11 4 12c2 1 2 3.5 2 4.5S6 21 8 21'/><path d='M16 3c2 0 2 3 2 4.5S18 11 20 12c-2 1-2 3.5-2 4.5S18 21 16 21'/></svg>") !important; }
.file-tree-item.ext-step .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2306B6D4' stroke-width='1.6' stroke-linejoin='round'><path d='M12 2.8 20.5 7.6v8.8L12 21.2 3.5 16.4V7.6z'/><path d='M3.5 7.6 12 12.4 20.5 7.6M12 12.4V21.2'/></svg>") !important; }
.file-tree-item.ext-stp .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2306B6D4' stroke-width='1.6' stroke-linejoin='round'><path d='M12 2.8 20.5 7.6v8.8L12 21.2 3.5 16.4V7.6z'/><path d='M3.5 7.6 12 12.4 20.5 7.6M12 12.4V21.2'/></svg>") !important; }
.file-tree-item.ext-png .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23DB2777' stroke-width='1.6' stroke-linejoin='round'><rect x='3.5' y='4.5' width='17' height='15' rx='2'/><circle cx='9' cy='9.5' r='1.7'/><path d='M20.5 16 14.5 10l-8 8' stroke-linecap='round'/></svg>") !important; }
.file-tree-item.ext-jpg .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23DB2777' stroke-width='1.6' stroke-linejoin='round'><rect x='3.5' y='4.5' width='17' height='15' rx='2'/><circle cx='9' cy='9.5' r='1.7'/><path d='M20.5 16 14.5 10l-8 8' stroke-linecap='round'/></svg>") !important; }
.file-tree-item.ext-jpeg .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23DB2777' stroke-width='1.6' stroke-linejoin='round'><rect x='3.5' y='4.5' width='17' height='15' rx='2'/><circle cx='9' cy='9.5' r='1.7'/><path d='M20.5 16 14.5 10l-8 8' stroke-linecap='round'/></svg>") !important; }
.file-tree-item.ext-gif .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23DB2777' stroke-width='1.6' stroke-linejoin='round'><rect x='3.5' y='4.5' width='17' height='15' rx='2'/><circle cx='9' cy='9.5' r='1.7'/><path d='M20.5 16 14.5 10l-8 8' stroke-linecap='round'/></svg>") !important; }
.file-tree-item.ext-svg .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23DB2777' stroke-width='1.6' stroke-linejoin='round'><rect x='3.5' y='4.5' width='17' height='15' rx='2'/><circle cx='9' cy='9.5' r='1.7'/><path d='M20.5 16 14.5 10l-8 8' stroke-linecap='round'/></svg>") !important; }
.file-tree-item.ext-webp .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23DB2777' stroke-width='1.6' stroke-linejoin='round'><rect x='3.5' y='4.5' width='17' height='15' rx='2'/><circle cx='9' cy='9.5' r='1.7'/><path d='M20.5 16 14.5 10l-8 8' stroke-linecap='round'/></svg>") !important; }
.file-tree-item.ext-bmp .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23DB2777' stroke-width='1.6' stroke-linejoin='round'><rect x='3.5' y='4.5' width='17' height='15' rx='2'/><circle cx='9' cy='9.5' r='1.7'/><path d='M20.5 16 14.5 10l-8 8' stroke-linecap='round'/></svg>") !important; }
.file-tree-item.ext-ico .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23DB2777' stroke-width='1.6' stroke-linejoin='round'><rect x='3.5' y='4.5' width='17' height='15' rx='2'/><circle cx='9' cy='9.5' r='1.7'/><path d='M20.5 16 14.5 10l-8 8' stroke-linecap='round'/></svg>") !important; }
.file-tree-item.ext-tif .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23DB2777' stroke-width='1.6' stroke-linejoin='round'><rect x='3.5' y='4.5' width='17' height='15' rx='2'/><circle cx='9' cy='9.5' r='1.7'/><path d='M20.5 16 14.5 10l-8 8' stroke-linecap='round'/></svg>") !important; }
.file-tree-item.ext-tiff .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23DB2777' stroke-width='1.6' stroke-linejoin='round'><rect x='3.5' y='4.5' width='17' height='15' rx='2'/><circle cx='9' cy='9.5' r='1.7'/><path d='M20.5 16 14.5 10l-8 8' stroke-linecap='round'/></svg>") !important; }
.file-tree-item.log-file .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><g fill='none' stroke='%2378716C' stroke-width='1.6' stroke-linejoin='round'><path d='M6.5 2.5h6.5l5 5v12a1.5 1.5 0 0 1-1.5 1.5h-10A1.5 1.5 0 0 1 5 19.5V4A1.5 1.5 0 0 1 6.5 2.5z'/><path d='M13 2.5v5h5'/></g><path stroke='%2378716C' stroke-width='1.3' stroke-linecap='round' d='M7.8 12.5h6M7.8 15.5h6M7.8 18.5h3.5'/></svg>") !important; }
.file-tree-item.directory .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23C99A43' stroke-width='1.7' stroke-linejoin='round'><path d='M3.5 7.5a1.5 1.5 0 0 1 1.5-1.5h3l2 2h8a1.5 1.5 0 0 1 1.5 1.5v8a1.5 1.5 0 0 1-1.5 1.5H5a1.5 1.5 0 0 1-1.5-1.5z'/></svg>") !important; width: 15px !important; height: 14px !important; }
/* document-templates category folder — card-index drawer, deeper amber, so
   corporate document templates read apart from parameter-template folders. */
.file-tree-item.directory.doc-category .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23A16207' stroke-width='1.7' stroke-linejoin='round'><rect x='3.5' y='5' width='17' height='14.5' rx='1.5'/><path d='M3.5 11h17'/><path d='M9.5 14.8h5' stroke-linecap='round'/><path d='M8 5V3.2h8V5' stroke-linecap='round'/></svg>") !important; width: 15px !important; height: 15px !important; }
.file-tree-item.ext-stl .file-icon::before,
.file-tree-item.ext-obj .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='%23DDD6FE' d='M12 2.5 21 7.5v9L12 21.5 3 16.5v-9z'/><path fill='%237C3AED' d='M12 2.5 21 7.5 12 12.5 3 7.5z'/></svg>") !important; }
.file-tree-item.ext-pvd .file-icon::before,
.file-tree-item.ext-vtm .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='%236EE7B7' d='M12 8.5 21.5 13.2 12 17.9 2.5 13.2z'/><path fill='%236EE7B7' d='M12 5.8 21.5 10.5 12 15.2 2.5 10.5z'/><path fill='%23059669' d='M12 3 21.5 7.7 12 12.4 2.5 7.7z'/></svg>") !important; }
.file-tree-item.ext-vtu .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='%23E2E5EA' d='M12 2.3 21 7.6 12 12.9 3 7.6z'/><path fill='%23E2E5EA' d='M3 7.6 12 12.9 12 21.7 3 16.4z'/><path fill='%239AA3B2' d='M21 7.6 12 12.9 12 21.7 21 16.4z'/></svg>") !important; }
.file-tree-item.ext-vtk .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='%23BFDBFE' d='M12 2.3 21 7.6 12 12.9 3 7.6z'/><path fill='%23BFDBFE' d='M3 7.6 12 12.9 12 21.7 3 16.4z'/><path fill='%232563EB' d='M21 7.6 12 12.9 12 21.7 21 16.4z'/></svg>") !important; }
.file-tree-item.ext-vtp .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='%2393C5FD' stroke='%232563EB' stroke-width='1' stroke-linejoin='round' d='M3.5 9.2 14.5 5 20.5 14.8 9.5 19z'/><path fill='none' stroke='%232563EB' stroke-width='.7' d='M3.5 9.2 20.5 14.8M14.5 5 9.5 19M9 12 15 9.9'/></svg>") !important; }
.file-tree-item.ext-zip .file-icon::before,
.file-tree-item.ext-gz .file-icon::before,
.file-tree-item.ext-tar .file-icon::before,
.file-tree-item.ext-tgz .file-icon::before,
.file-tree-item.ext-7z .file-icon::before,
.file-tree-item.ext-rar .file-icon::before,
.file-tree-item.ext-bz2 .file-icon::before,
.file-tree-item.ext-xz .file-icon::before,
.file-tree-item.ext-zst .file-icon::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='%23F4B63B' d='M3 7.2a1.8 1.8 0 0 1 1.8-1.8h3.4l2 2h8a1.8 1.8 0 0 1 1.8 1.8v8.6a1.8 1.8 0 0 1-1.8 1.8H4.8A1.8 1.8 0 0 1 3 17.8z'/><path fill='%23E7A52A' d='M3 7.2a1.8 1.8 0 0 1 1.8-1.8h3.4l2 2H3z'/><rect x='11' y='9.4' width='2' height='9.4' fill='%23C98A12'/><g stroke='%23fff' stroke-width='.7'><path d='M11 10.6h2M11 12.1h2M11 13.6h2M11 15.1h2'/></g><rect x='10.2' y='16.6' width='3.6' height='2.6' rx='.7' fill='%239A6A0C'/></svg>") !important; }

/* ============================================================================
 * Download status bar — pinned to the bottom of the Explorer (.file-tree-panel).
 * Shown while triggerDownload() fetches a file: "Preparing…" during the server's
 * packaging/TTFB wait, then a live "Downloading… N%" progress bar. VS-Code-like.
 * ========================================================================== */
.file-tree-panel { position: relative !important; }
.dl-status {
  position: absolute !important; left: 0 !important; right: 0 !important; bottom: 0 !important;
  display: flex !important; align-items: center !important; gap: 9px !important;
  padding: 8px 12px 9px !important;
  background: var(--b2-surface) !important;
  border-top: 1px solid var(--b2-line) !important;
  box-shadow: 0 -3px 10px rgba(17,18,22,0.05) !important;
  z-index: 5 !important;
}
.dl-status[hidden] { display: none !important; }
.dl-icon { width: 14px !important; height: 14px !important; flex: 0 0 14px !important; position: relative !important; }
.dl-icon.dl-spinner {
  border: 2px solid var(--b2-line-2) !important; border-top-color: var(--b2-acc) !important;
  border-radius: 50% !important; animation: dl-spin 0.7s linear infinite !important;
}
@keyframes dl-spin { to { transform: rotate(360deg); } }
.dl-text { flex: 1 1 auto !important; min-width: 0 !important; display: flex !important; flex-direction: column !important; line-height: 1.25 !important; }
.dl-name { color: var(--b2-ink) !important; font: 600 11px var(--f-mono) !important; white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; }
.dl-detail { color: var(--b2-ink-3) !important; font: 500 10.5px var(--f-sans) !important; font-variant-numeric: tabular-nums !important; }
.dl-bar { position: absolute !important; left: 0 !important; right: 0 !important; bottom: 0 !important; height: 2px !important; background: var(--b2-sunken) !important; overflow: hidden !important; }
.dl-bar-fill { height: 100% !important; width: 0 !important; background: var(--b2-acc) !important; transition: width 0.15s ease !important; }
.dl-status.indeterminate .dl-bar-fill { width: 35% !important; animation: dl-indet 1.1s ease-in-out infinite !important; }
@keyframes dl-indet { 0% { margin-left: -35%; } 100% { margin-left: 100%; } }
