/* =====================================================
   Curious AI - Global Styles (v6.0)
   Unified Dark Theme, ChatGPT-style alignment.
   - Straight vertical alignment for all chat messages
   - Code blocks confined within bubble boundaries
   - Compact sidebar (New chat button + history list)
   - Mobile responsive
   ===================================================== */

:root {
  --brand:        #1f2937;
  --brand-dark:   #0f172a;
  --brand-darker: #020617;
  --brand-accent: #111827;
  --brand-light:  #e5e7eb;
  --brand-soft:   #f3f4f6;
  --brand-soft-2: #f9fafb;
  --text-dark:    #0F172A;
  --text-muted:   #64748B;
  --border:       #E5E7EB;
  --border-soft:  #EEF2F6;
  --bg:           #FFFFFF;
  --bg-alt:       #F8FAFB;
  --sidebar-bg:   #f7f7f8;
  --user-bubble:  #ececec;
  --assistant-bubble: #ffffff;
  /* v19: SOFT LIGHT-GREY code blocks (true ChatGPT-style sheet, not black).
     A slightly cooler, very-light neutral grey — #f6f7f9 sheet with a
     marginally darker header strip, and a clear but soft border. */
  --code-bg:      #f6f7f9;
  --code-head-bg: #eceef2;
  --code-text:    #1f2937;
  --code-border:  #e1e4ea;
  --danger:       #dc2626;
  --warning:      #f59e0b;
  --success:      #16a34a;
}

/* Dark mode overrides */
body.dark-mode {
  --brand:        #e5e7eb;
  --brand-dark:   #f3f4f6;
  --brand-darker: #ffffff;
  --brand-accent: #ffffff;
  --brand-light:  #2a2b32;
  --brand-soft:   #202123;
  --brand-soft-2: #2a2b32;
  --text-dark:    #ECECEC;
  --text-muted:   #9ca3af;
  --border:       #2a2b32;
  --border-soft:  #2a2b32;
  --bg:           #1a1b1f;
  --bg-alt:       #15161a;
  --sidebar-bg:   #202123;
  --user-bubble:  #2f2f33;
  --assistant-bubble: #1a1b1f;
}

* { box-sizing: border-box; }

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  background: var(--bg);
  color: var(--text-dark);
  -webkit-font-smoothing: antialiased;
}

/* ===== Brand Buttons ===== */
.btn-brand {
  background: var(--brand);
  color: #fff !important;
  border: none;
  font-weight: 500;
  transition: all .2s;
}
.btn-brand:hover  { background: var(--brand-dark);  color: #fff; box-shadow: 0 4px 14px rgba(0,0,0,.15); }
.btn-brand:disabled { opacity:.7; cursor: progress; }

.btn-outline-brand {
  border: 1.5px solid var(--brand);
  color: var(--brand);
  background: transparent;
  font-weight: 500;
  transition: all .2s;
}
.btn-outline-brand:hover { background: var(--brand); color: #fff; }
.text-brand    { color: var(--brand) !important; }
.bg-brand      { background: var(--brand) !important; color: #fff; }
.bg-brand-soft { background: var(--brand-soft) !important; }

/* ===== Navbar ===== */
.navbar { box-shadow: 0 1px 0 rgba(0,0,0,.04); background: var(--bg) !important; }
.navbar-brand { font-weight: 700; }
.nav-link { color: var(--text-dark) !important; font-weight: 500; }
.nav-link:hover { color: var(--brand) !important; }

/* ===== Hero ===== */
.hero {
  padding: 100px 0 80px;
  background: linear-gradient(180deg, var(--brand-soft) 0%, var(--bg) 100%);
  text-align: center;
}
.hero h1 { font-size: 3.2rem; font-weight: 800; letter-spacing: -.02em; }
.hero h1 .accent { color: var(--brand); }
.hero p.lead { font-size: 1.2rem; color: var(--text-muted); max-width: 640px; margin: 0 auto; }

/* ===== Feature cards ===== */
.feature-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 28px;
  height: 100%;
  transition: all .2s;
}
.feature-card:hover { border-color: var(--brand); transform: translateY(-2px); box-shadow: 0 8px 24px rgba(0,0,0,.08); }
.feature-icon {
  width: 48px; height: 48px;
  border-radius: 12px;
  background: var(--brand-soft);
  color: var(--brand-dark);
  display: flex; align-items: center; justify-content: center;
  font-size: 1.4rem;
  margin-bottom: 16px;
}

/* ===== Pricing ===== */
.pricing-card {
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 36px 28px;
  background: var(--bg);
  height: 100%;
  display: flex; flex-direction: column;
  transition: all .2s;
  position: relative;
}
.pricing-card:hover { transform: translateY(-4px); box-shadow: 0 12px 32px rgba(0,0,0,.06); }
.pricing-card.featured {
  border: 2px solid var(--brand);
  box-shadow: 0 12px 40px rgba(0,0,0,.12);
  transform: scale(1.02);
}
.pricing-card .price { font-size: 2.8rem; font-weight: 800; color: var(--text-dark); }
.pricing-card .price small { font-size: 1rem; color: var(--text-muted); font-weight: 500; }
.pricing-card ul { list-style: none; padding: 0; margin: 24px 0; }
.pricing-card ul li { padding: 8px 0; color: var(--text-dark); }
.pricing-card ul li i { color: var(--brand); margin-right: 8px; }
.pricing-badge {
  position: absolute; top: -12px; right: 24px;
  background: var(--brand); color: #fff;
  padding: 4px 12px; border-radius: 20px;
  font-size: .75rem; font-weight: 600;
}

/* ===== Auth forms ===== */
.auth-wrap {
  min-height: calc(100vh - 80px);
  display: flex; align-items: center; justify-content: center;
  padding: 40px 16px;
  background: linear-gradient(180deg, var(--brand-soft) 0%, var(--bg) 100%);
}
.auth-card {
  background: var(--bg);
  border: 1px solid var(--border-soft);
  border-radius: 18px;
  padding: 40px 36px;
  width: 100%; max-width: 440px;
  box-shadow: 0 10px 30px rgba(0,0,0,.04);
}
.auth-card .auth-logo { display: flex; justify-content: center; margin-bottom: 16px; }
.input-icon-wrap { position: relative; }
.input-icon {
  position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
  color: var(--text-muted); pointer-events: none; font-size: 1rem;
}
.form-control { border-radius: 10px; padding: 10px 12px; background: var(--bg); color: var(--text-dark); border-color: var(--border); }
.form-control:focus,
.form-select:focus {
  border-color: var(--brand);
  box-shadow: 0 0 0 .2rem rgba(31,41,55,.15);
  background: var(--bg);
  color: var(--text-dark);
}
.btn-spinner { display: inline-flex; align-items: center; gap: 8px; }

/* =====================================================
   CHAT INTERFACE
   ===================================================== */
.chat-app {
  display: flex;
  height: 100vh;
  background: var(--bg);
  position: relative;
  overflow: hidden;
}

/* ----- Sidebar (more compact) ----- */
.chat-sidebar {
  width: 250px;
  background: var(--sidebar-bg);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  flex-shrink: 0;
  transition: width .25s ease, margin-left .25s ease;
  position: relative;
}
.chat-sidebar.collapsed {
  width: 0;
  margin-left: -1px;
  overflow: hidden;
}
.chat-sidebar.collapsed > * { opacity: 0; pointer-events: none; }

/* ===== Sidebar collapse / expand toggle ===== */
.sidebar-toggle-btn {
  position: absolute;
  top: 16px;
  left: 250px;
  transform: translateX(-50%);
  width: 28px; height: 28px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  z-index: 50;
  color: var(--text-dark);
  transition: left .28s cubic-bezier(.4,0,.2,1),
              transform .28s cubic-bezier(.4,0,.2,1),
              background .15s, box-shadow .15s, border-color .15s;
  box-shadow: 0 4px 14px rgba(15,23,42,.10), 0 1px 2px rgba(15,23,42,.06);
}
.sidebar-toggle-btn i { font-size: .95rem; transition: transform .25s ease; }
.sidebar-toggle-btn:hover {
  background: var(--brand-soft);
  border-color: var(--brand);
  color: var(--brand);
  box-shadow: 0 6px 18px rgba(15,23,42,.14), 0 1px 3px rgba(15,23,42,.08);
}
.sidebar-toggle-btn:active { transform: translateX(-50%) scale(.94); }
.chat-sidebar.collapsed ~ .sidebar-toggle-btn,
body:has(.chat-sidebar.collapsed) .sidebar-toggle-btn { left: 12px; transform: none; }
.chat-sidebar.collapsed ~ .sidebar-toggle-btn:active,
body:has(.chat-sidebar.collapsed) .sidebar-toggle-btn:active { transform: scale(.94); }
body.dark-mode .sidebar-toggle-btn {
  box-shadow: 0 4px 14px rgba(0,0,0,.45), 0 1px 2px rgba(0,0,0,.3);
}
body.dark-mode .sidebar-toggle-btn:hover {
  box-shadow: 0 6px 18px rgba(0,0,0,.55), 0 1px 3px rgba(0,0,0,.35);
}

.chat-sidebar .sidebar-header {
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 8px;
  font-size: .9rem;
}

/* COMPACT: smaller "+ New chat" button */
.chat-sidebar .new-chat-btn {
  margin: 8px 10px 8px;
  background: var(--brand);
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 7px 10px;
  min-height: 32px;
  font-size: .82rem;
  font-weight: 500;
  display: flex; align-items: center; justify-content: flex-start; gap: 6px;
  transition: background .15s, transform .15s, box-shadow .15s;
  width: calc(100% - 20px);
}
.chat-sidebar .new-chat-btn i { font-size: .82rem; }
.chat-sidebar .new-chat-btn:hover {
  background: var(--brand-dark);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(15, 23, 42, .12);
}

/* COMPACT: smaller history label & items */
.chat-sidebar .history-label {
  padding: 4px 14px 6px;
  font-size: .66rem;
  text-transform: uppercase;
  color: var(--text-dark);
  font-weight: 700;
  letter-spacing: .06em;
}
.chat-sidebar .history-list { flex: 1; overflow-y: auto; padding: 0 6px; }
.chat-sidebar .history-item {
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 10px;
  border-radius: 6px;
  color: var(--text-dark);
  text-decoration: none;
  font-size: .93rem;
  cursor: pointer;
  margin-bottom: 2px;
  transition: background .15s;
  line-height: 1.5;
  color: #1a1a2e;
}
.chat-sidebar .history-item .text-truncate { font-size: .93rem; color: #1a1a2e; }
.chat-sidebar .history-item:hover { background: var(--brand-light); color: var(--text-dark); }
.chat-sidebar .history-item.active { background: var(--brand-light); color: var(--text-dark); font-weight: 500; }
.chat-sidebar .history-item .del-btn {
  opacity: 0; transition: opacity .15s;
  background: transparent; border: none; color: var(--text-muted);
  font-size: .8rem; padding: 2px 4px;
}
.chat-sidebar .history-item:hover .del-btn { opacity: 1; }

/* Sidebar footer */
.chat-sidebar .sidebar-footer {
  border-top: 1px solid var(--border);
  padding: 8px 8px;
  font-size: .85rem;
  position: relative;
}
.user-menu-trigger {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 8px;
  border-radius: 8px;
  cursor: pointer;
  transition: background .15s;
  width: 100%;
  background: transparent;
  border: none;
  color: var(--text-dark);
  text-align: left;
}
.user-menu-trigger:hover { background: var(--brand-light); }
.user-avatar-circle {
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--brand);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-weight: 600;
  font-size: .8rem;
  flex-shrink: 0;
}
.user-menu-trigger .uname {
  flex: 1;
  font-weight: 500;
  font-size: .85rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-width: 0;
}
.user-menu-trigger .udots { color: var(--text-muted); font-size: .85rem; }

/* Popup user menu */
.user-popup-menu {
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: 56px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 12px 40px rgba(0,0,0,.18);
  padding: 6px;
  z-index: 80;
  display: none;
}
.user-popup-menu.open { display: block; }
.user-popup-menu .menu-email {
  padding: 8px 10px;
  font-size: .76rem;
  color: var(--text-muted);
  border-bottom: 1px solid var(--border-soft);
  margin-bottom: 4px;
  word-break: break-all;
}
.user-popup-menu .menu-item {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px;
  color: var(--text-dark);
  text-decoration: none;
  border-radius: 6px;
  font-size: .85rem;
  cursor: pointer;
  background: transparent;
  border: none;
  width: 100%;
  text-align: left;
}
.user-popup-menu .menu-item:hover { background: var(--brand-soft); color: var(--text-dark); }
.user-popup-menu .menu-item i { width: 16px; font-size: .95rem; color: var(--text-muted); }
.user-popup-menu .menu-divider {
  height: 1px; background: var(--border-soft); margin: 4px 0;
}
.user-popup-menu .plan-tag {
  margin-left: auto;
  font-size: .68rem;
  background: var(--brand-light);
  color: var(--text-dark);
  padding: 2px 8px;
  border-radius: 999px;
  font-weight: 600;
}

/* Theme toggle inside menu */
.theme-switch-row {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px;
  font-size: .85rem;
  color: var(--text-dark);
}
.theme-switch-row .theme-segs {
  margin-left: auto;
  display: inline-flex;
  background: var(--brand-soft);
  border-radius: 999px;
  padding: 3px;
}
.theme-switch-row .theme-seg {
  border: none;
  background: transparent;
  padding: 3px 9px;
  font-size: .74rem;
  border-radius: 999px;
  cursor: pointer;
  color: var(--text-muted);
  font-weight: 500;
}
.theme-switch-row .theme-seg.active {
  background: var(--bg);
  color: var(--text-dark);
  box-shadow: 0 1px 3px rgba(0,0,0,.1);
}

/* ----- Main ----- */
.chat-main {
  flex: 1;
  display: flex; flex-direction: column;
  min-width: 0;
  overflow: hidden;
}
.chat-topbar {
  /* v28: the Builder 2.0 model pill was removed from this bar, so we add a
     small min-height to keep the area visually balanced even when empty. */
  padding: 10px 20px;
  min-height: 52px;
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between;
  background: var(--bg);
  gap: 10px;
  flex-shrink: 0;
}

/* Model selector dropdown */
.chat-topbar .model-selector .model-name {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--brand-light);
  color: var(--text-dark);
  padding: 6px 12px;
  border: none;
  border-radius: 999px;
  font-weight: 600;
  font-size: .85rem;
  cursor: pointer;
}
.chat-topbar .model-selector .model-name:hover { background: var(--brand-soft); }
.chat-topbar .model-menu {
  min-width: 280px;
  padding: 6px;
  border-radius: 12px;
  border: 1px solid var(--border);
  box-shadow: 0 12px 32px rgba(0,0,0,.08);
  background: var(--bg);
}
.chat-topbar .model-option {
  padding: 10px 12px;
  border-radius: 8px;
  color: var(--text-dark);
}
.chat-topbar .model-option:hover { background: var(--brand-soft); }
.chat-topbar .model-option.active { background: var(--brand-light); }
.chat-topbar .model-option .fw-semibold { color: var(--text-dark); }
.chat-topbar .model-option .small { color: var(--text-muted); }

/* =====================================================
   MESSAGES AREA - STRAIGHT VERTICAL ALIGNMENT (ChatGPT-style)
   Both user and assistant messages share the same left
   alignment and the same constrained width. This guarantees
   a clean, perfectly straight vertical line through the
   conversation.
   ===================================================== */
.chat-messages {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 24px clamp(12px, 3vw, 24px) 32px;
  background: var(--bg);
  position: relative;
  width: 100%;
}
.chat-messages.is-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

/* Universal width constraint - same for empty state and messages */
.chat-messages > .message,
.chat-messages > .chat-empty {
  width: 100%;
  max-width: 780px;
  margin-left: auto;
  margin-right: auto;
}

/* ===== Message bubble — UNIFIED LEFT ALIGNMENT ===== */
.message {
  width: 100%;
  max-width: 780px;
  margin: 0 auto 20px;
  display: flex;
  gap: 12px;
  align-items: flex-start;
  /* Force consistent left-aligned layout for ALL messages */
  flex-direction: row;
  justify-content: flex-start;
}

/* Override - both user and assistant align identically */
.message.user,
.message.assistant {
  flex-direction: row;
  justify-content: flex-start;
  margin-left: auto;
  margin-right: auto;
}

.message .avatar {
  width: 32px; height: 32px;
  border-radius: 50%;
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: .85rem;
  color: #fff;
  overflow: hidden;
}
.message.user .avatar {
  background: linear-gradient(135deg, #475569, #334155);
}
.message.assistant .avatar {
  background: transparent;
  border: none;                 /* v14: ring removed */
  padding: 0;
  box-shadow: none;
}
.message.assistant .avatar svg { width: 100%; height: 100%; border-radius: 50%; }

/* Bubble — flex:1 with min-width:0 so children (incl. wide code blocks) shrink correctly */
.message .bubble {
  flex: 1 1 auto;
  min-width: 0;
  max-width: calc(100% - 44px);
  line-height: 1.65;
  color: var(--text-dark);
  word-wrap: break-word;
  padding-top: 2px;
}

.message.user .bubble {
  background: var(--user-bubble);
  border: 1px solid var(--border-soft);
  border-radius: 14px;
  padding: 10px 14px;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .04);
}

.message.assistant .bubble {
  background: transparent;
  padding: 4px 0;
}

.message .bubble .content { white-space: normal; word-break: break-word; overflow-wrap: anywhere; }
.message .bubble .content > br + br { line-height: .8; }

/* =====================================================
   CODE BLOCKS — LIGHT GREY "SHEET" THEME (v19)
   Contained within bubble; soft grey paper look, not
   the heavy black box we had before. Inspired by the
   ChatGPT code-card style.
   The code-block must NEVER overflow its parent bubble.
   It scrolls internally on the X-axis instead of pushing
   the layout wider.
   ===================================================== */
.message .bubble .code-block {
  margin: 12px 0;
  background: var(--code-bg);
  border-radius: 12px;
  overflow: hidden;
  border: 1px solid var(--code-border);
  /* v19: soft, low-contrast shadow so the card reads as a
     light sheet of paper instead of a heavy dark block. */
  box-shadow: 0 1px 2px rgba(15, 23, 42, .04),
              0 2px 6px rgba(15, 23, 42, .04);
  /* Strict containment to the bubble width */
  max-width: 100%;
  width: 100%;
}
.message .bubble .code-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  padding: 8px 12px;
  background: var(--code-head-bg);
  color: #1f2328;
  font-size: .76rem;
  border-bottom: 1px solid var(--code-border);
}
.message .bubble .code-head .code-meta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  flex: 1 1 180px;
}
.message .bubble .code-head .code-meta span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #1f2328;
  font-weight: 500;
}
.message .bubble .code-head em {
  color: #6b7280;
  font-style: normal;
  opacity: .95;
  text-transform: lowercase;
}
.message .bubble .code-head .code-actions {
  display: inline-flex;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.message .bubble .code-head .code-btn {
  background: rgba(0,0,0,.04);
  color: #1f2328;
  border: 1px solid rgba(0,0,0,.10);
  border-radius: 6px;
  padding: 3px 9px;
  font-size: .7rem;
  cursor: pointer;
  display: inline-flex; align-items: center; gap: 4px;
  transition: all .15s ease;
}
.message .bubble .code-head .code-btn:hover {
  background: rgba(0,0,0,.08);
  border-color: rgba(0,0,0,.18);
  color: #000;
}
.message .bubble .code-head .code-btn.is-success {
  background: #16a34a;
  border-color: #16a34a;
  color: #ffffff;
}
.message .bubble .code-head .code-btn.is-error {
  background: #b91c1c;
  border-color: #b91c1c;
  color: #ffffff;
}

/* The <pre> is the scroll container — horizontal scroll, never pushes layout */
.message .bubble pre {
  background: var(--code-bg);
  color: var(--code-text);
  padding: 14px 16px;
  overflow-x: auto;
  overflow-y: hidden;
  font-size: .82rem;
  margin: 0;
  font-family: 'JetBrains Mono', 'Menlo', 'Consolas', 'Courier New', monospace;
  line-height: 1.6;
  max-width: 100%;
}
.message .bubble pre code,
.message .bubble pre code.hljs {
  display: block;
  background: transparent !important;
  color: inherit;
  padding: 0 !important;
  white-space: pre;
  word-wrap: normal;
}

/* Inline code (within paragraphs) — v19 light-theme inline pill */
.message .bubble code {
  background: rgba(15, 23, 42, .06);
  color: #b91c1c;
  padding: 2px 6px;
  border-radius: 4px;
  font-size: .88em;
  font-family: 'JetBrains Mono', 'Menlo', 'Consolas', monospace;
}

/* Highlight.js color palette — v19 LIGHT THEME, tuned for the soft
   grey code-block background. Colours follow the GitHub light /
   ChatGPT light palette so the sheet stays calm and readable. */
.message .bubble pre .hljs-comment,
.message .bubble pre .hljs-quote { color: #6a737d; font-style: italic; }
.message .bubble pre .hljs-keyword,
.message .bubble pre .hljs-selector-tag,
.message .bubble pre .hljs-literal,
.message .bubble pre .hljs-section,
.message .bubble pre .hljs-link { color: #d73a49; }
.message .bubble pre .hljs-string,
.message .bubble pre .hljs-attr,
.message .bubble pre .hljs-attribute,
.message .bubble pre .hljs-template-variable { color: #032f62; }
.message .bubble pre .hljs-number,
.message .bubble pre .hljs-symbol,
.message .bubble pre .hljs-bullet { color: #005cc5; }
.message .bubble pre .hljs-title,
.message .bubble pre .hljs-title.function_,
.message .bubble pre .hljs-function,
.message .bubble pre .hljs-selector-id,
.message .bubble pre .hljs-selector-class { color: #6f42c1; }
.message .bubble pre .hljs-variable,
.message .bubble pre .hljs-property,
.message .bubble pre .hljs-name,
.message .bubble pre .hljs-tag { color: #22863a; }
.message .bubble pre .hljs-built_in,
.message .bubble pre .hljs-type { color: #e36209; }
.message .bubble pre .hljs-meta { color: #6a737d; }

/* Code-block scrollbar styling */
.message .bubble pre::-webkit-scrollbar { height: 8px; }
.message .bubble pre::-webkit-scrollbar-track { background: rgba(255,255,255,.04); }
.message .bubble pre::-webkit-scrollbar-thumb { background: rgba(0,0,0,.18); border-radius: 4px; }
.message .bubble pre::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,.30); }

/* v17: Code block stays a soft grey sheet in dark mode too (ChatGPT-style) */
body.dark-mode .message .bubble .code-block { background: #f4f4f5; border-color: #d4d4d8; }
body.dark-mode .message .bubble .code-head  { background: #e7e7ea; color: #1f2328; border-bottom-color: #d4d4d8; }
body.dark-mode .message .bubble pre         { background: #f4f4f5; color: #1f2328; }
body.dark-mode .message .bubble .code-head .code-meta span { color: #1f2328; }
body.dark-mode .message .bubble .code-head .code-btn { background: rgba(0,0,0,.05); color: #1f2328; border-color: rgba(0,0,0,.12); }
body.dark-mode .message .bubble .code-head .code-btn:hover { background: rgba(0,0,0,.10); color: #000; }

/* Attachments */
.message .attachment {
  margin-top: 8px;
  padding: 8px 12px;
  background: var(--brand-soft);
  border-radius: 8px;
  font-size: .85rem;
  display: inline-flex; align-items: center; gap: 8px;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}
.message .attachment.download-link {
  background: var(--brand-light);
  border: 1px solid var(--border);
}
.message .attachment.download-link a { color: var(--text-dark); font-weight: 600; text-decoration: none; }
.message .attachment.download-link a:hover { text-decoration: underline; }

/* ===== Thinking strip ===== */
.message.thinking .bubble { padding-top: 8px; }
.thinking-strip {
  display: inline-flex; align-items: center; gap: 10px;
  background: var(--brand-soft);
  border: 1px solid var(--border-soft);
  color: var(--text-dark);
  padding: 8px 14px;
  border-radius: 999px;
  font-size: .85rem;
  font-weight: 500;
}
.thinking-strip .thinking-label { transition: opacity .25s ease; }

/* v22: silent variant — dots only, no "Thinking… / Searching…" labels. */
.thinking-strip.is-silent {
  padding: 8px 14px;
  background: var(--brand-soft);
}
.thinking-strip.is-silent .typing-dots span {
  width: 7px; height: 7px;
  background: var(--text-muted);
}

/* Typing dots */
.typing-dots { display: inline-flex; gap: 4px; align-items: center; }
.typing-dots span {
  width: 6px; height: 6px; background: var(--text-muted);
  border-radius: 50%;
  animation: bounce 1.4s infinite ease-in-out both;
}
.typing-dots span:nth-child(1) { animation-delay: -.32s; }
.typing-dots span:nth-child(2) { animation-delay: -.16s; }
@keyframes bounce { 0%, 80%, 100% { transform: scale(0); opacity:.4; } 40% { transform: scale(1); opacity:1; } }

/* ===== Sources strip ===== */
.sources-inline {
  margin-top: 12px;
  padding: 10px 0 2px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: .82rem;
  line-height: 1.5;
}
.sources-inline-label {
  font-size: .78rem;
  font-weight: 600;
  color: var(--text-muted);
  display: inline-flex; align-items: center; gap: 5px;
}
.sources-inline-label .bi-info-circle { font-size: .75rem; opacity: .7; }
.sources-inline-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 14px;
}
.sources-inline-list .src-item {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  color: #1a73e8;
  text-decoration: none;
  font-weight: 500;
  transition: color .15s, text-decoration-color .15s;
  border-bottom: 1px solid transparent;
  padding-bottom: 1px;
}
.sources-inline-list .src-item:hover {
  color: #1558c0;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.sources-inline-list .src-num {
  font-weight: 600;
  color: var(--text-muted);
  font-size: .78rem;
}
.sources-inline-list .src-extra { display: none; }
.sources-inline-list .src-extra .src-item { margin-right: 14px; }

.src-more-btn {
  background: transparent;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: .8rem;
  font-weight: 500;
  padding: 2px 6px;
  border-radius: 6px;
  display: inline-flex; align-items: center; gap: 4px;
  transition: background .15s, color .15s;
}
.src-more-btn:hover { background: var(--brand-soft); color: var(--text-dark); }
.src-more-btn .src-more-count { color: var(--text-muted); font-weight: 400; }

body.dark-mode .sources-inline-list .src-item { color: #8ab4f8; }
body.dark-mode .sources-inline-list .src-item:hover { color: #a8c7fa; }

/* ===== Empty state ===== */
.chat-empty {
  text-align: center;
  width: 100%;
  max-width: 780px;
  color: var(--text-muted);
  padding: 20px;
  margin: 0 auto;
}
.chat-empty h2 { color: var(--text-dark); font-weight: 700; margin-bottom: 6px; }
.chat-empty .logo-big {
  display: inline-flex; align-items: center; justify-content: center;
  margin-bottom: 16px;
}

/* ===== Composer ===== */
.composer-card { margin: 24px auto 16px; max-width: 740px; width: 100%; }
.center-composer .composer-inner { box-shadow: 0 8px 28px rgba(0,0,0,.06); }

.composer-inner {
  border: 1.5px solid var(--border);
  border-radius: 18px;
  padding: 10px;
  display: flex; align-items: flex-end; gap: 8px;
  transition: all .2s;
  background: var(--bg);
  box-shadow: 0 4px 14px rgba(0,0,0,.04);
}
.composer-inner:focus-within { border-color: var(--brand); box-shadow: 0 0 0 3px rgba(0,0,0,.08); }
.composer-inner textarea {
  flex: 1;
  min-width: 0;
  width: 100%;
  border: none; outline: none; resize: none;
  font-size: .95rem;
  padding: 10px;
  max-height: none;
  overflow-y: hidden;
  overflow-wrap: anywhere;
  word-break: break-word;
  white-space: pre-wrap;
  font-family: inherit;
  background: transparent;
  color: var(--text-dark);
}
.composer-inner textarea::placeholder { color: var(--text-muted); }
.composer-btn {
  background: transparent; border: none;
  color: var(--text-muted);
  padding: 8px 10px;
  border-radius: 10px;
  cursor: pointer;
  transition: all .15s;
}
.composer-btn:hover { background: var(--brand-soft); color: var(--text-dark); }
.composer-btn.send  { background: var(--brand); color: #fff; }
.composer-btn.send:hover     { background: var(--brand-dark); color: #fff; }
.composer-btn.send:disabled  { background: var(--text-muted); cursor: not-allowed; opacity: .6; }

.composer-help {
  margin: 8px auto 0;
  font-size: .75rem; color: var(--text-muted);
  text-align: center;
}

/* File preview
   v22: multi-attachment chips that live INSIDE the composer box.
        Each chip is a small rounded card; multiple chips wrap onto
        new lines, and the parent composer expands up to its max-height
        as more files are queued (Genspark / ChatGPT style).
   v21: redesigned as a Google / ChatGPT style attachment chip.
   Images render a real thumbnail; non-image files render a file-type
   icon. The whole chip has its own rounded card with a subtle hover. */
.file-preview {
  padding: 6px 8px 6px 6px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 12px;
  font-size: .82rem;
  display: inline-flex; align-items: center; gap: 8px;
  max-width: 280px;
  color: var(--text-dark);
  box-shadow: 0 1px 2px rgba(0,0,0,.04);
}
.file-preview .file-thumb {
  width: 36px; height: 36px;
  border-radius: 8px;
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  background: var(--brand-light);
}
.file-preview .file-thumb-img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.file-preview .file-thumb-doc {
  background: var(--brand-light);
  color: var(--brand-primary);
  font-size: 1.15rem;
}
.file-preview .file-meta {
  display: flex; flex-direction: column; line-height: 1.2;
  min-width: 0;
  max-width: 180px;
}
.file-preview .fname {
  font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.file-preview .fsize { color: var(--text-muted); font-size: .75rem; }
.file-preview .remove-file {
  position: relative;
  margin-left: 4px;
  background: rgba(0,0,0,.06);
  border: none;
  color: var(--text-dark);
  cursor: pointer;
  width: 22px; height: 22px;
  padding: 0;
  border-radius: 50%;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: .75rem;
  flex-shrink: 0;
  transition: background .15s, color .15s;
}
.file-preview .remove-file:hover { background: #dc2626; color: #fff; }
body.dark-mode .file-preview .remove-file { background: rgba(255,255,255,.10); color: #ECECEC; }
body.dark-mode .file-preview .remove-file:hover { background: #dc2626; color: #fff; }

/* v22: image chip variant — thumb is a touch larger and the meta sits
   beside it the same way for visual consistency with file chips. */
.file-preview.file-preview-image .file-thumb { background: transparent; }
.file-preview.file-preview-image .file-thumb-img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  background: var(--brand-light);
}

/* v22: file-preview strip INSIDE the composer-inner.
   It expands the composer vertically (up to the inner-box max-height)
   as chips are added. Chips wrap onto new lines if they overflow. */
.composer-inner { flex-direction: column; align-items: stretch; gap: 0; }
.composer-inner .composer-row {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  width: 100%;
}
.composer-inner .file-preview-strip {
  /* v51.9.1: stack chips top-to-bottom instead of wrapping side-by-side */
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap;
  gap: 6px;
  padding: 2px 4px 6px;
  max-height: 220px;
  overflow-y: auto;
  scrollbar-width: thin;
}
.composer-inner .file-preview-strip:empty { display: none; }
.composer-inner.has-attachments-host { padding: 8px 10px; }
.composer-inner.has-files .file-preview-strip {
  border-bottom: 1px dashed var(--border);
  margin-bottom: 6px;
}
.composer-inner.is-dragover {
  border-color: var(--brand);
  background: var(--brand-light);
  box-shadow: 0 0 0 3px rgba(31,41,55,.10);
}

/* Bottom composer */
.chat-composer-bottom {
  border-top: 1px solid var(--border);
  padding: 12px clamp(12px, 3vw, 24px) 16px;
  background: var(--bg);
  flex-shrink: 0;
}
.chat-composer-bottom .composer-inner,
.chat-composer-bottom > #filePreviewBottom {
  max-width: 780px;
  margin-left: auto;
  margin-right: auto;
}
.chat-composer-bottom #filePreviewBottom { max-width: 780px; margin: 0 auto 8px; }

/* Suggestion chips */
.suggestion-chips {
  display: flex; flex-wrap: wrap; gap: 10px;
  justify-content: center;
  margin-top: 20px; max-width: 740px; margin-left: auto; margin-right: auto;
}
.chip {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 9px 16px;
  font-size: .85rem;
  color: var(--text-dark);
  cursor: pointer;
  transition: all .15s;
}
.chip:hover { border-color: var(--brand); background: var(--brand-soft); color: var(--text-dark); }

/* ===== HTML preview overlay ===== */
.html-preview-overlay {
  position: fixed; inset: 0;
  background: rgba(15, 23, 42, .55);
  z-index: 2050;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
}
.html-preview-modal {
  background: #ffffff;
  border-radius: 14px;
  width: min(1100px, 96vw);
  height: min(82vh, 800px);
  display: flex; flex-direction: column;
  box-shadow: 0 24px 60px rgba(0,0,0,.30);
  overflow: hidden;
}
.html-preview-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 14px;
  background: #ffffff;
  border-bottom: 1px solid #e5e7eb;
  font-weight: 600;
  color: #0f172a;
}
.hpv-btn {
  background: #ffffff;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 4px 10px;
  cursor: pointer;
  color: #0f172a;
}
.hpv-btn:hover { background: #f3f4f6; }
#htmlPreviewFrame {
  flex: 1; width: 100%;
  border: none;
  background: #ffffff;
}

/* ===== Project files panel ===== */
.project-files-panel {
  margin-top: 12px;
  background: var(--brand-soft);
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  padding: 12px 14px;
  max-width: 100%;
}
.project-files-panel .pfp-head {
  display: flex; align-items: center; justify-content: space-between;
  font-weight: 600;
  font-size: .85rem;
  color: var(--text-dark);
  margin-bottom: 10px;
}
.project-files-panel .pfp-actions { display: inline-flex; gap: 6px; }
.project-files-panel .pfp-actions a {
  text-decoration: none;
  font-size: .78rem;
  padding: 5px 10px;
  border-radius: 8px;
  background: var(--brand);
  color: #fff;
  display: inline-flex; align-items: center; gap: 5px;
  font-weight: 500;
}
.project-files-panel .pfp-actions a:hover { background: var(--brand-dark); }
.project-files-panel .pfp-list {
  display: flex; flex-direction: column; gap: 4px;
}
.pfp-file {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px;
  border-radius: 8px;
  background: var(--bg);
  border: 1px solid var(--border-soft);
  font-size: .82rem;
  color: var(--text-dark);
}
.pfp-file i { color: var(--text-muted); }
.pfp-file .fname { flex: 1; font-family: 'JetBrains Mono', monospace; font-size: .8rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pfp-file .fdl {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-dark);
  border-radius: 6px;
  padding: 2px 8px;
  font-size: .72rem;
  cursor: pointer;
  text-decoration: none;
}
.pfp-file .fdl:hover { background: var(--brand-light); }

/* ===== Admin Layout ===== */
.admin-layout { display: flex; min-height: 100vh; background: var(--bg-alt); }
.admin-sidebar {
  width: 250px;
  background: var(--bg);
  border-right: 1px solid var(--border);
  padding: 20px 0;
  flex-shrink: 0;
}
.admin-sidebar .brand {
  padding: 0 20px 20px;
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 10px;
  font-weight: 700; color: var(--brand);
}
.admin-sidebar a {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 20px;
  color: var(--text-dark); text-decoration: none;
  font-weight: 500; font-size: .92rem;
  border-left: 3px solid transparent;
  transition: all .15s;
}
.admin-sidebar a:hover { background: var(--brand-soft); color: var(--text-dark); }
.admin-sidebar a.active { background: var(--brand-soft); color: var(--text-dark); border-left-color: var(--brand); font-weight: 600; }
.admin-sidebar .nav-section-label {
  padding: 16px 20px 6px;
  font-size: .7rem;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 700;
  letter-spacing: .08em;
}
.admin-content { flex: 1; padding: 30px; min-width: 0; }
.admin-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 24px;
  margin-bottom: 20px;
}
.stat-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 20px;
  transition: all .2s;
}
.stat-card:hover { border-color: var(--brand); box-shadow: 0 4px 14px rgba(0,0,0,.06); }
.stat-card .stat-value { font-size: 2rem; font-weight: 700; color: var(--brand); }
.stat-card .stat-label { color: var(--text-muted); font-size: .85rem; text-transform: uppercase; letter-spacing: .04em; }
.stat-card .stat-icon {
  width: 40px; height: 40px;
  border-radius: 10px;
  background: var(--brand-light);
  color: var(--text-dark);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 1.2rem;
  margin-bottom: 8px;
}

/* ===== Tables ===== */
.table thead th { background: var(--brand-soft); color: var(--text-dark); font-weight: 600; border-bottom: 1px solid var(--border); }

/* ===== Badges ===== */
.badge.bg-brand { background: var(--brand) !important; }

/* =====================================================
   RESPONSIVE — Tablet & Mobile
   ===================================================== */
@media (max-width: 1024px) {
  .chat-messages > .message,
  .chat-messages > .chat-empty,
  .message,
  .chat-composer-bottom .composer-inner,
  .chat-composer-bottom > #filePreviewBottom {
    max-width: 720px;
  }
}

@media (max-width: 768px) {
  .hero h1 { font-size: 2.2rem; }

  /* Sidebar — slide-in drawer */
  .chat-sidebar  {
    position: fixed;
    left: -86vw;
    width: 86vw;
    max-width: 280px;
    height: 100vh;
    z-index: 1000;
    transition: left .25s;
    box-shadow: 4px 0 20px rgba(0,0,0,.15);
  }
  .chat-sidebar.open  { left: 0; }
  .sidebar-toggle-btn { display: none; }

  .admin-sidebar { position: fixed; left: -250px; height: 100vh; z-index: 1000; transition: left .25s; }
  .admin-sidebar.open { left: 0; }
  .pricing-card.featured { transform: none; }

  /* Topbar */
  .chat-topbar {
    padding: 10px 12px;
    gap: 8px;
  }
  .chat-topbar .model-selector .model-name {
    padding: 6px 10px;
    font-size: .82rem;
  }

  /* Messages area — tighter on mobile but still constrained */
  .chat-messages {
    padding: 14px 12px 24px;
  }
  .chat-messages > .message,
  .chat-messages > .chat-empty,
  .message {
    max-width: 100%;
  }
  .message {
    gap: 10px;
    margin-bottom: 16px;
  }
  .message .avatar {
    width: 30px;
    height: 30px;
    font-size: .8rem;
  }
  .message .bubble {
    max-width: calc(100% - 40px);
  }
  .message.user .bubble {
    padding: 9px 13px;
    border-radius: 12px;
    font-size: .92rem;
  }
  .message .bubble .code-block {
    border-radius: 8px;
    margin: 10px 0;
  }
  .message .bubble .code-head {
    padding: 7px 10px;
    align-items: flex-start;
    flex-direction: column;
    gap: 6px;
  }
  .message .bubble .code-head .code-actions {
    width: 100%;
    justify-content: flex-start;
  }
  .message .bubble pre {
    padding: 12px;
    font-size: .78rem;
  }

  /* Composer */
  .composer-card {
    margin: 10px auto;
    width: 100%;
    max-width: 100%;
  }
  .chat-composer-bottom {
    padding: 10px 12px calc(12px + env(safe-area-inset-bottom));
  }
  .chat-composer-bottom .composer-inner,
  .chat-composer-bottom > #filePreviewBottom,
  .center-composer,
  .file-preview {
    width: 100%;
    max-width: 100%;
  }
  .composer-inner {
    padding: 7px;
    border-radius: 14px;
    gap: 6px;
  }
  .composer-inner textarea {
    font-size: .9rem;
    padding: 8px;
  }
  .composer-btn {
    flex: 0 0 auto;
    padding: 7px;
  }
  .chat-sidebar .new-chat-btn {
    margin: 8px 10px 8px;
    padding: 8px 10px;
    font-size: .85rem;
  }
  .chat-empty h2 { font-size: 1.4rem; }
  .chat-empty p { font-size: .9rem; }
}

@media (max-width: 480px) {
  .chat-messages {
    padding: 12px 8px 20px;
  }
  .message {
    gap: 8px;
  }
  .message .avatar {
    width: 28px;
    height: 28px;
    font-size: .75rem;
  }
  .message .bubble {
    max-width: calc(100% - 36px);
    line-height: 1.55;
  }
  .message.user .bubble {
    padding: 8px 12px;
    border-radius: 12px;
    font-size: .9rem;
  }
  .message .bubble .code-head {
    padding: 6px 8px;
  }
  .message .bubble .code-head .code-btn {
    padding: 3px 7px;
    font-size: .68rem;
  }
  .message .bubble pre {
    padding: 10px 12px;
    font-size: .74rem;
  }
  .chat-composer-bottom {
    padding: 8px 8px calc(10px + env(safe-area-inset-bottom));
  }
  .composer-inner {
    padding: 6px;
    border-radius: 14px;
  }
  .composer-help {
    font-size: .68rem;
  }
  .chat-empty h2 { font-size: 1.2rem; }
  .suggestion-chips { gap: 6px; margin-top: 16px; }
  .chip {
    padding: 7px 12px;
    font-size: .78rem;
  }
}

/* =====================================================================
   v10.0 UI FIXES — applied as overrides at the end so we don't disturb
   any earlier rules. Covers:
     1. User bubbles aligned to the RIGHT (ChatGPT-style)
     2. Assistant "sticker" avatar — bigger, centered, gold ring
     3. Model selector — clean two-line label "Builder 2.0 / Best for coding"
     4. Code block header — single filename, no language tag
     5. Typing animation — caret + smooth reveal
     6. Vertical alignment of the conversation column kept perfectly
        straight (no leftward drift on long answers)
   ===================================================================== */

/* ---------- 1. User messages on the RIGHT ---------- */
.chat-messages > .message.user {
  flex-direction: row-reverse;   /* avatar on the right, bubble flows right-to-left */
  justify-content: flex-start;
  margin-left: auto;
  margin-right: auto;
}
.chat-messages > .message.user .bubble {
  background: var(--user-bubble);
  border: 1px solid var(--border-soft);
  border-radius: 16px 16px 4px 16px;
  padding: 10px 14px;
  max-width: min(70%, 560px);    /* user bubble is narrower so it sits on the right */
  flex: 0 1 auto;
  text-align: left;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .04);
}
.chat-messages > .message.user .avatar {
  background: linear-gradient(135deg, #475569, #334155);
}

/* Assistant stays left-aligned and full-width — but keep the column straight */
.chat-messages > .message.assistant {
  flex-direction: row;
  justify-content: flex-start;
}
.chat-messages > .message.assistant .bubble {
  text-align: left;
  max-width: calc(100% - 50px);
}

/* ---------- 2. Assistant avatar — v14: NO RING, clean borderless logo ---------- */
.message.assistant .avatar {
  width: 36px;
  height: 36px;
  background: transparent;
  border: none;                 /* v14: removed gold ring entirely */
  box-shadow: none;             /* v14: removed glow */
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.message.assistant .avatar svg,
.message.assistant .avatar img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  display: block;
  object-fit: contain;
}
body.dark-mode .message.assistant .avatar {
  background: transparent;
  border: none;
  box-shadow: none;
}

/* ---------- 3. Model selector pill — ChatGPT-4 style, longer & roomier ---------- */
.chat-topbar .model-selector .model-name {
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  padding: 9px 22px 10px 18px;   /* v11: larger pill, more horizontal room */
  line-height: 1.2;
  min-width: 220px;              /* v11: ensures the subtitle fits in one line */
  border-radius: 14px;           /* v11: gentler, more ChatGPT-4-like */
}
.chat-topbar .model-selector .model-name > i.bi-stars {
  display: none;        /* the star icon was crowding the two-line label */
}
.chat-topbar .model-selector .model-name #modelLabel {
  font-weight: 700;
  font-size: 1rem;               /* v11: bigger main title */
  letter-spacing: .1px;
}
.chat-topbar .model-selector .model-name .model-sub {
  font-size: .74rem;             /* v11: subtitle slightly bigger so it reads naturally */
  font-weight: 500;
  color: var(--text-muted);
  margin-top: 2px;
  letter-spacing: .15px;
  white-space: nowrap;
}
.chat-topbar .model-selector .model-name::after {
  margin-left: 12px;
  align-self: center;
}

/* ---------- 4. Code header — clean single filename, no language tag ---------- */
.message .bubble .code-head .code-fname {
  color: #e4e4e7;
  font-weight: 600;
  font-size: .78rem;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* legacy <em> language tag is gone — hide it just in case it ever shows up */
.message .bubble .code-head em { display: none; }

.message .bubble .code-head .code-btn .btn-label {
  display: inline-block;
}
.message .bubble .code-head .code-btn {
  transition: background .15s ease, border-color .15s ease, color .15s ease, transform .12s ease;
}
.message .bubble .code-head .code-btn:active { transform: translateY(1px); }

/* ---------- 5. Typing animation ---------- */
.message.assistant .content.is-typing {
  white-space: pre-wrap;
  word-break: break-word;
  font-family: inherit;
}
.message.assistant .content.is-typing .typed-text {
  white-space: pre-wrap;
}
.typing-caret {
  display: inline-block;
  width: 7px;
  height: 1.05em;
  margin-left: 2px;
  vertical-align: text-bottom;
  background: currentColor;
  opacity: .75;
  animation: hanaCaretBlink 1s steps(1) infinite;
  border-radius: 1px;
}
@keyframes hanaCaretBlink {
  0%, 49%   { opacity: .75; }
  50%, 100% { opacity: 0;   }
}

/* ---------- 6. Conversation column — keep it perfectly straight ---------- */
.chat-messages {
  padding-left: clamp(16px, 4vw, 32px);
  padding-right: clamp(16px, 4vw, 32px);
}
.chat-messages > .message,
.chat-messages > .chat-empty {
  max-width: 780px;
  margin-left: auto;
  margin-right: auto;
}

/* Make sure long answers don't drift left because of wide code blocks */
.message .bubble { min-width: 0; }
.message .bubble .code-block { max-width: 100%; }

/* ---------- v11: ChatGPT-4 style action toolbar under each assistant reply ----------
   v50.9: increased vertical gap so the copy / like / dislike row is
   noticeably separated from whatever content sits above it — especially
   the generated-image card, which used to look glued to the toolbar. */
.message.assistant .bubble .msg-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 14px;
  padding-top: 6px;
  opacity: .85;
  transition: opacity .15s ease;
}
/* v50.9: when the msg-actions row sits directly below a generated-image
   card, give it an even bigger gap so the icons don't visually collide
   with the rounded image corners. */
.message.assistant .bubble .gen-image-card + .msg-actions {
  margin-top: 18px;
  padding-top: 8px;
}
.message.assistant:hover .bubble .msg-actions { opacity: 1; }
.message.assistant .bubble .msg-act {
  background: transparent;
  border: none;
  color: var(--text-muted);
  width: 30px;
  height: 30px;
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: .95rem;
  transition: background .15s ease, color .15s ease, transform .12s ease;
}
.message.assistant .bubble .msg-act:hover {
  background: var(--brand-soft);
  color: var(--text-dark);
}
.message.assistant .bubble .msg-act:active { transform: translateY(1px); }
.message.assistant .bubble .msg-act.is-success { color: var(--success); }
.message.assistant .bubble .msg-act.is-error   { color: var(--danger); }
body.dark-mode .message.assistant .bubble .msg-act:hover {
  background: rgba(255,255,255,.06);
  color: #ffffff;
}

/* v51.1 — USER message action row (Copy + Edit).
   Sits underneath each user bubble, right-aligned to match the bubble side.
   Small, flat, borderless — no shadow, no lift.

   Visibility rule (v51.1): the row is INVISIBLE by default — hover no
   longer reveals it. The user has to CLICK the bubble to toggle it on.
   Clicking the bubble again (or outside) hides it. This keeps the chat
   clean and only surfaces actions when the user explicitly wants them.

   The toggle itself is handled in chat.js by adding / removing the
   `.actions-open` class on the .message.user element. */
.message.user .user-msg-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 2px;
  margin-top: 4px;
  padding-right: 2px;
  opacity: 0;
  pointer-events: none;
  transition: opacity .15s ease;
}
.message.user.actions-open .user-msg-actions {
  opacity: .9;
  pointer-events: auto;
}
.message.user .user-msg-actions .user-msg-act {
  background: transparent;
  border: none;
  color: var(--text-muted, #64748b);
  width: 26px;
  height: 26px;
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: .82rem;
  transition: background .15s ease, color .15s ease;
}
.message.user .user-msg-actions .user-msg-act:hover {
  background: rgba(15, 23, 42, .06);
  color: var(--text-dark, #0f172a);
}
.message.user .user-msg-actions .user-msg-act.is-copied {
  color: var(--success, #16a34a);
}
body.dark-mode .message.user .user-msg-actions .user-msg-act {
  color: #9aa3b2;
}
body.dark-mode .message.user .user-msg-actions .user-msg-act:hover {
  background: rgba(255,255,255,.06);
  color: #ffffff;
}

/* ---------- v11: Sidebar header without the logo — just the company name ---------- */
.chat-sidebar .sidebar-header {
  justify-content: flex-start;
}
.chat-sidebar .sidebar-header .sidebar-brand {
  font-size: 1.05rem;
  letter-spacing: .2px;
}

/* ---------- v11: Sources strip stays VISIBLE permanently (no fade) ---------- */
.message.assistant .bubble .sources-inline {
  opacity: 1 !important;
  visibility: visible !important;
  margin-top: 10px;
  margin-bottom: 4px;
}

/* ---------- Empty-state composer sits centered, not drifted left ---------- */
.chat-empty .center-composer {
  max-width: 720px;
  margin-left: auto;
  margin-right: auto;
}
.chat-empty h2 {
  text-align: center;
}
.chat-empty p {
  text-align: center;
}

/* ---------- Mobile: user bubble should still hug the right edge ---------- */
@media (max-width: 640px) {
  .chat-messages > .message.user .bubble {
    max-width: 80%;
  }
}

/* =====================================================================
   v12.0 UI FIXES
   ---------------------------------------------------------------------
   1. USER BUBBLE — never grows infinitely. Long content (pasted code,
      huge logs, etc.) is capped at a sensible max-height and scrolls
      internally instead of pushing the chat layout taller.
   2. SIDEBAR — small breathing gap between "New chat" and "Recent chats"
      so the two sections don't sit glued together.
   3. SIDEBAR INNER TOGGLE — ChatGPT-style icon button placed inside the
      sidebar header. The old floating arrow on the right edge of the
      sidebar is removed; collapsing is now done via this header icon.
   4. MODEL SELECTOR — single static pill (no dropdown caret, no menu).
      The admin selects the underlying engine from the backend.
   ===================================================================== */

/* ---------- 1. User bubble height cap + internal scroll ---------- */
.chat-messages > .message.user .bubble {
  max-height: 360px;             /* about 18-20 lines of normal text */
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: rgba(100, 116, 139, .35) transparent;
}
.chat-messages > .message.user .bubble::-webkit-scrollbar {
  width: 8px;
}
.chat-messages > .message.user .bubble::-webkit-scrollbar-track {
  background: transparent;
}
.chat-messages > .message.user .bubble::-webkit-scrollbar-thumb {
  background: rgba(100, 116, 139, .35);
  border-radius: 4px;
}
.chat-messages > .message.user .bubble::-webkit-scrollbar-thumb:hover {
  background: rgba(100, 116, 139, .55);
}

/* The .content inside the bubble must wrap aggressively so pasted code,
   long URLs and giant words don't force the bubble wider. */
.chat-messages > .message.user .bubble .content {
  white-space: pre-wrap;
  word-break: break-word;
  overflow-wrap: anywhere;
}

/* Assistant bubble: also cap any pasted/long preformatted content inside
   a single code block so the chat column never stretches vertically into
   an unscrollable wall of code. */
.chat-messages > .message.assistant .bubble .code-block {
  max-height: 520px;
  display: flex;
  flex-direction: column;
}
.chat-messages > .message.assistant .bubble .code-block pre {
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: auto;
  max-height: 460px;
}

/* ---------- 2. Sidebar gap between New-chat and Recent-chats ---------- */
.chat-sidebar .sidebar-gap {
  height: 14px;
  flex-shrink: 0;
}

/* ---------- 3. Sidebar inner toggle (ChatGPT-style icon in header) ---------- */
.chat-sidebar .sidebar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.chat-sidebar .sidebar-inner-toggle {
  background: transparent;
  border: none;
  color: var(--text-muted);
  width: 30px;
  height: 30px;
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 1.05rem;
  transition: background .15s ease, color .15s ease, transform .12s ease;
  flex-shrink: 0;
}
.chat-sidebar .sidebar-inner-toggle:hover {
  background: var(--brand-light);
  color: var(--text-dark);
}
.chat-sidebar .sidebar-inner-toggle:active { transform: scale(.94); }

/* Hide the OLD floating arrow on the right edge of the sidebar.
   Collapsing is now handled by the inner toggle inside the header. */
.sidebar-toggle-btn {
  display: none !important;
}

/* When the sidebar is collapsed, expose a small reopen handle on the
   far left of the chat area so the user can bring the sidebar back. */
.chat-sidebar.collapsed ~ .sidebar-reopen-btn,
body:has(.chat-sidebar.collapsed) .sidebar-reopen-btn {
  display: inline-flex;
}
.sidebar-reopen-btn {
  display: none;
  position: absolute;
  top: 14px;
  left: 12px;
  z-index: 60;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text-dark);
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(15,23,42,.10);
  transition: background .15s ease, color .15s ease;
}
.sidebar-reopen-btn:hover {
  background: var(--brand-soft);
  color: var(--brand);
}

/* ---------- 4. Static model-name pill (no dropdown caret) ---------- */
.chat-topbar .model-selector .model-name-static {
  cursor: default;
  pointer-events: none;            /* truly static \u2014 no hover / click effect */
}
.chat-topbar .model-selector .model-name-static::after {
  /* kill the bootstrap dropdown caret triangle */
  display: none !important;
  content: none !important;
}
.chat-topbar .model-selector .model-name-static:hover {
  background: var(--brand-light);
}

/* ---------- Mobile tweaks for the new sidebar header layout ---------- */
@media (max-width: 768px) {
  .chat-sidebar .sidebar-inner-toggle {
    width: 34px;
    height: 34px;
    font-size: 1.1rem;
  }
}

/* ---------- v12: composer textarea hard-cap to prevent runaway growth ---------- */
.composer-inner textarea {
  max-height: 220px;
  overflow-y: auto;
}
.composer-inner textarea::-webkit-scrollbar { width: 8px; }
.composer-inner textarea::-webkit-scrollbar-thumb {
  background: rgba(100, 116, 139, .35);
  border-radius: 4px;
}

/* =====================================================================
   v13 ADDITIONS
   ---------------------------------------------------------------------
   1. Microphone (mic) button inside the composer for voice input
   2. Stop button — replaces the Send arrow while a reply is generating
   3. Smooth fade transition for the thinking-strip label as it cycles
      Thinking… -> Searching the web… -> Giving you the answer…
   ===================================================================== */

/* Mic button (next to attach + send) */
.composer-btn.mic-btn {
  background: transparent;
  border: 0;
  color: var(--text-muted);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all .18s ease;
}
.composer-btn.mic-btn:hover {
  color: var(--brand);
  background: rgba(99, 102, 241, .08);
}
.composer-btn.mic-btn.is-listening {
  color: #ffffff;
  background: #dc2626;
  animation: mic-pulse 1.2s ease-in-out infinite;
}
@keyframes mic-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(220, 38, 38, .55); }
  50%      { box-shadow: 0 0 0 8px rgba(220, 38, 38, 0);  }
}

/* Stop button — same circular shape as the send arrow */
.composer-btn.send.is-stop {
  background: #1f2937;
  color: #ffffff;
  border-color: #1f2937;
}
.composer-btn.send.is-stop:hover {
  background: #111827;
}
body.dark-mode .composer-btn.send.is-stop {
  background: #ececec;
  color: #1a1b1f;
  border-color: #ececec;
}

/* Engagement label fade between Thinking / Searching / Answering */
.thinking-strip .thinking-label.is-fading {
  opacity: 0;
}

/* Live transcript hint while mic is active — v14: wraps long messages */
.mic-hint {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  background: #111827;
  color: #f3f4f6;
  font-size: .78rem;
  font-weight: 500;
  padding: 8px 14px;
  border-radius: 10px;
  white-space: normal;        /* v14: allow wrapping for longer text */
  text-align: center;
  max-width: 320px;
  width: max-content;
  line-height: 1.4;
  pointer-events: none;
  z-index: 50;
  box-shadow: 0 6px 20px rgba(0,0,0,.30);
}
.mic-hint::after {
  /* small caret under the hint */
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: #111827;
}
body.dark-mode .mic-hint {
  background: #f3f4f6;
  color: #111827;
}
body.dark-mode .mic-hint::after {
  border-top-color: #f3f4f6;
}

/* v14: subtle visual cue when voice input is not supported in this browser */
.composer-btn.mic-btn.is-unsupported {
  opacity: 0.5;
  cursor: help;
}
.composer-btn.mic-btn.is-unsupported:hover {
  opacity: 0.85;
  background: rgba(220, 38, 38, .08);
  color: #dc2626;
}
.composer-inner { position: relative; }

/* =====================================================
   v15 ADDITIONS
   1. Run button styling for single-file HTML code blocks
   2. Live HTML preview modal overlay
   ===================================================== */

/* Highlighted "Run" button — sits next to Copy / Download in the
   code-head action row. Uses a brand-accent green to make it obvious
   that this is the action that previews the HTML. */
.message .bubble .code-head .code-btn.run-code-btn {
  background: #16a34a;
  border-color: #16a34a;
  color: #ffffff;
  font-weight: 500;
}
.message .bubble .code-head .code-btn.run-code-btn:hover {
  background: #15803d;
  border-color: #15803d;
  color: #ffffff;
}

/* ----- Live HTML preview overlay ----- */
.html-preview-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .55);
  z-index: 9999;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.html-preview-overlay.is-open { display: flex; }

.html-preview-modal {
  background: var(--bg);
  color: var(--text-dark);
  width: 100%;
  max-width: 1100px;
  height: 88vh;
  border-radius: 14px;
  box-shadow: 0 20px 60px rgba(0,0,0,.45);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--border);
}
.html-preview-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 14px;
  background: var(--sidebar-bg);
  border-bottom: 1px solid var(--border);
}
.html-preview-header .hp-title {
  font-weight: 600;
  font-size: .95rem;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--text-dark);
}
.html-preview-header .hp-title .badge-live {
  background: #16a34a;
  color: #fff;
  font-size: .7rem;
  padding: 2px 8px;
  border-radius: 99px;
  font-weight: 600;
}
.html-preview-actions {
  display: inline-flex;
  gap: 6px;
}
.html-preview-actions .hp-btn {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-dark);
  border-radius: 8px;
  padding: 5px 10px;
  font-size: .82rem;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  transition: all .15s ease;
}
.html-preview-actions .hp-btn:hover {
  background: var(--brand-soft);
  border-color: var(--brand);
}
.html-preview-actions .hp-btn.hp-close {
  background: #dc2626;
  border-color: #dc2626;
  color: #fff;
}
.html-preview-actions .hp-btn.hp-close:hover {
  background: #b91c1c;
  border-color: #b91c1c;
}
.html-preview-iframe-wrap {
  flex: 1;
  background: #ffffff;
  position: relative;
}
.html-preview-iframe-wrap iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
  background: #ffffff;
}

@media (max-width: 720px) {
  .html-preview-overlay { padding: 0; }
  .html-preview-modal { height: 100vh; max-width: 100%; border-radius: 0; }
}

/* =====================================================================
   v25 overrides — full change-set:
   1. Assistant messages no longer carry a logo avatar, so the bubble
      should occupy the full row (no 32px + 12px gap reserved on the
      left where the avatar used to sit).
   2. Like / Dislike buttons PERSIST after click: the chosen one locks
      into a dark / filled state until the user toggles it back off.
   3. Copy button briefly shows a green check after a successful copy,
      then returns to its clipboard icon.
   4. Attachment preview chips stay neatly tucked INSIDE the composer
      (bottom-left corner), no matter how many files the user queues.
   ===================================================================== */

/* 1) Assistant row — no avatar, full-width bubble */
.message.assistant > .bubble {
  max-width: 100%;
}
.message.assistant > .avatar { display: none !important; }

/* 2) Like / Dislike persistent active state */
.message.assistant .bubble .msg-act.is-active {
  color: var(--text-dark);
  background: rgba(0, 0, 0, 0.08);
}
.message.assistant .bubble .msg-act.good-msg-btn.is-active {
  color: #111827;
}
.message.assistant .bubble .msg-act.bad-msg-btn.is-active {
  color: #111827;
}
body.dark-mode .message.assistant .bubble .msg-act.is-active {
  color: #ffffff;
  background: rgba(255, 255, 255, 0.14);
}

/* 3) Copy button success tick */
.message.assistant .bubble .msg-act.is-copied {
  color: var(--success, #16a34a);
}

/* 4) Composer attachment chips — v51.9.1: stacked TOP-TO-BOTTOM in a
      single vertical column so multiple files / images no longer sit
      shoulder-to-shoulder in the composer. Each chip lives on its own
      row, matching the Claude / Genspark uploaded-file preview style. */
.composer-inner .file-preview-strip {
  /* keep the strip clearly INSIDE the composer corner — no outside drift */
  margin: 0;
  padding: 6px 6px 8px;
  align-self: stretch;             /* full width so vertical chips align */
  width: 100%;
  display: flex;
  flex-direction: column;          /* v51.9.1: stack vertically */
  flex-wrap: nowrap;
  gap: 6px;
  overflow-x: hidden;
  overflow-y: auto;                /* scroll VERTICALLY when many files */
  max-height: 220px;               /* room for a few stacked chips */
  scrollbar-width: thin;
}
.composer-inner .file-preview-strip::-webkit-scrollbar { width: 6px; }
.composer-inner .file-preview-strip::-webkit-scrollbar-thumb {
  background: rgba(0,0,0,.18); border-radius: 4px;
}
.composer-inner .file-preview {
  flex-shrink: 0;                  /* keep each chip its natural height */
  align-self: flex-start;          /* each chip stays its natural width on its own row */
}
/* Make sure the chip strip is the FIRST child inside the composer so the
   text input still sits below it (Genspark / ChatGPT corner layout). */
.composer-inner.has-attachments-host {
  flex-direction: column;
  align-items: stretch;
}

/* Thinking strip — slightly larger label so it reads well without an avatar */
.message.assistant.thinking .bubble {
  padding-top: 4px;
}
.thinking-strip .thinking-label {
  font-size: .92rem;
  color: var(--text-muted);
  margin-left: 8px;
  transition: opacity .22s ease;
}
.thinking-strip .thinking-label.is-fading { opacity: 0; }

/* =====================================================================
   v27: MONICA CODE VIEWER — Claude-style split-screen code panel
   ---------------------------------------------------------------------
   The panel lives inside .chat-app alongside the sidebar and main chat
   area. By default it is collapsed to zero width (display:none). When the
   assistant emits any code, the JS adds the class `monica-open` to <body>,
   sliding the panel into view and shrinking the chat-main column so the
   layout splits cleanly into two columns:
     left  ~50–55%   the chat stream
     right ~45–50%   this panel (forced LIGHT theme)

   The panel ALWAYS uses a light theme regardless of the global dark mode
   so generated code is highly readable. We scope every Monica style to
   `.monica-light` so the forced palette never leaks into the rest of the
   chat.
   ===================================================================== */
.monica-panel {
  width: 0;
  flex-shrink: 0;
  background: #1e1f24;
  border-left: 1px solid #2d2f36;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: width .28s cubic-bezier(.4,0,.2,1);
  position: relative;
  z-index: 10;
  color: #e6e6e6;
}
body.monica-open .monica-panel {
  /* v28: narrower side panel so the main chat column stays comfortably
     readable when code files open. ≈ 32–36% of typical viewports. */
  width: clamp(340px, 34vw, 560px);
}

/* ---------- v31: Forced DARK theme palette (scoped to .monica-light) ----
   The class name is kept as `.monica-light` for backward compatibility but
   the colour values now describe a Claude / VS-Code-Dark style panel: a
   near-black background, slate header, soft light text and a blue accent.
   The panel is always dark regardless of the global app theme so generated
   code reads like a real IDE side-panel.                                  */
.monica-light,
.monica-light * {
  color-scheme: dark;
}
.monica-light {
  --m-bg:        #1e1f24;   /* main code background (near-black slate)   */
  --m-bg-soft:   #24262d;   /* viewer / codebar background               */
  --m-bg-head:   #16171b;   /* darker header strip                       */
  --m-border:    #2d2f36;   /* subtle divider                            */
  --m-border-2:  #3a3d46;
  --m-text:      #e6e6e6;   /* soft white code text                      */
  --m-text-soft: #b4b7c0;
  --m-muted:     #8b8e98;
  --m-accent:    #4f9cf9;   /* blue accent for icons / active tab        */
  --m-accent-bg: #1e2a3f;
  --m-success:   #22c55e;
}
.monica-light { background: var(--m-bg); color: var(--m-text); }

/* ---------- Header ---------- */
.monica-panel .monica-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--m-border);
  background: var(--m-bg-head);
  flex-shrink: 0;
}
.monica-panel .monica-title {
  display: inline-flex; align-items: center; gap: 8px;
  font-weight: 600;
  font-size: .92rem;
  color: var(--m-text);
  min-width: 0;
}
.monica-panel .monica-title > i { color: var(--m-accent); font-size: 1.05rem; }
.monica-panel .monica-title-text {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.monica-panel .monica-file-count {
  font-size: .72rem;
  font-weight: 500;
  color: var(--m-text-soft);
  background: rgba(255,255,255,.04);
  border: 1px solid var(--m-border);
  padding: 2px 8px;
  border-radius: 999px;
  white-space: nowrap;
}
.monica-panel .monica-actions {
  display: inline-flex; align-items: center; gap: 6px;
  flex-shrink: 0;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* Generic Monica action button (Copy / Download) */
.monica-panel .monica-act-btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(255,255,255,.04);
  color: var(--m-text);
  border: 1px solid var(--m-border-2);
  border-radius: 8px;
  padding: 6px 10px;
  font-size: .78rem;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  white-space: nowrap;
  transition: background .12s, border-color .12s, color .12s, transform .08s;
}
.monica-panel .monica-act-btn:hover:not(:disabled) {
  background: var(--m-accent-bg);
  border-color: var(--m-accent);
  color: #ffffff;
}
.monica-panel .monica-act-btn:active:not(:disabled) { transform: translateY(1px); }
.monica-panel .monica-act-btn:disabled {
  opacity: .45; cursor: not-allowed;
}
.monica-panel .monica-act-btn.is-success {
  background: var(--m-success);
  border-color: var(--m-success);
  color: #ffffff;
}
.monica-panel .monica-act-btn i { font-size: .9rem; }

/* The ZIP button gets a stronger, primary look so it reads as the
   "main" action in the header. */
.monica-panel .monica-zip-btn {
  background: var(--m-accent);
  color: #ffffff;
  border-color: var(--m-accent);
}
.monica-panel .monica-zip-btn:hover:not(:disabled) {
  background: #1d4ed8;
  border-color: #1d4ed8;
  color: #ffffff;
}

.monica-panel .monica-close-btn {
  width: 30px; height: 30px;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.04);
  border: 1px solid var(--m-border-2);
  border-radius: 8px;
  cursor: pointer;
  color: var(--m-text-soft);
  transition: background .12s, border-color .12s, color .12s;
  margin-left: 4px;
}
.monica-panel .monica-close-btn:hover {
  background: rgba(220, 38, 38, .18);
  border-color: #ef4444;
  color: #ff8585;
}

/* ---------- File-tab strip ---------- */
.monica-panel .monica-tabs {
  display: flex;
  gap: 2px;
  padding: 6px 8px 0 8px;
  background: var(--m-bg-head);
  border-bottom: 1px solid var(--m-border);
  overflow-x: auto;
  overflow-y: hidden;
  flex-shrink: 0;
  scrollbar-width: thin;
}
.monica-panel .monica-tabs::-webkit-scrollbar { height: 6px; }
.monica-panel .monica-tabs::-webkit-scrollbar-thumb { background: #3a3d46; border-radius: 3px; }
.monica-panel .monica-tabs:empty { display: none; }

.monica-panel .monica-tab {
  display: inline-flex; align-items: center; gap: 6px;
  background: transparent;
  border: 1px solid transparent;
  border-bottom: none;
  border-radius: 8px 8px 0 0;
  padding: 7px 12px 8px 12px;
  font-size: .78rem;
  color: var(--m-text-soft);
  cursor: pointer;
  white-space: nowrap;
  font-family: 'JetBrains Mono', 'Fira Mono', ui-monospace, monospace;
  position: relative;
  bottom: -1px;          /* lifts the active tab to overlap the divider */
  transition: background .12s, color .12s, border-color .12s;
  max-width: 240px;
}
.monica-panel .monica-tab > i { font-size: .95rem; color: var(--m-accent); flex-shrink: 0; }
.monica-panel .monica-tab .mt-name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 180px;
}
.monica-panel .monica-tab:hover {
  background: rgba(255,255,255,.06);
  color: var(--m-text);
}
.monica-panel .monica-tab.is-active {
  background: var(--m-bg);
  color: var(--m-text);
  border-color: var(--m-border);
  border-bottom: 1px solid var(--m-bg);
  font-weight: 600;
}

/* ---------- Code viewer ---------- */
.monica-panel .monica-viewer {
  flex: 1;
  overflow: auto;
  background: var(--m-bg);
  position: relative;
}
.monica-panel .monica-empty {
  height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  color: var(--m-muted);
  text-align: center;
  padding: 24px 12px;
}
.monica-panel .monica-empty i { font-size: 2.4rem; opacity: .35; margin-bottom: 10px; }
.monica-panel .monica-empty p { margin: 0; font-size: .88rem; }

.monica-codewrap {
  display: flex;
  flex-direction: column;
  min-height: 100%;
}
.monica-codebar {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 14px;
  background: var(--m-bg-soft);
  border-bottom: 1px solid var(--m-border);
  font-size: .78rem;
  color: var(--m-text-soft);
  flex-shrink: 0;
}
.monica-codebar .mcb-icon i { color: var(--m-accent); }
.monica-codebar .mcb-name {
  flex: 1;
  font-family: 'JetBrains Mono', 'Fira Mono', ui-monospace, monospace;
  color: var(--m-text);
  font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.monica-codebar .mcb-lang {
  font-size: .68rem;
  font-weight: 600;
  color: var(--m-text-soft);
  background: rgba(255,255,255,.04);
  border: 1px solid var(--m-border);
  padding: 2px 8px;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: .03em;
}
.monica-pre {
  margin: 0;
  padding: 14px 16px 24px 16px;
  background: var(--m-bg);
  color: var(--m-text);
  font-family: 'JetBrains Mono', 'Fira Mono', ui-monospace, 'Courier New', monospace;
  font-size: 13px;
  line-height: 1.55;
  white-space: pre;
  overflow-x: auto;
  flex: 1;
  tab-size: 4;
  -moz-tab-size: 4;
}
.monica-pre code {
  background: transparent !important;
  color: inherit !important;
  padding: 0 !important;
  font: inherit !important;
  display: block;
}
.monica-pre::-webkit-scrollbar,
.monica-panel .monica-viewer::-webkit-scrollbar { width: 10px; height: 10px; }
.monica-pre::-webkit-scrollbar-thumb,
.monica-panel .monica-viewer::-webkit-scrollbar-thumb {
  background: #3a3d46; border-radius: 5px; border: 2px solid var(--m-bg);
}
.monica-pre::-webkit-scrollbar-thumb:hover,
.monica-panel .monica-viewer::-webkit-scrollbar-thumb:hover {
  background: #4f535e;
}

/* ---------- v31: highlight.js DARK palette (One Dark / VS-Code-Dark) ---
   Scoped to the Monica side panel only. Each token type has a distinct
   colour so different code categories are visually separated, exactly like
   a real IDE. The base text is soft-white (#e6e6e6) on a near-black slate
   background so reading long files is comfortable.                       */
.monica-light .hljs            { color: #e6e6e6; background: transparent; }
.monica-light .hljs-comment,
.monica-light .hljs-quote      { color: #7c828d; font-style: italic; }
.monica-light .hljs-keyword,
.monica-light .hljs-selector-tag,
.monica-light .hljs-meta-keyword { color: #c678dd; }   /* keywords: purple */
.monica-light .hljs-built_in,
.monica-light .hljs-type,
.monica-light .hljs-class .hljs-title,
.monica-light .hljs-title.class_      { color: #e5c07b; } /* types: gold   */
.monica-light .hljs-string,
.monica-light .hljs-meta-string       { color: #98c379; } /* strings: green*/
.monica-light .hljs-number,
.monica-light .hljs-literal,
.monica-light .hljs-symbol            { color: #d19a66; } /* nums: orange  */
.monica-light .hljs-name,
.monica-light .hljs-attr,
.monica-light .hljs-attribute,
.monica-light .hljs-selector-attr,
.monica-light .hljs-selector-class,
.monica-light .hljs-selector-id,
.monica-light .hljs-tag .hljs-name    { color: #e06c75; } /* tags: coral   */
.monica-light .hljs-function .hljs-title,
.monica-light .hljs-title.function_,
.monica-light .hljs-title             { color: #61afef; } /* funcs: blue   */
.monica-light .hljs-variable,
.monica-light .hljs-template-variable { color: #e06c75; }
.monica-light .hljs-tag,
.monica-light .hljs-tag .hljs-attr    { color: #d19a66; }
.monica-light .hljs-section,
.monica-light .hljs-doctag             { color: #c678dd; }
.monica-light .hljs-regexp             { color: #56b6c2; }
.monica-light .hljs-meta               { color: #56b6c2; }
.monica-light .hljs-emphasis           { font-style: italic; }
.monica-light .hljs-strong             { font-weight: 700; }

/* ---------- v31: Force the DARK palette even on a light page -----------
   The Monica panel is always dark, regardless of the page theme, so the
   IDE feel is consistent. Each surface is pinned to its dark token below. */
body:not(.dark-mode) .monica-panel,
body:not(.dark-mode) .monica-panel .monica-pre,
body:not(.dark-mode) .monica-panel .monica-viewer {
  background-color: #1e1f24 !important;
  color: #e6e6e6 !important;
  border-color: #2d2f36 !important;
}
body:not(.dark-mode) .monica-panel .monica-head,
body:not(.dark-mode) .monica-panel .monica-tabs {
  background-color: #16171b !important;
  color: #e6e6e6 !important;
  border-color: #2d2f36 !important;
}
body:not(.dark-mode) .monica-panel .monica-tab {
  color: #b4b7c0 !important;
}
body:not(.dark-mode) .monica-panel .monica-tab.is-active {
  background-color: #1e1f24 !important;
  color: #ffffff !important;
  border-color: #2d2f36 !important;
  border-bottom: 1px solid #1e1f24 !important;
}
body:not(.dark-mode) .monica-panel .monica-act-btn,
body:not(.dark-mode) .monica-panel .monica-close-btn {
  background-color: rgba(255,255,255,.04) !important;
  color: #e6e6e6 !important;
  border-color: #3a3d46 !important;
}
body:not(.dark-mode) .monica-panel .monica-zip-btn {
  background-color: #2563eb !important;
  color: #ffffff !important;
  border-color: #2563eb !important;
}
body:not(.dark-mode) .monica-panel .monica-act-btn.is-success {
  background-color: #22c55e !important;
  color: #ffffff !important;
  border-color: #22c55e !important;
}
body:not(.dark-mode) .monica-panel .monica-codebar {
  background-color: #24262d !important;
  color: #b4b7c0 !important;
  border-color: #2d2f36 !important;
}
body:not(.dark-mode) .monica-panel .monica-codebar .mcb-name {
  color: #e6e6e6 !important;
}

/* ---------- Responsive ------------------------------------------------
   On small screens, slide the Monica panel OVER the chat instead of
   squeezing the chat column so the chat stays readable.                */
@media (max-width: 900px) {
  .monica-panel {
    position: absolute;
    top: 0; right: 0; bottom: 0;
    width: 0;
    box-shadow: -8px 0 24px rgba(0,0,0,.18);
  }
  body.monica-open .monica-panel {
    width: min(96vw, 560px);
  }
  .monica-panel .monica-actions { gap: 4px; }
  .monica-panel .monica-act-btn { padding: 6px 8px; font-size: .72rem; }
  .monica-panel .monica-act-btn span { display: none; }   /* icon-only on phones */
  .monica-panel .monica-zip-btn span { display: inline; } /* keep the ZIP label */
}

/* =====================================================================
   v27: Hide the user-message avatar globally so the chat surface is a
   clean bubble-only view (Claude-style). Combined with v25's assistant
   avatar removal, neither side carries an avatar circle now.
   ===================================================================== */
.chat-messages .message.user > .avatar,
.chat-messages .message.user .avatar {
  display: none !important;
}

/* =====================================================================
   v29: Static 'Builder 2.0 Pro' model label in the chat top bar.
   This replaces the previous dropdown. It is intentionally NOT a
   <select> or a clickable trigger — it is a plain pill of text so the
   user can see which model is in use but cannot change it from the UI.
   The actual model is still configured server-side from the admin panel
   (API & Model Settings).
   ===================================================================== */
.chat-topbar-model {
  display: inline-flex;
  align-items: center;
}
.chat-topbar-model .model-name-static {
  display: inline-flex;
  align-items: center;
  padding: 6px 14px;
  background: var(--brand-light);
  color: var(--text-dark);
  border-radius: 999px;
  font-weight: 600;
  font-size: .9rem;
  letter-spacing: .1px;
  user-select: none;          /* not interactive */
  cursor: default;            /* not a dropdown */
  pointer-events: none;       /* makes it 100% clear: no click affordance */
  border: 1px solid var(--border);
}

/* =====================================================================
   v29: '+' button popup menu (ChatGPT-style) anchored to the composer.
   Two items:
     • File Upload         — opens the underlying multi-file picker
     • Web Search (toggle) — ON by default, persisted in localStorage,
                             and sent to the server as the form field
                             `web_search` (0 or 1) on every submit.
   Background uses a soft DARK GREY (not pure black) per product spec
   so the popup stays readable on both light and dark themes.
   ===================================================================== */
.plus-menu-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.composer-btn.plus-btn {
  /* match the existing composer-btn sizing so the row stays aligned */
  font-weight: 600;
}
/* v30: '+' popup menu now follows the page theme.
        - Light theme: white card with soft border, dark text (matches chat).
        - Dark theme : dark card so it stays readable in dark mode.
   The popup is anchored to the '+' button and floats just above it. */
.plus-menu {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 0;
  min-width: 240px;
  padding: 6px;
  background: var(--bg);
  color: var(--text-dark);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 12px 32px rgba(15, 23, 42, .12);
  display: none;
  z-index: 1000;
}
.plus-menu.open {
  display: block;
}
.plus-menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 12px;
  background: transparent;
  border: 0;
  border-radius: 8px;
  color: var(--text-dark);
  font-size: .92rem;
  text-align: left;
  cursor: pointer;
}
.plus-menu-item:hover {
  background: var(--brand-soft);
}
.plus-menu-item i {
  font-size: 1.05rem;
  color: var(--text-muted);
  opacity: .95;
}
.plus-menu-item .plus-menu-label {
  flex: 1;
}
/* Web Search small ON/OFF pill toggle on the right side of the row */
.plus-menu-toggle {
  width: 32px;
  height: 18px;
  border-radius: 999px;
  background: #cbd0d8;          /* OFF look — soft grey on light bg */
  position: relative;
  flex-shrink: 0;
  transition: background .15s ease;
}
.plus-menu-toggle-dot {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 2px rgba(0,0,0,.15);
  transition: transform .15s ease;
}
.plus-menu-item[aria-checked="true"] .plus-menu-toggle {
  background: #16a34a;          /* ON = green */
}
.plus-menu-item[aria-checked="true"] .plus-menu-toggle-dot {
  transform: translateX(14px);
}

/* Dark-theme override — keep the popup readable on a dark page. */
body.dark-mode .plus-menu {
  background: #2a2b32;
  color: #ECECEC;
  border-color: #3a3c42;
  box-shadow: 0 12px 32px rgba(0,0,0,.45);
}
body.dark-mode .plus-menu-item        { color: #ECECEC; }
body.dark-mode .plus-menu-item:hover  { background: rgba(255,255,255,.06); }
body.dark-mode .plus-menu-item i      { color: #cbd0d8; }
body.dark-mode .plus-menu-toggle      { background: #5a5d66; }
body.dark-mode .plus-menu-item[aria-checked="true"] .plus-menu-toggle { background: #2f8f4d; }

/* =====================================================================
   v30: GENSPARK-STYLE IMAGE ATTACHMENT PREVIEW
   ---------------------------------------------------------------------
   When the user attaches an image (via picker, drag-drop OR clipboard
   paste) the chip in the composer is now a BIG thumbnail tile (similar
   to Genspark / ChatGPT) instead of a tiny 36×36px icon. Clicking the
   thumb opens a fullscreen lightbox so the user can verify the image
   before sending. Non-image file chips stay compact — only IMAGE chips
   get the larger preview.
   ===================================================================== */
.file-preview.file-preview-image {
  padding: 6px 8px 6px 6px;
  max-width: 280px;
  flex-direction: row;
  align-items: center;
  gap: 8px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 12px;
  position: relative;
}
.file-preview.file-preview-image .file-thumb {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  background: var(--brand-light);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  cursor: zoom-in;
}
.file-preview.file-preview-image .file-thumb:hover {
  opacity: .85;
}
.file-preview.file-preview-image .file-thumb-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.file-preview.file-preview-image .file-meta {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
  min-width: 0;
  max-width: 180px;
}
.file-preview.file-preview-image .file-meta .fname {
  font-size: .82rem;
  font-weight: 600;
  color: var(--text-dark);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.file-preview.file-preview-image .file-meta .fsize {
  font-size: .75rem;
  color: var(--text-muted);
}
.file-preview.file-preview-image .remove-file {
  position: relative;
  top: auto;
  right: auto;
  margin-left: 4px;
  width: 22px;
  height: 22px;
  background: rgba(0,0,0,.06);
  color: var(--text-dark);
  border-radius: 50%;
  z-index: 2;
  border: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: .75rem;
  cursor: pointer;
  flex-shrink: 0;
}
.file-preview.file-preview-image .remove-file:hover {
  background: #dc2626;
  color: #fff;
}

/* =====================================================================
   v30: IMAGE LIGHTBOX (full-size preview)
   Opened from a click on the attachment thumb or on a sent-image link.
   ===================================================================== */
.img-lightbox-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .85);
  z-index: 10000;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.img-lightbox-overlay.is-open { display: flex; }
.img-lightbox-frame {
  position: relative;
  max-width: 92vw;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.img-lightbox-frame img {
  max-width: 92vw;
  max-height: 80vh;
  border-radius: 8px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, .55);
  object-fit: contain;
  background: #111;
}
.img-lightbox-name {
  color: #f1f1f3;
  font-size: .9rem;
  text-align: center;
  max-width: 92vw;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.img-lightbox-close {
  position: absolute;
  top: -42px;
  right: -4px;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .15);
  color: #fff;
  border: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  transition: background .15s ease, transform .12s ease;
}
.img-lightbox-close:hover {
  background: rgba(255, 255, 255, .25);
  transform: scale(1.05);
}
@media (max-width: 600px) {
  .img-lightbox-close { top: -38px; right: 0; }
  .img-lightbox-frame img { max-height: 70vh; }
}

/* =====================================================================
   v31: BIG inline image tile inside the SENT user message bubble.
   ---------------------------------------------------------------------
   When the user attaches an image and sends it, the image appears as a
   large card (Genspark-style) right below the message text instead of a
   small paperclip + filename link. Clicking opens the full-size lightbox.
   This applies BOTH to freshly-sent messages (via JS appendMessage) AND
   to messages reloaded from history (rendered in chat.php).
   ===================================================================== */
/* v32: Genspark-style image attachment tile.
   Larger preview (up to ~380px wide), full image visible (contain instead
   of cover so no edges are cropped), crisp rendering, a visible zoom
   indicator overlay, and a clearer filename strip. Clicking opens the
   full-size lightbox. */
.message .sent-image-tile {
  position: relative;
  display: block;
  margin-top: 8px;
  /* v50.8: uploaded / sent image tile now caps at 560px (same as the
     generated-image card) so both live comfortably inside the 740px
     composer column, and neither looks cramped nor overflows. */
  max-width: 560px;
  width: 100%;
  border-radius: 14px;
  border: 1px solid var(--border);
  background: var(--bg);
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(15, 23, 42, .06);
  cursor: zoom-in;
  transition: transform .12s ease, box-shadow .12s ease;
}
.message .sent-image-tile:hover {
  transform: translateY(-1px);
  box-shadow: 0 8px 22px rgba(15, 23, 42, .14);
}
.message .sent-image-tile img {
  display: block;
  width: 100%;
  max-width: 560px;      /* v50.8: matches the tile cap above */
  height: auto;
  max-height: 500px;     /* v50.8: taller cap so 9:16 portraits look right */
  /* v51.5: cover (not contain) so the image fills the whole tile edge-to-edge
     with no dead colored strip on the sides. Cleaner, ChatGPT/Genspark-style. */
  object-fit: cover;
  background: #ffffff;
  image-rendering: -webkit-optimize-contrast;
}
/* v50.8: on narrow screens the tile fills the bubble width. */
@media (max-width: 560px) {
  .message .sent-image-tile { max-width: 100%; }
  .message .sent-image-tile img { max-width: 100%; max-height: 380px; }
}
body.dark-mode .message .sent-image-tile img { background: #1c1d22; }

/* v51.5: cleaner sent-image tile — no visible border/shadow frame, no filename
   footer strip, no zoom-icon overlay. The image renders edge-to-edge like a
   normal chat attachment (ChatGPT / Genspark style). */
.message .sent-image-tile {
  border: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
}
.message .sent-image-tile .sent-image-name { display: none !important; }
.message .sent-image-tile::after { display: none !important; }
body.dark-mode .message .sent-image-tile {
  border: 0 !important;
  background: transparent !important;
}
/* v32: subtle hover overlay with a magnifier icon to telegraph that the
   tile is clickable and will open a full-size preview. */
.message .sent-image-tile::after {
  content: "\F4A4"; /* bi-zoom-in */
  font-family: "bootstrap-icons";
  position: absolute;
  top: 8px;
  right: 8px;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: .95rem;
  color: #fff;
  background: rgba(15, 23, 42, .55);
  border-radius: 8px;
  opacity: 0;
  transition: opacity .15s ease;
  pointer-events: none;
}
.message .sent-image-tile:hover::after { opacity: 1; }
.message .sent-image-tile .sent-image-name {
  padding: 8px 12px;
  font-size: .78rem;
  color: var(--text-muted);
  background: var(--bg-soft, var(--bg));
  border-top: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.message .sent-image-tile .sent-image-name i { font-size: .9rem; }

/* User-bubble alignment: tile sits inside the bubble, right-aligned for
   user messages, left-aligned otherwise. */
.message.user .bubble .sent-image-tile { margin-left: auto; }

/* Dark-mode adjustments */
body.dark-mode .message .sent-image-tile {
  background: #2a2b32;
  border-color: #3a3c42;
}
body.dark-mode .message .sent-image-tile .sent-image-name {
  background: #1f2026;
  color: #cbd0d8;
  border-top-color: #3a3c42;
}

/* Compact file (non-image) chip inside the user bubble. */
.message .file-attachment-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  padding: 6px 10px;
  border-radius: 10px;
  background: var(--brand-soft);
  border: 1px solid var(--border);
  font-size: .8rem;
  color: var(--text-dark);
  max-width: 320px;
}
.message .file-attachment-chip .file-thumb-doc {
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 6px; background: var(--bg); color: var(--brand);
  flex-shrink: 0;
}
.message .file-attachment-chip .file-meta { display: flex; flex-direction: column; min-width: 0; }
.message .file-attachment-chip .fname {
  font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 220px;
}
.message .file-attachment-chip .fsize { color: var(--text-muted); font-size: .72rem; }
body.dark-mode .message .file-attachment-chip {
  background: rgba(255,255,255,.05);
  border-color: #3a3c42;
  color: #ECECEC;
}
body.dark-mode .message .file-attachment-chip .file-thumb-doc {
  background: #2a2b32; color: #cbd0d8;
}

/* =====================================================================
   v35: The global floating "Show code" reopen handle has been REMOVED.
   ---------------------------------------------------------------------
   Re-opening the side code panel is now handled by per-message inline
   pills (see .inline-view-all-files-btn below) so EVERY past reply that
   produced code retains its own affordance to re-open the panel — not
   just the most-recent reply, which was the v34 limitation.
   ===================================================================== */

/* =====================================================================
   v33: COMPACT AI-STUDIO STYLE ATTACHMENT CHIPS
   ---------------------------------------------------------------------
   Earlier versions (v30) rendered image attachments as big 220x140 px
   preview tiles. That looked clumsy when several images were queued —
   the chips overflowed the composer and looked nothing like the clean
   little file-cards in Google AI Studio. v33 collapses image chips
   back to the SAME compact shape as document chips:
       [thumb 36x36] [filename + size]            [ X ]
   Clicking the small thumb still opens the full-size lightbox
   (handled in chat.js), so no preview functionality is lost — the
   composer just looks tidy now.
   ===================================================================== */
.file-preview.file-preview-image {
  padding: 6px 8px 6px 6px;
  max-width: 280px;
  flex-direction: row;          /* back to horizontal layout */
  align-items: center;
  gap: 8px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 12px;
  position: relative;
  box-shadow: 0 1px 2px rgba(0,0,0,.04);
}
.file-preview.file-preview-image .file-thumb {
  width: 36px;                  /* small square thumb, just like file chips */
  height: 36px;
  border-radius: 8px;
  background: var(--brand-light);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  cursor: zoom-in;
  transition: transform .15s ease, box-shadow .15s ease;
}
.file-preview.file-preview-image .file-thumb:hover {
  transform: scale(1.05);
  box-shadow: 0 2px 8px rgba(15, 23, 42, .12);
}
.file-preview.file-preview-image .file-thumb-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.file-preview.file-preview-image .file-meta {
  display: flex;
  flex-direction: column;       /* stacked name + size like AI Studio */
  align-items: flex-start;
  justify-content: center;
  line-height: 1.25;
  gap: 0;
  padding: 0;
  min-width: 0;
  max-width: 180px;
  flex: 1;
}
.file-preview.file-preview-image .file-meta .fname {
  font-size: .82rem;
  font-weight: 600;
  color: var(--text-dark);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.file-preview.file-preview-image .file-meta .fsize {
  font-size: .72rem;
  color: var(--text-muted);
  flex-shrink: 0;
  font-weight: 400;
}
.file-preview.file-preview-image .remove-file {
  position: relative;           /* back in the flex flow, NOT floating */
  top: auto;
  right: auto;
  margin-left: 4px;
  width: 22px;
  height: 22px;
  background: rgba(0,0,0,.06);
  color: var(--text-dark);
  border-radius: 50%;
  z-index: 1;
  border: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: .75rem;
  cursor: pointer;
  flex-shrink: 0;
  transition: background .15s, color .15s;
}
.file-preview.file-preview-image .remove-file:hover {
  background: #dc2626;
  color: #fff;
}
body.dark-mode .file-preview.file-preview-image .remove-file {
  background: rgba(255,255,255,.10);
  color: #ECECEC;
}
body.dark-mode .file-preview.file-preview-image .remove-file:hover {
  background: #dc2626;
  color: #fff;
}

/* Strip itself: smaller height now that chips are compact again */
.composer-inner .file-preview-strip {
  max-height: 60px;             /* one row of compact chips */
  padding: 6px 6px 6px;
}

/* =====================================================================
   v33: STOP BUTTON — clearer AI-Studio style indicator
   ---------------------------------------------------------------------
   When the assistant is generating a reply, the Send button becomes a
   Stop button. v32 only changed the colour to dark grey, which made
   the transition almost invisible. v33 adds:
     * a soft red colour (matches recording/active state language)
     * a subtle pulsing ring so the user clearly sees "something is
       running, click to stop"
     * a proper stop-square glyph centred in the button
   Identical visual language to Google AI Studio's circular Stop
   control.
   ===================================================================== */
.composer-btn.send.is-stop {
  background: #1f2937;
  color: #ffffff;
  border-color: #1f2937;
  position: relative;
  animation: hana-stop-pulse 1.6s ease-in-out infinite;
}
.composer-btn.send.is-stop:hover {
  background: #111827;
  animation: none;              /* steady on hover so click feels solid */
}
.composer-btn.send.is-stop .send-btn-inner {
  /* a thin ring around a filled square — classic Stop affordance */
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1.5px solid rgba(255,255,255,.85);
  background: transparent;
  position: relative;
  /* v35: bulletproof click routing — every pointer event on the inner
     ring/icon must bubble up to the BUTTON, never report the span/icon
     as the event target. The previous inline-style fallback occasionally
     dropped on slow first paints, so we lock it down in CSS too. */
  pointer-events: none;
}
.composer-btn.send.is-stop .send-btn-inner * {
  pointer-events: none;
}
.composer-btn.send.is-stop .send-btn-inner i {
  font-size: .85rem;
  line-height: 1;
  color: #fff;
}
@keyframes hana-stop-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(31, 41, 55, .45); }
  50%      { box-shadow: 0 0 0 6px rgba(31, 41, 55, 0);  }
}
body.dark-mode .composer-btn.send.is-stop {
  background: #ececec;
  color: #1a1b1f;
  border-color: #ececec;
}
body.dark-mode .composer-btn.send.is-stop .send-btn-inner {
  border-color: rgba(0,0,0,.75);
}
body.dark-mode .composer-btn.send.is-stop .send-btn-inner i {
  color: #1a1b1f;
}
body.dark-mode .composer-btn.send.is-stop {
  animation-name: hana-stop-pulse-dark;
}
@keyframes hana-stop-pulse-dark {
  0%, 100% { box-shadow: 0 0 0 0 rgba(236, 236, 236, .45); }
  50%      { box-shadow: 0 0 0 6px rgba(236, 236, 236, 0);  }
}

/* ============================================================
   v34 CHANGES
   ============================================================ */

/* v34 (1/4): Attach-only user bubble.
   When the user sends only files (no caption), the bubble no longer
   contains the literal text "(attachment)". The bubble background and
   padding are removed so only the clean file/image tile is visible,
   matching the look of Genspark / ChatGPT / Claude. */
.message.user .bubble.bubble-attach-only {
  background: transparent !important;
  border: 0 !important;
  padding: 0 !important;
  box-shadow: none !important;
}
.message.user .bubble.bubble-attach-only .sent-image-tile,
.message.user .bubble.bubble-attach-only .file-attachment-chip,
.message.user .bubble.bubble-attach-only .attachment {
  margin-top: 0;
}

/* =====================================================================
   v35: Per-message INLINE "View all files in this task" pill.
   ---------------------------------------------------------------------
   In v34 this was a single global floating button pinned to the bottom-
   right of the chat. That had two real problems:
     (1) It tracked only the MOST-RECENT reply's files — there was no
         way to re-open the side panel against an older message in the
         same conversation.
     (2) On page load with a saved chat it stayed visible from the last
         conversation's state, which confused users.
   v35 attaches the pill DIRECTLY to each assistant bubble that produced
   code, so it travels with the message itself (Manus-style). Every past
   reply keeps its own re-open button, scoped to that reply's file set.
   ===================================================================== */
/* v48 — FLAT, ATTACHED pill (Manus-style)
   Sits directly under the assistant bubble, no drop shadow, no float,
   no hover lift. Reads as an inline extension of the bubble itself. */
.inline-view-all-files-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  padding: 7px 12px;
  border-radius: 10px;
  border: 1px solid var(--border, #e5e7eb);
  background: var(--bg, #ffffff);
  color: var(--text-dark, #0f172a);
  font-size: .82rem;
  font-weight: 500;
  cursor: pointer;
  box-shadow: none;
  transition: background .12s ease, border-color .12s ease;
}
.inline-view-all-files-btn:hover {
  background: #f4f6f9;
  border-color: #d5d9e0;
  transform: none;
  box-shadow: none;
}
.inline-view-all-files-btn:active {
  background: #eceff3;
  transform: none;
  box-shadow: none;
}
.inline-view-all-files-btn i { font-size: 1rem; color: var(--text-muted, #64748b); }
.inline-view-all-files-btn .ivaf-label { white-space: nowrap; }
.inline-view-all-files-btn .ivaf-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--accent, #2563eb);
  color: #fff;
  font-size: .7rem;
  font-weight: 600;
}
body.dark-mode .inline-view-all-files-btn {
  background: #2a2b32;
  color: #e7e9ee;
  border-color: #3a3c42;
  box-shadow: none;
}
body.dark-mode .inline-view-all-files-btn:hover {
  background: #33353d;
}
body.dark-mode .inline-view-all-files-btn i { color: #9aa3b2; }
@media (max-width: 640px) {
  .inline-view-all-files-btn {
    padding: 7px 12px;
    font-size: .78rem;
  }
  .inline-view-all-files-btn .ivaf-label { white-space: normal; }
}

/* =====================================================================
   v36 — Sidebar enhancements: Search chats + Chat context menu
   ---------------------------------------------------------------------
   Adds:
     • "Search chats" button (under "New chat") with inline filter input
     • Three-dot context menu on each chat (Share / Rename / Pin /
       Archive / Delete)
     • Archived section toggle at the bottom of the chat list
     • Minimal modal (rename + share dialogs) — light + dark theme aware
   All other v35 styles are untouched.
   ===================================================================== */

/* ---- Search chats button (matches New chat button shape, but quieter) ---- */
.chat-sidebar .search-chats-btn {
  margin: 0 10px 4px;
  background: transparent;
  color: var(--text-dark);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 10px;
  min-height: 32px;
  font-size: .82rem;
  font-weight: 500;
  display: flex; align-items: center; gap: 8px;
  width: calc(100% - 20px);
  cursor: pointer;
  transition: background .15s, border-color .15s, transform .15s;
}
.chat-sidebar .search-chats-btn i { font-size: .85rem; color: var(--text-muted); }
.chat-sidebar .search-chats-btn:hover {
  background: var(--brand-soft);
  border-color: var(--text-muted);
}
.chat-sidebar .search-chats-btn[aria-expanded="true"] {
  background: var(--brand-soft);
  border-color: var(--brand);
}

/* ---- Inline search input that appears when the button is expanded ---- */
.chat-sidebar .search-chats-box {
  margin: 0 10px 6px;
  display: flex; align-items: center; gap: 8px;
  background: var(--brand-soft-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 10px;
  width: calc(100% - 20px);
}
.chat-sidebar .search-chats-box i.bi-search {
  font-size: .85rem; color: var(--text-muted);
}
.chat-sidebar .search-chats-box input {
  border: 0; outline: 0; background: transparent;
  flex: 1; font-size: .85rem; color: var(--text-dark);
  padding: 2px 0;
}
.chat-sidebar .search-chats-box input::placeholder { color: var(--text-muted); }
.chat-sidebar .search-chats-clear {
  background: transparent; border: 0; color: var(--text-muted);
  padding: 2px 4px; border-radius: 4px; cursor: pointer; font-size: .78rem;
}
.chat-sidebar .search-chats-clear:hover { background: var(--border); color: var(--text-dark); }

/* ---- History item — keep existing layout, add pin icon + menu button ---- */
.chat-sidebar .history-item .chat-pin-icon {
  font-size: .78rem;
  color: var(--brand);
  margin-right: 4px;
  flex-shrink: 0;
  opacity: .8;
}
.chat-sidebar .history-item .chat-title-text {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chat-sidebar .history-item .chat-menu-btn {
  opacity: 0;
  background: transparent;
  border: 0;
  color: var(--text-muted);
  font-size: .9rem;
  padding: 2px 6px;
  border-radius: 4px;
  cursor: pointer;
  transition: opacity .15s, background .15s, color .15s;
  flex-shrink: 0;
}
.chat-sidebar .history-item:hover .chat-menu-btn,
.chat-sidebar .history-item.active .chat-menu-btn,
.chat-sidebar .history-item .chat-menu-btn[aria-expanded="true"] {
  opacity: 1;
}
.chat-sidebar .history-item .chat-menu-btn:hover {
  background: rgba(0, 0, 0, .08);
  color: var(--text-dark);
}
html.dark .chat-sidebar .history-item .chat-menu-btn:hover {
  background: rgba(255, 255, 255, .08);
}

/* Hide search-filtered items */
.chat-sidebar .history-item.search-hidden,
.chat-sidebar .archived-toggle.search-hidden {
  display: none !important;
}

/* ---- Archived section ---- */
.chat-sidebar .archived-toggle {
  margin: 14px 6px 4px;
  padding: 6px 10px;
  display: flex; align-items: center; gap: 8px;
  border-radius: 6px;
  font-size: .8rem;
  color: var(--text-muted);
  cursor: pointer;
  user-select: none;
  transition: background .15s;
}
.chat-sidebar .archived-toggle:hover { background: var(--brand-soft); color: var(--text-dark); }
.chat-sidebar .archived-toggle .archived-chev { transition: transform .15s; font-size: .7rem; }
.chat-sidebar .archived-toggle.is-open .archived-chev { transform: rotate(90deg); }
.chat-sidebar .history-item.is-archived { opacity: .85; }

/* =====================================================================
   Chat context menu — floating popover next to the three-dots button
   ===================================================================== */
.chat-context-menu {
  position: fixed;
  z-index: 9999;
  min-width: 200px;
  background: #ffffff;
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 12px 32px rgba(15, 23, 42, .14), 0 2px 6px rgba(15, 23, 42, .06);
  padding: 6px;
  font-size: .9rem;
  animation: ccm-pop-in .12s ease-out;
}
html.dark .chat-context-menu {
  background: #2a2b32;
  border-color: #3a3b42;
  box-shadow: 0 16px 40px rgba(0, 0, 0, .55), 0 2px 6px rgba(0, 0, 0, .3);
}
@keyframes ccm-pop-in {
  from { opacity: 0; transform: translateY(-2px) scale(.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.chat-context-menu .ccm-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  background: transparent;
  border: 0;
  color: var(--text-dark);
  padding: 8px 10px;
  border-radius: 8px;
  font-size: .9rem;
  text-align: left;
  cursor: pointer;
  transition: background .12s, color .12s;
}
.chat-context-menu .ccm-item i {
  font-size: .95rem; color: var(--text-muted); width: 16px; text-align: center;
}
.chat-context-menu .ccm-item:hover {
  background: var(--brand-soft);
}
html.dark .chat-context-menu .ccm-item:hover { background: #3a3b42; }
.chat-context-menu .ccm-item.ccm-danger { color: #dc2626; }
.chat-context-menu .ccm-item.ccm-danger i { color: #dc2626; }
.chat-context-menu .ccm-item.ccm-danger:hover { background: rgba(220, 38, 38, .08); }
html.dark .chat-context-menu .ccm-item.ccm-danger:hover { background: rgba(220, 38, 38, .15); }
.chat-context-menu .ccm-divider {
  height: 1px; background: var(--border); margin: 6px 4px;
}

/* =====================================================================
   Minimal modal (Rename / Share)
   ===================================================================== */
.hana-modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(15, 23, 42, .42);
  z-index: 10000;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  animation: hmb-fade-in .15s ease-out;
}
@keyframes hmb-fade-in { from { opacity: 0; } to { opacity: 1; } }
.hana-modal {
  background: #ffffff;
  border-radius: 16px;
  width: 100%; max-width: 460px;
  box-shadow: 0 24px 64px rgba(15, 23, 42, .25);
  overflow: hidden;
  animation: hm-slide-in .16s ease-out;
}
html.dark .hana-modal {
  background: #2a2b32; color: var(--text-dark);
}
@keyframes hm-slide-in { from { transform: translateY(8px); opacity: .85; } to { transform: translateY(0); opacity: 1; } }
.hana-modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
}
.hana-modal-head h3 { margin: 0; font-size: 1.05rem; font-weight: 600; color: var(--text-dark); }
.hana-modal-close {
  background: transparent; border: 0; color: var(--text-muted);
  font-size: 1rem; padding: 4px 8px; border-radius: 6px; cursor: pointer;
}
.hana-modal-close:hover { background: var(--brand-soft); color: var(--text-dark); }
html.dark .hana-modal-close:hover { background: #3a3b42; }
.hana-modal-body {
  padding: 20px;
  font-size: .92rem;
  color: var(--text-dark);
  line-height: 1.55;
}
.hana-modal-body label {
  display: block; font-size: .82rem; color: var(--text-muted); margin-bottom: 6px; font-weight: 500;
}
.hana-modal-body .hm-input {
  width: 100%; box-sizing: border-box;
  padding: 10px 12px;
  border: 1.5px solid var(--border);
  border-radius: 10px;
  font-size: .95rem;
  background: var(--brand-soft-2);
  color: var(--text-dark);
  outline: 0;
  transition: border-color .15s, box-shadow .15s;
}
.hana-modal-body .hm-input:focus {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(99, 102, 241, .12);
}
.hana-modal-body .hm-share-row {
  display: flex; gap: 8px; align-items: stretch; margin-top: 4px;
}
.hana-modal-body .hm-share-row .hm-input { flex: 1; font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-size: .85rem; }
.hana-modal-body .hm-help { font-size: .82rem; color: var(--text-muted); margin-top: 10px; }
.hana-modal-foot {
  display: flex; align-items: center; justify-content: flex-end; gap: 8px;
  padding: 12px 20px 18px;
  border-top: 1px solid var(--border);
  background: var(--brand-soft-2);
}
.hana-modal-foot .hm-btn {
  padding: 8px 16px;
  border-radius: 8px;
  font-size: .88rem; font-weight: 500;
  border: 1.5px solid var(--border);
  background: #ffffff;
  color: var(--text-dark);
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s, transform .1s;
}
html.dark .hana-modal-foot .hm-btn { background: #3a3b42; border-color: #4a4b52; }
.hana-modal-foot .hm-btn:hover { background: var(--brand-soft); transform: translateY(-1px); }
.hana-modal-foot .hm-btn-primary {
  background: var(--brand);
  border-color: var(--brand);
  color: #ffffff;
}
html.dark .hana-modal-foot .hm-btn-primary { color: #111827; }
.hana-modal-foot .hm-btn-primary:hover { background: var(--brand-dark); border-color: var(--brand-dark); }
.hana-modal-foot .hm-btn-danger {
  background: #dc2626; border-color: #dc2626; color: #ffffff;
}
.hana-modal-foot .hm-btn-danger:hover { background: #b91c1c; border-color: #b91c1c; }

/* Tiny toast for "Link copied" feedback */
.hana-toast {
  position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
  background: #0f172a; color: #ffffff;
  padding: 10px 18px; border-radius: 10px;
  font-size: .88rem; font-weight: 500;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .25);
  z-index: 10001;
  opacity: 0; pointer-events: none;
  transition: opacity .2s, transform .2s;
}
.hana-toast.is-show { opacity: 1; transform: translateX(-50%) translateY(-4px); }
html.dark .hana-toast { background: #e5e7eb; color: #111827; }

/* =====================================================================
   v47: MANUS-STYLE FILE EXPLORER MODAL
   ---------------------------------------------------------------------
   A centered white popup (LIGHT theme, forced) that fully replaces the
   old right-side Monica panel. Opens only when the user clicks the
   "View all files in this task" pill above an assistant reply.
   Layout: file tree on the left, syntax-highlighted preview on the right.
   ===================================================================== */

/* --- kill the old Monica right-side panel so it never leaks in --- */
.monica-panel { display: none !important; }
body.monica-open { /* no side-effect layout change any more */ }

.mfe-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, .45);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 10050;
  padding: 24px;
  animation: mfeFadeIn .18s ease;
}
.mfe-overlay.is-open { display: flex; }
@keyframes mfeFadeIn { from { opacity: 0; } to { opacity: 1; } }

.mfe-modal {
  width: min(1080px, 96vw);
  height: min(680px, 88vh);
  background: #ffffff;
  color: #1a1c2c;
  border-radius: 14px;
  box-shadow: 0 32px 80px rgba(15, 23, 42, .38), 0 4px 12px rgba(15, 23, 42, .18);
  border: 1px solid #e5e7eb;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: mfePopIn .22s cubic-bezier(.4, 0, .2, 1);
  color-scheme: light;
}
.mfe-overlay.is-fullscreen .mfe-modal {
  width: 96vw;
  height: 94vh;
}
@keyframes mfePopIn {
  from { transform: scale(.96) translateY(6px); opacity: 0; }
  to   { transform: scale(1) translateY(0); opacity: 1; }
}

/* Force light palette inside the modal regardless of app dark mode */
.mfe-modal, .mfe-modal * { color-scheme: light; }
html.dark .mfe-modal,
body.dark-mode .mfe-modal {
  background: #ffffff;
  color: #1a1c2c;
}

/* -------- Header -------- */
.mfe-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px 10px 18px;
  border-bottom: 1px solid #e5e7eb;
  background: #fafafa;
  flex-shrink: 0;
}
.mfe-title {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-weight: 600;
  font-size: .95rem;
  color: #1a1c2c;
  min-width: 0;
}
.mfe-title > i {
  color: #f59e0b;
  font-size: 1.15rem;
  flex-shrink: 0;
}
.mfe-title-text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 60vw;
}
.mfe-actions {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  position: relative;
  flex-shrink: 0;
}
.mfe-act-btn,
.mfe-close-btn {
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 8px;
  color: #4b5563;
  cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.mfe-act-btn:hover,
.mfe-close-btn:hover {
  background: #f1f5f9;
  color: #0f172a;
  border-color: #e5e7eb;
}
.mfe-act-btn i,
.mfe-close-btn i { font-size: 1rem; }

/* Overflow menu ("...") */
.mfe-menu {
  position: absolute;
  top: 40px;
  right: 40px;
  min-width: 220px;
  background: #ffffff;
  border: 1px solid #e5e7eb;
  border-radius: 10px;
  box-shadow: 0 12px 32px rgba(15, 23, 42, .18);
  padding: 6px;
  z-index: 5;
}
.mfe-menu[hidden] { display: none; }
.mfe-menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  background: transparent;
  border: none;
  border-radius: 6px;
  font-size: .86rem;
  color: #1a1c2c;
  text-align: left;
  cursor: pointer;
  transition: background .12s;
}
.mfe-menu-item:hover { background: #f1f5f9; }
.mfe-menu-item i { color: #64748b; font-size: 1rem; }

/* -------- Body -------- */
.mfe-body {
  flex: 1;
  min-height: 0;
  display: flex;
}

/* File tree column */
.mfe-tree {
  width: 260px;
  flex-shrink: 0;
  border-right: 1px solid #e5e7eb;
  background: #fafafa;
  overflow-y: auto;
  padding: 10px 6px 14px 6px;
  font-size: .85rem;
}
.mfe-tree::-webkit-scrollbar { width: 8px; }
.mfe-tree::-webkit-scrollbar-thumb { background: #d1d5db; border-radius: 4px; }

.mfe-tree-node {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 8px;
  border-radius: 6px;
  cursor: pointer;
  color: #1a1c2c;
  user-select: none;
  transition: background .1s;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mfe-tree-node:hover { background: #eef2f7; }
.mfe-tree-node.is-active {
  background: #e0e7ff;
  color: #1e3a8a;
  font-weight: 500;
}
.mfe-tree-node .caret {
  width: 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: .7rem;
  color: #6b7280;
  transition: transform .15s;
  flex-shrink: 0;
}
.mfe-tree-node.is-folder .caret::before { content: "▸"; }
.mfe-tree-node.is-folder.is-open .caret::before { content: "▾"; }
.mfe-tree-node.is-file .caret { visibility: hidden; }
.mfe-tree-node > .node-icon {
  font-size: 1rem;
  flex-shrink: 0;
}
.mfe-tree-node.is-folder > .node-icon { color: #f59e0b; }
.mfe-tree-node.is-file   > .node-icon { color: #6b7280; }
.mfe-tree-node .node-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
}
.mfe-tree-children {
  padding-left: 16px;
}
.mfe-tree-children[hidden] { display: none; }

/* Preview column */
.mfe-preview {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  background: #ffffff;
  overflow: hidden;
}
.mfe-empty {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #94a3b8;
  gap: 10px;
  font-size: .9rem;
}
.mfe-empty i { font-size: 2.4rem; opacity: .5; }
.mfe-empty p { margin: 0; }

.mfe-file-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 14px;
  background: #f8fafc;
  border-bottom: 1px solid #e5e7eb;
  font-size: .82rem;
  color: #475569;
  flex-shrink: 0;
}
.mfe-file-header .mfh-name {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: 'JetBrains Mono', 'Fira Mono', ui-monospace, monospace;
  color: #1a1c2c;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mfe-file-header .mfh-name i { color: #64748b; }
.mfe-file-header .mfh-lang {
  font-size: .68rem;
  font-weight: 600;
  color: #475569;
  background: #e2e8f0;
  padding: 2px 8px;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: .03em;
}
.mfe-file-header .mfh-download {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border-radius: 6px;
  background: #2563eb;
  color: #ffffff;
  text-decoration: none;
  font-size: .78rem;
  font-weight: 500;
  border: none;
  cursor: pointer;
  transition: background .12s;
}
.mfe-file-header .mfh-download:hover { background: #1d4ed8; color: #ffffff; }
.mfe-file-header .mfh-download i { font-size: .9rem; }

.mfe-code {
  flex: 1;
  overflow: auto;
  margin: 0;
  padding: 14px 16px 24px 16px;
  background: #ffffff;
  color: #1f2937;
  font-family: 'JetBrains Mono', 'Fira Mono', ui-monospace, 'Courier New', monospace;
  font-size: 13px;
  line-height: 1.6;
  white-space: pre;
  tab-size: 4;
  -moz-tab-size: 4;
}
.mfe-code code {
  background: transparent !important;
  color: inherit !important;
  padding: 0 !important;
  font: inherit !important;
  display: block;
}
.mfe-code::-webkit-scrollbar { width: 10px; height: 10px; }
.mfe-code::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 5px; }
.mfe-code::-webkit-scrollbar-thumb:hover { background: #94a3b8; }

/* Light-mode syntax highlighting inside the modal (GitHub-ish) */
.mfe-code .hljs               { color: #1f2937; background: transparent; }
.mfe-code .hljs-comment,
.mfe-code .hljs-quote         { color: #6a737d; font-style: italic; }
.mfe-code .hljs-keyword,
.mfe-code .hljs-selector-tag,
.mfe-code .hljs-meta-keyword  { color: #d73a49; }
.mfe-code .hljs-built_in,
.mfe-code .hljs-type,
.mfe-code .hljs-class .hljs-title,
.mfe-code .hljs-title.class_  { color: #6f42c1; }
.mfe-code .hljs-string,
.mfe-code .hljs-meta-string   { color: #032f62; }
.mfe-code .hljs-number,
.mfe-code .hljs-literal,
.mfe-code .hljs-symbol        { color: #005cc5; }
.mfe-code .hljs-name,
.mfe-code .hljs-attr,
.mfe-code .hljs-selector-attr,
.mfe-code .hljs-selector-class,
.mfe-code .hljs-selector-id,
.mfe-code .hljs-tag .hljs-name { color: #22863a; }
.mfe-code .hljs-function .hljs-title,
.mfe-code .hljs-title.function_,
.mfe-code .hljs-title         { color: #6f42c1; }
.mfe-code .hljs-variable,
.mfe-code .hljs-template-variable { color: #e36209; }
.mfe-code .hljs-tag,
.mfe-code .hljs-tag .hljs-attr { color: #22863a; }
.mfe-code .hljs-section,
.mfe-code .hljs-doctag         { color: #d73a49; }
.mfe-code .hljs-regexp         { color: #032f62; }
.mfe-code .hljs-meta           { color: #6a737d; }

/* Responsive */
@media (max-width: 720px) {
  .mfe-overlay { padding: 8px; }
  .mfe-modal   { width: 100vw; height: 100vh; border-radius: 8px; }
  .mfe-tree    { width: 180px; font-size: .8rem; }
  .mfe-title-text { max-width: 40vw; font-size: .85rem; }
}

/* v47: keep the "View all files in this task" pill at the TOP of the
   assistant bubble (moved above the reply content, not below it). */
.bubble .inline-view-all-files-btn {
  margin-top: 0;
  margin-bottom: 10px;
  display: inline-flex;
}
.bubble .inline-view-all-files-btn + .content,
.bubble .inline-view-all-files-btn + * {
  margin-top: 0;
}

/* =====================================================================
   v50: CREATE IMAGE MODAL
   ---------------------------------------------------------------------
   A centered, elegant popup opened from the '+' composer menu.
   Contains: model picker, aspect-ratio picker, prompt box, live INR
   pricing, and a Generate button. Matches the light/dark themes of the
   rest of the app.
   ===================================================================== */
.cig-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.55);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 12000;
  padding: 24px;
  animation: cigFade .18s ease;
}
.cig-overlay.open { display: flex; }
@keyframes cigFade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.cig-modal {
  width: 100%;
  max-width: 640px;
  max-height: calc(100vh - 48px);
  background: #ffffff;
  color: #0f172a;
  border-radius: 18px;
  box-shadow: 0 24px 60px rgba(15, 23, 42, .28), 0 2px 10px rgba(15,23,42,.10);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  animation: cigPop .22s cubic-bezier(.2,.9,.3,1.15);
}
@keyframes cigPop {
  from { transform: translateY(14px) scale(.97); opacity: 0; }
  to   { transform: translateY(0)    scale(1);   opacity: 1; }
}

.cig-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 18px;
  border-bottom: 1px solid #eef1f5;
  background: linear-gradient(180deg, #fafbfc, #ffffff);
}
.cig-head-left { display: flex; align-items: center; gap: 12px; }
.cig-head-icon {
  width: 38px; height: 38px;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, #eef2ff, #e0e7ff);
  color: #4338ca;
  border-radius: 10px;
  font-size: 1.15rem;
}
.cig-title    { margin: 0; font-size: 1.02rem; font-weight: 700; color: #0f172a; }
.cig-subtitle { font-size: .78rem; color: #64748b; margin-top: 1px; }
.cig-close {
  border: 0;
  background: transparent;
  color: #64748b;
  width: 34px; height: 34px;
  border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
.cig-close:hover { background: #f1f5f9; color: #0f172a; }

.cig-body {
  padding: 18px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.cig-label {
  display: block;
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: #475569;
  margin-bottom: 8px;
}

/* -------- Model grid -------- */
.cig-model-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
.cig-model-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 11px 12px 12px;
  border: 1.5px solid #e2e8f0;
  background: #ffffff;
  border-radius: 12px;
  cursor: pointer;
  text-align: left;
  transition: border-color .12s ease, box-shadow .12s ease, background .12s ease;
}
.cig-model-card:hover {
  border-color: #cbd5e1;
  background: #fafbfc;
}
.cig-model-card.active {
  border-color: #4f46e5;
  background: #eef2ff;
  box-shadow: 0 0 0 3px rgba(79, 70, 229, .15);
}
.cig-model-card .m-name {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 700;
  font-size: .92rem;
  color: #0f172a;
}
.cig-model-card .m-sub   { font-size: .74rem; color: #64748b; }
.cig-model-card .m-price {
  margin-top: 4px;
  font-size: .82rem;
  font-weight: 700;
  color: #16a34a;
}
.cig-model-card .m-price .m-usd { color: #94a3b8; font-weight: 500; font-size: .72rem; margin-left: 4px; }
.cig-model-card .m-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  padding: 2px 7px;
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  background: #e0e7ff;
  color: #4338ca;
  border-radius: 999px;
}
.cig-model-card .m-badge.cheapest { background: #dcfce7; color: #166534; }
.cig-model-card .m-badge.premium  { background: #fef3c7; color: #92400e; }
.cig-model-card .m-badge.recommended { background: #ede9fe; color: #6d28d9; }

/* -------- Size / aspect row -------- */
.cig-size-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.cig-size-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  border: 1.5px solid #e2e8f0;
  background: #ffffff;
  color: #334155;
  border-radius: 999px;
  font-size: .82rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color .12s ease, background .12s ease, color .12s ease;
}
.cig-size-btn:hover { border-color: #cbd5e1; background: #fafbfc; }
.cig-size-btn.active {
  border-color: #4f46e5;
  background: #4f46e5;
  color: #ffffff;
}
.cig-size-btn .ar-box {
  display: inline-block;
  border: 1.5px solid currentColor;
  border-radius: 3px;
  opacity: .8;
}

/* -------- Prompt textarea -------- */
.cig-prompt {
  width: 100%;
  padding: 12px 14px;
  border: 1.5px solid #e2e8f0;
  border-radius: 12px;
  font-size: .94rem;
  color: #0f172a;
  background: #ffffff;
  font-family: inherit;
  resize: vertical;
  min-height: 88px;
  outline: none;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.cig-prompt:focus {
  border-color: #4f46e5;
  box-shadow: 0 0 0 3px rgba(79, 70, 229, .15);
}

.cig-hint {
  /* v50.3+: the "Cost: ₹X · N credits" line has been removed from the
     Create Image modal per product decision. The container is hidden
     entirely so no empty band is visible under the prompt textarea. */
  display: none !important;
}
.cig-cost-hint {
  color: #0f172a;
  font-weight: 600;
}
.cig-hint-right { display: none !important; }

.cig-err {
  padding: 10px 12px;
  background: #fef2f2;
  border: 1px solid #fecaca;
  color: #991b1b;
  border-radius: 10px;
  font-size: .85rem;
}

.cig-foot {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  padding: 14px 18px;
  border-top: 1px solid #eef1f5;
  background: #fafbfc;
}
.cig-btn {
  padding: 9px 18px;
  font-size: .9rem;
  font-weight: 600;
  border-radius: 10px;
  border: 1.5px solid transparent;
  cursor: pointer;
  transition: background .12s ease, border-color .12s ease, color .12s ease, transform .06s ease;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.cig-btn:active { transform: translateY(1px); }
.cig-btn-ghost {
  background: #ffffff;
  border-color: #e2e8f0;
  color: #334155;
}
.cig-btn-ghost:hover { background: #f1f5f9; }
.cig-btn-primary {
  background: linear-gradient(135deg, #4f46e5, #6366f1);
  border-color: transparent;
  color: #ffffff;
  box-shadow: 0 6px 16px rgba(79, 70, 229, .28);
}
.cig-btn-primary:hover { filter: brightness(1.05); }
.cig-btn-primary:disabled {
  opacity: .7;
  cursor: not-allowed;
  filter: grayscale(.15);
}
.cig-btn-spinner { display: inline-flex; align-items: center; gap: 8px; }
.cig-spin {
  width: 14px; height: 14px;
  border: 2px solid rgba(255,255,255,.4);
  border-top-color: #ffffff;
  border-radius: 50%;
  display: inline-block;
  animation: cigSpin .7s linear infinite;
}
@keyframes cigSpin { to { transform: rotate(360deg); } }

/* -------- Dark theme -------- */
body.dark-mode .cig-modal {
  background: #1e1f24;
  color: #ececec;
  box-shadow: 0 24px 60px rgba(0,0,0,.55);
}
body.dark-mode .cig-head          { background: linear-gradient(180deg, #23252b, #1e1f24); border-bottom-color: #2f3138; }
body.dark-mode .cig-head-icon     { background: linear-gradient(135deg, #2d2a55, #23213f); color: #a5b4fc; }
body.dark-mode .cig-title         { color: #f8fafc; }
body.dark-mode .cig-subtitle      { color: #94a3b8; }
body.dark-mode .cig-close         { color: #94a3b8; }
body.dark-mode .cig-close:hover   { background: #2a2c33; color: #f8fafc; }
body.dark-mode .cig-label         { color: #94a3b8; }
body.dark-mode .cig-model-card    { background: #23252b; border-color: #2f3138; }
body.dark-mode .cig-model-card:hover { background: #262931; border-color: #40434b; }
body.dark-mode .cig-model-card.active { background: #1f1e3a; border-color: #6366f1; box-shadow: 0 0 0 3px rgba(99,102,241,.22); }
body.dark-mode .cig-model-card .m-name { color: #f8fafc; }
body.dark-mode .cig-model-card .m-sub  { color: #94a3b8; }
body.dark-mode .cig-model-card .m-price { color: #4ade80; }
body.dark-mode .cig-size-btn      { background: #23252b; border-color: #2f3138; color: #cbd5e1; }
body.dark-mode .cig-size-btn:hover { background: #262931; }
body.dark-mode .cig-size-btn.active { background: #6366f1; border-color: #6366f1; color: #ffffff; }
body.dark-mode .cig-prompt        { background: #23252b; border-color: #2f3138; color: #f8fafc; }
body.dark-mode .cig-prompt:focus  { border-color: #6366f1; box-shadow: 0 0 0 3px rgba(99,102,241,.22); }
body.dark-mode .cig-hint          { color: #94a3b8; }
body.dark-mode .cig-cost-hint     { color: #f8fafc; }
body.dark-mode .cig-err           { background: #3f1d1d; border-color: #7f1d1d; color: #fecaca; }
body.dark-mode .cig-foot          { background: #191a1f; border-top-color: #2f3138; }
body.dark-mode .cig-btn-ghost     { background: #23252b; border-color: #2f3138; color: #cbd5e1; }
body.dark-mode .cig-btn-ghost:hover { background: #262931; }

/* -------- Small screens -------- */
@media (max-width: 560px) {
  .cig-overlay { padding: 12px; }
  .cig-model-grid { grid-template-columns: 1fr; }
}

/* =====================================================================
   v50.2 — NEW UI: Web Search toggle in '+' menu, reference-image upload
             inside the Create Image modal, and the clean "generated
             image" card with an on-image Download button (no filename,
             no model/size caption, no separate download row).
   ===================================================================== */

/* ---- Web Search toggle inside the '+' popup (v50.3 restyle) ----
   The original toggle used a green pill — which clashed visually with
   the rest of the black/gray menu. We now force the entire item into a
   quiet neutral look:
     - globe icon is BLACK (not the default blue Bootstrap icon color)
     - toggle switch is COMPACT (28×16) so it doesn't dominate the row
     - active state uses subtle dark gray instead of bright green
   Web Search still defaults to ON — that is enforced in chat.php via
   the `web_search_on` user column defaulting to 1. */
.plus-menu-item.plus-menu-websearch {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
}
.plus-menu-item.plus-menu-websearch .plus-menu-label { flex: 1; text-align: left; }
/* Force the globe icon (bi-globe) black in every state. */
.plus-menu-item.plus-menu-websearch > i.bi-globe {
  color: #111827 !important;
  font-size: 1rem;
}
body.dark-mode .plus-menu-item.plus-menu-websearch > i.bi-globe {
  color: #f3f4f6 !important;
}

/* v50.8: Web Search toggle redesigned as a Claude-style checkmark (✓)
   indicator instead of an ON/OFF pill switch. When Web Search is ON a
   crisp brand-blue check mark shows on the right; when OFF the check
   is hidden and the row looks like a plain menu item. This matches
   modern chat-UI conventions (Claude, ChatGPT) exactly, and is much
   quieter than the old green pill.

   The existing HTML nodes are reused: the outer .plus-menu-toggle acts
   as the check container, and its inner .plus-menu-toggle-dot becomes
   the actual check mark (via a Bootstrap Icons check glyph). Web Search
   still defaults to ON — that is enforced in chat.php via the
   `web_search_on` user column defaulting to 1. */
.plus-menu-item.plus-menu-websearch .plus-menu-toggle {
  position: relative;
  width: 20px;
  height: 20px;
  background: transparent;
  border-radius: 4px;
  transition: opacity .15s ease, transform .15s ease;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  user-select: none;
}
.plus-menu-item.plus-menu-websearch .plus-menu-toggle-dot {
  position: static;
  width: 20px;
  height: 20px;
  background: transparent;
  border-radius: 0;
  box-shadow: none;
  transition: opacity .15s ease, transform .15s ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* The check mark itself — rendered via a Bootstrap Icons glyph so we
     don't need to change the HTML. */
  color: #2563eb;             /* brand blue, matches Claude's accent tone */
  font-family: "bootstrap-icons";
  font-size: 18px;
  line-height: 1;
  font-weight: 700;
  opacity: 0;                 /* hidden when OFF */
}
.plus-menu-item.plus-menu-websearch .plus-menu-toggle-dot::before {
  content: "\F26B";           /* bi-check2 — clean thick check mark */
}
/* ON state — the check becomes visible. */
.plus-menu-item.plus-menu-websearch[aria-checked="true"] .plus-menu-toggle-dot {
  opacity: 1;
  transform: scale(1);
}
/* OFF state — keep row layout stable, just hide the check. */
.plus-menu-item.plus-menu-websearch[aria-checked="false"] .plus-menu-toggle-dot {
  opacity: 0;
  transform: scale(.85);
}
/* Dark-mode overrides. */
body.dark-mode .plus-menu-item.plus-menu-websearch .plus-menu-toggle-dot {
  color: #60a5fa;             /* softer blue on dark bg */
}

/* ---- Cleaner Create Image modal header (icon removed) ---- */
.cig-head-left { gap: 0 !important; }
.cig-label-hint { font-weight: 400; font-size: .75rem; color: #94a3b8; margin-left: 6px; }
body.dark-mode .cig-label-hint { color: #64748b; }

/* ---- Reference image upload inside the Create Image modal ---- */
.cig-upload-row { display: flex; align-items: center; gap: 10px; }
.cig-upload-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border-radius: 10px;
  border: 1px dashed #cbd5e1;
  background: #f8fafc;
  color: #334155;
  font-size: .85rem;
  cursor: pointer;
  transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.cig-upload-btn:hover {
  background: #eef2ff;
  border-color: #a5b4fc;
  color: #4338ca;
}
.cig-upload-btn i { font-size: 1rem; }
body.dark-mode .cig-upload-btn { background: #23252b; border-color: #3f4147; color: #cbd5e1; }
body.dark-mode .cig-upload-btn:hover { background: #262931; border-color: #6366f1; color: #a5b4fc; }

.cig-upload-preview {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}
.cig-upload-tile {
  position: relative;
  width: 72px;
  height: 72px;
  border-radius: 10px;
  overflow: hidden;
  background: #f1f5f9;
  border: 1px solid #e2e8f0;
  box-shadow: 0 1px 2px rgba(15,23,42,.05);
}
.cig-upload-tile img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.cig-upload-x {
  position: absolute;
  top: 3px;
  right: 3px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: none;
  background: rgba(15,23,42,.72);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: .7rem;
  line-height: 1;
  padding: 0;
}
.cig-upload-x:hover { background: rgba(15,23,42,.92); }
.cig-upload-name {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  background: linear-gradient(180deg, transparent, rgba(0,0,0,.7));
  color: #fff;
  font-size: .62rem;
  padding: 12px 4px 3px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
body.dark-mode .cig-upload-tile { background: #23252b; border-color: #2f3138; }

/* ---- Generated-image card (the assistant reply after Create Image) ----
   No filename, no caption, no separate download row. Just the image
   itself, with a small overlay "Download" button in the bottom-right
   corner that grabs the ZIP archive. Clean, Midjourney-style. */
.message.assistant .bubble:has(> .gen-image-card) {
  background: transparent;
  padding: 0;
  box-shadow: none;
  /* v50.6: never let the image bubble stretch wider than the message
     column, no matter what the underlying image's intrinsic size is. */
  max-width: 100%;
  overflow: hidden;
}
/* v50.9: loading skeleton width matches the new 680px final card width
   (v50.8 was 560px), so there's no width jump when the image finishes
   generating. Min-height also grown a touch to look less flat. */
.gen-image-card.hana-genimg-skeleton {
  width: min(100%, 680px) !important;
  max-width: min(100%, 680px) !important;
  min-height: 240px !important;
  margin-top: 6px !important;
  margin-bottom: 18px !important;
}
@media (max-width: 560px) {
  .gen-image-card.hana-genimg-skeleton {
    width: 100% !important;
    max-width: 100% !important;
    min-height: 180px !important;
  }
}
/* v50.9: generated image sizing — v50.8 raised the cap to 560px but the
   16:9 thumbnail was still visibly small compared to the composer column
   below it. We now bump the card up to 680px so a wide 16:9 image fills
   the message column properly, and we raise the height cap to 640px so
   9:16 portraits render at a comfortable size too. The card also sits a
   little lower relative to the user message thanks to a slightly larger
   top offset, and the bottom margin is unchanged (16px) so the like /
   copy toolbar and the composer both have a clean gap. */
.gen-image-card {
  position: relative;
  display: inline-block;
  /* v50.9: cap raised from 560 → 680 px so 16:9 images fill the column. */
  max-width: min(100%, 680px);
  width: auto;
  border-radius: 14px;
  overflow: hidden;
  background: #0b0d10;
  box-shadow: 0 8px 24px rgba(15,23,42,.14);
  box-sizing: border-box;
  /* v50.9: extra top margin nudges the image DOWN a touch so it doesn't
     hug the user message above; bottom margin keeps the composer gap. */
  margin-top: 6px;
  margin-bottom: 18px;
}
.gen-image-card .gen-image {
  display: block;
  /* Image itself: capped both horizontally and vertically so it always
     stays inside its rounded card and inside the bubble column. Height
     cap is generous so tall 9:16 portraits still show at a readable
     size while never blowing past the viewport. */
  max-width: 100%;
  /* v50.9: height cap raised from 560 → 640 px so tall 9:16 renders and
     wide 16:9 renders both look properly sized inside the card. */
  max-height: 640px;
  width: 100%;
  height: auto;
  object-fit: contain;
  cursor: zoom-in;
}
/* On narrow screens the card fills the bubble width comfortably. */
@media (max-width: 560px) {
  .gen-image-card {
    max-width: 100%;
    margin-top: 4px;
    margin-bottom: 14px;
  }
  .gen-image-card .gen-image { max-height: 460px; }
}
/* v50.3+: on-image action bar — now a single Download pill anchored
   comfortably INSIDE the rounded image card. The fullscreen icon was
   removed (the whole image is clickable to open the lightbox); the
   pill is sized and positioned so it never overflows the card's
   rounded corner. */
.gen-image-card .gen-image-actions {
  position: absolute;
  right: 12px;
  bottom: 12px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  z-index: 3;
  /* Extra safety net: even if a taller icon slips in, keep the row
     visually clipped inside the card by respecting the parent radius. */
  max-width: calc(100% - 24px);
  pointer-events: none; /* container is transparent to hover; buttons re-enable */
}
.gen-image-card .gen-image-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 999px;
  background: rgba(15,23,42,.72);
  color: #ffffff !important;
  text-decoration: none !important;
  border: 1px solid rgba(255,255,255,.22);
  box-shadow: 0 2px 6px rgba(0,0,0,.18);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition: background .12s ease, transform .12s ease;
  cursor: pointer;
  padding: 0;
  pointer-events: auto; /* re-enable clicks on the actual buttons */
  flex: 0 0 auto;
  box-sizing: border-box;
}
.gen-image-card .gen-image-btn:hover {
  background: rgba(15,23,42,.92);
  transform: translateY(-1px);
  text-decoration: none !important;
}
.gen-image-card .gen-image-btn i {
  font-size: 0.95rem;
  line-height: 1;
  display: inline-block;
}
/* Back-compat: old rule targeted .gen-image-dl directly with padding + text;
   the new .gen-image-btn wrapper covers the download icon. */
body.dark-mode .gen-image-card { background: #0b0d10; box-shadow: 0 8px 24px rgba(0,0,0,.4); }

/* Empty content div right above the image card should collapse cleanly. */
.message.assistant .bubble > .content:empty { display: none; }

/* ---- Cleaner overall look for the Create Image modal ----
   Slightly larger radius, softer shadow, tighter head. */
.cig-modal { border-radius: 18px !important; }
.cig-head  { border-top-left-radius: 18px; border-top-right-radius: 18px; }
.cig-foot  { border-bottom-left-radius: 18px; border-bottom-right-radius: 18px; }

/* Small responsive tweak: on narrow screens the reference tiles stay tidy. */
@media (max-width: 560px) {
  .cig-upload-tile { width: 60px; height: 60px; }
}

/* =====================================================================
 * v51: Topbar model dropdown — "Builder 2.0 Pro" / "Builder 2.0 Light"
 * ---------------------------------------------------------------------
 * The topbar model chip was a static pill in v50. In v51 it's a proper
 * dropdown: clicking the pill opens a small menu with the two variants,
 * each with a title + one-line subtitle and a checkmark on the active
 * one. The visual language matches the Web Search checkmark toggle so
 * both dropdowns feel like siblings.
 * ===================================================================== */
.hana-model-dd {
  position: relative;
  display: inline-block;
}
.hana-model-dd-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 1px solid transparent;
  padding: 6px 10px 6px 12px;
  border-radius: 10px;
  font-size: 0.95rem;
  font-weight: 600;
  color: #111827;
  cursor: pointer;
  line-height: 1.2;
  transition: background .15s ease, border-color .15s ease;
}
.hana-model-dd-toggle:hover,
.hana-model-dd.open .hana-model-dd-toggle {
  background: #f1f5f9;
  border-color: #e2e8f0;
}
.hana-model-dd-caret {
  font-size: 0.85rem;
  opacity: .7;
  transition: transform .15s ease;
}
.hana-model-dd.open .hana-model-dd-caret {
  transform: rotate(180deg);
}

.hana-model-dd-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 260px;
  background: #ffffff;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  box-shadow: 0 10px 30px rgba(15, 23, 42, .12);
  padding: 6px;
  z-index: 1050;
  opacity: 0;
  transform: translateY(-4px) scale(.98);
  pointer-events: none;
  transition: opacity .15s ease, transform .15s ease;
}
.hana-model-dd.open .hana-model-dd-menu {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}
.hana-model-dd-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  background: transparent;
  border: none;
  border-radius: 8px;
  padding: 8px 10px;
  cursor: pointer;
  text-align: left;
  color: #111827;
  transition: background .12s ease;
}
.hana-model-dd-item:hover {
  background: #f3f4f6;
}
.hana-model-dd-item-body {
  flex: 1;
  min-width: 0;
}
.hana-model-dd-item-title {
  font-weight: 600;
  font-size: 0.92rem;
  line-height: 1.25;
}
.hana-model-dd-item-sub {
  font-size: 0.75rem;
  color: #6b7280;
  line-height: 1.3;
  margin-top: 2px;
}
.hana-model-dd-check {
  color: #2563eb;
  font-size: 18px;
  line-height: 1;
  font-weight: 700;
  opacity: 0;
  transition: opacity .12s ease;
  flex-shrink: 0;
}
.hana-model-dd-item[aria-checked="true"] .hana-model-dd-check {
  opacity: 1;
}

/* Dark-mode overrides — match the existing dark theme tones. */
body.dark-mode .hana-model-dd-toggle {
  color: #f3f4f6;
}
body.dark-mode .hana-model-dd-toggle:hover,
body.dark-mode .hana-model-dd.open .hana-model-dd-toggle {
  background: #262931;
  border-color: #2f3138;
}
body.dark-mode .hana-model-dd-menu {
  background: #1c1e24;
  border-color: #2f3138;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .45);
}
body.dark-mode .hana-model-dd-item {
  color: #f3f4f6;
}
body.dark-mode .hana-model-dd-item:hover {
  background: #262931;
}
body.dark-mode .hana-model-dd-item-sub {
  color: #94a3b8;
}
body.dark-mode .hana-model-dd-check {
  color: #60a5fa;
}

/* v51.9.2: RESTORED — the Builder 2.0 Pro / LITE model picker is once
   again shown in the chat topbar so users can switch variants. The
   earlier v51.5 rule that hid it (display:none) has been removed. */
.chat-topbar .chat-topbar-model,
.chat-topbar-model { display: flex !important; }

/* v51.9.2: hide any stray DeepSeek-style "Thought for N seconds" pill
   that might still be sitting in older chat history (server-rendered
   messages, cached DOM, etc.). The generator call site has been
   commented out too — this is just a safety net. */
.message.thought-summary,
.thought-summary,
.thought-dd { display: none !important; }

/* =====================================================================
   v51.7 — Claude-style USER FILE ATTACHMENTS
   ---------------------------------------------------------------------
   Before v51.7, when a user message contained BOTH text and one or more
   file uploads, the file chip / image tile was rendered *inside* the
   grey user bubble. The bubble background wrapped around the chip so
   the attachment looked "stuck" onto the message — visually messy, with
   the filename bleeding into the bubble border.

   In v51.7 the JS now emits the file chips into a separate
   `.user-attachments-row` element that sits ABOVE the text bubble, on a
   fully transparent background — matching how Claude / ChatGPT / Gens-
   park display uploaded files: each attachment is a clean stand-alone
   tile, and only the text sits inside the grey bubble underneath.
   ===================================================================== */
.message.user .user-attachments-row {
  /* v51.9: attachments now stack TOP-TO-BOTTOM as a single vertical
     column, right-aligned to the user bubble side. Previously they
     wrapped side-by-side across the row (flex-direction: row +
     flex-wrap: wrap), which looked crowded when multiple files or
     images were attached. Claude-style stacked layout keeps each
     attachment tile on its own line so the user can scan them
     top-to-bottom cleanly. */
  display: flex;
  flex-direction: column;
  align-items: flex-end;       /* right-align, same as user bubble */
  gap: 8px;
  margin: 0 0 6px 0;
  background: transparent;
  padding: 0;
  border: 0;
}
.message.user .user-attachments-row .attachment,
.message.user .user-attachments-row .file-attachment-chip,
.message.user .user-attachments-row .sent-image-tile {
  margin-top: 0;      /* row provides spacing already */
}

/* When files live in the outside row, promote the file chip to a
   proper stand-alone card (Claude-style) — a bit larger, with a soft
   shadow, so it clearly reads as an attached document tile rather
   than a tiny inline pill. */
.message.user .user-attachments-row .file-attachment-chip {
  padding: 10px 14px;
  border-radius: 12px;
  background: var(--bg, #ffffff);
  border: 1px solid var(--border, #e5e7eb);
  box-shadow: 0 1px 2px rgba(15, 23, 42, .05);
  max-width: 360px;
}
.message.user .user-attachments-row .file-attachment-chip .file-thumb-doc {
  width: 34px;
  height: 34px;
  border-radius: 8px;
  background: var(--brand-soft, #eef2ff);
  color: var(--brand, #4f46e5);
  font-size: 1.05rem;
}
.message.user .user-attachments-row .file-attachment-chip .fname {
  font-weight: 600;
  color: var(--text-dark, #0f172a);
  max-width: 240px;
}
.message.user .user-attachments-row .file-attachment-chip .fsize {
  color: var(--text-muted, #64748b);
  font-size: .72rem;
}
body.dark-mode .message.user .user-attachments-row .file-attachment-chip {
  background: #2a2b32;
  border-color: #3a3c42;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .3);
}
body.dark-mode .message.user .user-attachments-row .file-attachment-chip .file-thumb-doc {
  background: #1f2026;
  color: #cbd0d8;
}
body.dark-mode .message.user .user-attachments-row .file-attachment-chip .fname {
  color: #f3f4f6;
}

/* Plain paperclip "attachment" (server-restored messages) — same
   transparent-card treatment when it lives in the outside row. */
.message.user .user-attachments-row .attachment {
  background: var(--bg, #ffffff);
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 12px;
  padding: 10px 14px;
  color: var(--text-dark, #0f172a);
  font-weight: 500;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .05);
}
body.dark-mode .message.user .user-attachments-row .attachment {
  background: #2a2b32;
  border-color: #3a3c42;
  color: #f3f4f6;
}

/* =====================================================================
   v51.8 — DeepSeek-style "Thought for N seconds" collapsible pill.
   ---------------------------------------------------------------------
   Once the model replies, the live "Thinking..." strip is replaced by
   a compact pill above the answer bubble. It's a real dropdown — click
   to expand/collapse. When expanded, the body only carries a short
   privacy note (the model's raw reasoning is never surfaced).

   Structure:
     .message.assistant.thought-summary
       .thought-dd[data-open="0|1"]
         button.thought-dd-toggle  ->  ▸ / ▾   +   label
         .thought-dd-body          ->  hidden until data-open="1"
   ===================================================================== */
.message.assistant.thought-summary {
  /* This is a lightweight row — no bubble background, no shadow.
     It should read as a small meta pill sitting just above the actual
     answer, exactly like DeepSeek's "Thought for N seconds". */
  background: transparent !important;
  padding: 0 !important;
  margin: 6px 0 4px 0;
  border: 0;
  box-shadow: none;
  display: flex;
  justify-content: flex-start;
}
.message.assistant.thought-summary .thought-dd {
  display: inline-flex;
  flex-direction: column;
  align-items: stretch;
  max-width: 100%;
}
.message.assistant.thought-summary .thought-dd-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(15, 23, 42, .04);
  border: 1px solid var(--border, #e5e7eb);
  color: var(--text-muted, #64748b);
  font-size: .82rem;
  font-weight: 500;
  padding: 4px 10px 4px 8px;
  border-radius: 999px;
  cursor: pointer;
  line-height: 1.2;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.message.assistant.thought-summary .thought-dd-toggle:hover {
  background: rgba(15, 23, 42, .07);
  color: var(--text-dark, #0f172a);
  border-color: rgba(15, 23, 42, .12);
}
.message.assistant.thought-summary .thought-dd-caret {
  font-size: .78rem;
  transition: transform .15s ease;
}
.message.assistant.thought-summary .thought-dd[data-open="1"] .thought-dd-toggle {
  background: rgba(15, 23, 42, .07);
  color: var(--text-dark, #0f172a);
}
.message.assistant.thought-summary .thought-dd-label {
  white-space: nowrap;
}
.message.assistant.thought-summary .thought-dd-body {
  margin-top: 6px;
  padding: 10px 14px;
  background: var(--bg, #ffffff);
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 10px;
  color: var(--text-muted, #64748b);
  font-size: .82rem;
  line-height: 1.5;
  max-width: 560px;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .04);
}
body.dark-mode .message.assistant.thought-summary .thought-dd-toggle {
  background: rgba(255, 255, 255, .05);
  border-color: rgba(255, 255, 255, .10);
  color: #b1b7c1;
}
body.dark-mode .message.assistant.thought-summary .thought-dd-toggle:hover,
body.dark-mode .message.assistant.thought-summary .thought-dd[data-open="1"] .thought-dd-toggle {
  background: rgba(255, 255, 255, .08);
  color: #f3f4f6;
  border-color: rgba(255, 255, 255, .16);
}
body.dark-mode .message.assistant.thought-summary .thought-dd-body {
  background: #2a2b32;
  border-color: #3a3c42;
  color: #c8ccd4;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .3);
}

/* =====================================================================
   v51.8 — user-attachments row: force TOP-BOTTOM stacking + smaller,
   Claude/DeepSeek-style attachment tiles.
   ---------------------------------------------------------------------
   Previously the attachments row was `flex-wrap: wrap` which, together
   with the tile's default 560px max-width, made images render as
   large slabs sitting BESIDE the text bubble on wide screens. The user
   asked for a clean top-to-bottom stack (image / file card ABOVE the
   text bubble, everything right-aligned so it still hugs the user's
   side of the chat) and for a noticeably smaller preview so short
   uploaded snapshots don't dominate the conversation.
   ===================================================================== */
.message.user .user-attachments-row {
  /* Stack every attachment on its own row so images/files never
     sit side-by-side or beside the text bubble. */
  flex-direction: column;
  align-items: flex-end;      /* right edge matches the user bubble */
  gap: 6px;
  margin: 0 0 8px 0;
}
.message.user .user-attachments-row .sent-image-tile {
  /* v51.8: cap uploaded image previews at ~300px so they read as a
     compact attachment tile (Claude / DeepSeek feel) instead of a
     huge photo. On narrow screens the media query further down keeps
     things responsive. */
  max-width: 300px !important;
  width: auto !important;
  border-radius: 12px;
  overflow: hidden;
  margin-top: 0;
}
.message.user .user-attachments-row .sent-image-tile img {
  max-width: 300px !important;
  max-height: 240px !important;
  width: 100%;
  height: auto;
  object-fit: cover;
  border-radius: 12px;
  display: block;
}
@media (max-width: 560px) {
  .message.user .user-attachments-row .sent-image-tile,
  .message.user .user-attachments-row .sent-image-tile img {
    max-width: 240px !important;
    max-height: 200px !important;
  }
}

/* v51.8 — smaller / lighter text inside the user bubble when the bubble
   only carries a caption underneath an attachment tile. Keeps things
   feeling like a compact caption rather than a big paragraph. */
.message.user .bubble .content {
  font-size: .95rem;
  line-height: 1.45;
}

/* =====================================================================
   v51.8 — small download button on user attachments (images + files).
   ---------------------------------------------------------------------
   Every attachment tile now carries a compact download icon so the user
   can grab a local copy of what they attached without needing the
   original file on disk. For images the button floats over the top-right
   corner (transparent glass look) and for the file chip it lives inline
   at the far right of the row. Clicking the download button never
   opens the lightbox (the JS above stops propagation).
   ===================================================================== */
.message .sent-image-tile { position: relative; }
.message .attach-dl-btn {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 28px;
  height: 28px;
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(15, 23, 42, .55);
  color: #fff;
  font-size: .95rem;
  text-decoration: none;
  opacity: 0;
  transition: opacity .15s ease, background .15s ease, transform .1s ease;
  z-index: 2;
}
.message .sent-image-tile:hover .attach-dl-btn,
.message .attach-dl-btn:focus-visible {
  opacity: 1;
}
.message .attach-dl-btn:hover {
  background: rgba(15, 23, 42, .78);
  color: #fff;
  transform: translateY(-1px);
}

/* File chip variant: sits inline at the end of the row, always visible. */
.message .file-attachment-chip {
  position: relative;
}
.message .file-attachment-chip .attach-dl-chip {
  position: static;
  opacity: 1;
  margin-left: 8px;
  width: 30px;
  height: 30px;
  background: rgba(15, 23, 42, .06);
  color: var(--text-muted, #64748b);
  border-radius: 8px;
  flex-shrink: 0;
}
.message .file-attachment-chip .attach-dl-chip:hover {
  background: rgba(15, 23, 42, .12);
  color: var(--text-dark, #0f172a);
}
body.dark-mode .message .file-attachment-chip .attach-dl-chip {
  background: rgba(255, 255, 255, .08);
  color: #cbd0d8;
}
body.dark-mode .message .file-attachment-chip .attach-dl-chip:hover {
  background: rgba(255, 255, 255, .16);
  color: #ffffff;
}

/* Make sure the file chip lays out as a row so the download button sits
   cleanly to the right of the filename + size block. */
.message .file-attachment-chip {
  display: inline-flex;
  align-items: center;
}

/* =====================================================================
   v52.1  ────  Final UX polish (applied per product spec)
   ─────────────────────────────────────────────────────────────────────
   1) Chat topbar "Builder 2.0 Pro / LITE" pill is now noticeably LARGER
      and heavier so the current variant is easy to see at a glance.
   2) Composer file-preview strip scrolls LEFT / RIGHT (horizontal slider)
      instead of TOP / BOTTOM — matches ChatGPT / Genspark. Each chip is
      now a small square-ish thumbnail tile with NO filename and NO size
      label; only the picture (or the file-type icon) + the X button.
   3) User-side sent image / file tiles no longer show the filename strip
      or the ".fname" label anywhere in the chat surface. The download
      button is still there for images.
   4) A new `.assistant-attachments-row` container stacks attachment
      tiles ABOVE the assistant's text bubble content — image on top,
      text below — instead of images sitting side-by-side with the text.
   ===================================================================== */

/* --- 1) BIGGER topbar model label ----------------------------------- */
.chat-topbar {
  padding-top: 10px;
  padding-bottom: 10px;
}
.hana-model-dd-toggle {
  padding: 10px 16px 10px 18px !important;
  font-size: 1.15rem !important;   /* was 0.95rem */
  font-weight: 700 !important;
  border-radius: 12px !important;
  letter-spacing: .1px;
}
.hana-model-dd-toggle .hana-model-dd-label {
  font-size: 1.15rem;
  font-weight: 700;
  line-height: 1.2;
}
.hana-model-dd-caret {
  font-size: 1rem !important;
}
@media (max-width: 640px) {
  .hana-model-dd-toggle {
    padding: 8px 12px 8px 14px !important;
    font-size: 1.02rem !important;
  }
  .hana-model-dd-toggle .hana-model-dd-label { font-size: 1.02rem; }
}

/* --- 2) Composer preview strip → horizontal slider ------------------ */
/* Override both earlier rules (v22 & v51.9.1) that stacked chips as a
   vertical column with overflow-y:auto. */
.composer-inner .file-preview-strip,
.composer-inner.has-attachments-host .file-preview-strip {
  display: flex !important;
  flex-direction: row !important;   /* v52.1: left → right */
  flex-wrap: nowrap !important;
  gap: 8px !important;
  padding: 6px 8px !important;
  max-height: none !important;
  overflow-x: auto !important;      /* v52.1: horizontal scroll */
  overflow-y: hidden !important;
  scrollbar-width: thin;
  -webkit-overflow-scrolling: touch;
}
.composer-inner .file-preview-strip::-webkit-scrollbar {
  height: 6px !important;
  width: auto !important;
}
.composer-inner .file-preview-strip::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, .18);
  border-radius: 4px;
}
body.dark-mode .composer-inner .file-preview-strip::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, .22);
}

/* v52.6.1: IMAGE chips → compact 64x64 square thumbnail, filename
   hidden (per product spec). NON-IMAGE chips (code / text / pdf /
   doc / zip / etc.) → keep their natural width and ALWAYS show the
   real filename + size next to the file-type icon, matching the
   ChatGPT / Genspark composer behaviour. */
.composer-inner .file-preview.file-preview-image {
  flex: 0 0 auto !important;
  align-self: center !important;
  width: 64px;
  height: 64px;
  padding: 0 !important;
  border-radius: 12px !important;
  position: relative;
  overflow: hidden;
  border: 1px solid var(--border);
  background: var(--bg);
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
}
/* Non-image (file) chips keep the compact horizontal card look and
   show the filename. Anchored to the top of the strip.
   v52.7: overflow relaxed to visible so long filenames still ellipsize
   inside .fname (which owns its own overflow:hidden) but the X remove
   button on the chip is never clipped by the chip border. Width bumped
   so the filename + size + X all fit comfortably on one row. */
.composer-inner .file-preview:not(.file-preview-image) {
  flex: 0 0 auto !important;
  align-self: center !important;
  padding: 6px 10px 6px 6px !important;
  border-radius: 12px !important;
  position: relative;
  overflow: visible !important;
  border: 1px solid var(--border);
  background: var(--bg);
  display: inline-flex !important;
  align-items: center;
  justify-content: flex-start !important;
  gap: 8px;
  min-width: 200px;
  max-width: 340px;
  height: auto;
}
/* Hide filename ONLY on image chips. Non-image chips keep it visible. */
.composer-inner .file-preview.file-preview-image .file-meta,
.composer-inner .file-preview.file-preview-image .fname,
.composer-inner .file-preview.file-preview-image .fsize {
  display: none !important;
}
/* Non-image chip → show filename + size stacked next to the icon. */
.composer-inner .file-preview:not(.file-preview-image) .file-meta {
  display: flex !important;
  flex-direction: column;
  line-height: 1.25;
  min-width: 80px;
  max-width: 220px;
  flex: 1 1 auto;
  align-items: flex-start;
  justify-content: center;
  overflow: hidden;
}
.composer-inner .file-preview:not(.file-preview-image) .fname {
  display: block !important;
  visibility: visible !important;
  opacity: 1 !important;
  font-weight: 600 !important;
  font-size: .85rem !important;
  color: var(--text-dark) !important;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.composer-inner .file-preview:not(.file-preview-image) .fsize {
  display: block !important;
  visibility: visible !important;
  opacity: 1 !important;
  font-size: .72rem !important;
  color: var(--text-muted) !important;
}
/* Image chip: thumb fills the whole 64x64 tile. */
.composer-inner .file-preview.file-preview-image .file-thumb {
  width: 100%;
  height: 100%;
  border-radius: 12px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 !important;
  background: transparent;
}
.composer-inner .file-preview.file-preview-image .file-thumb-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 12px;
}
/* Non-image chip: small icon tile (36x36) beside the filename. */
.composer-inner .file-preview:not(.file-preview-image) .file-thumb {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 !important;
  background: var(--brand-light);
  flex-shrink: 0;
}
.composer-inner .file-preview:not(.file-preview-image) .file-thumb-doc {
  width: 100%;
  height: 100%;
  border-radius: 8px;
  background: var(--brand-light);
  color: var(--brand-primary, var(--brand, #4f46e5));
  font-size: 1.15rem;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Image chip: keep the old fallback icon look for images-with-no-thumb. */
.composer-inner .file-preview.file-preview-image .file-thumb-doc {
  width: 100%;
  height: 100%;
  border-radius: 12px;
  background: var(--brand-soft, #eef2ff);
  color: var(--brand, #4f46e5);
  font-size: 1.4rem;
}
/* X (remove) button:
   - Image chips: floating top-right on the thumbnail tile.
   - Non-image chips: inline at the end of the row. */
/* v52.7: X (remove) button on IMAGE chip → clearly visible on the
   top-right corner of the 64x64 thumbnail. Slightly larger + white
   ring so it never blends into the image behind it. */
.composer-inner .file-preview.file-preview-image .remove-file {
  position: absolute !important;
  top: -6px !important;
  right: -6px !important;
  width: 22px !important;
  height: 22px !important;
  min-width: 22px !important;
  padding: 0 !important;
  border-radius: 50% !important;
  background: #0f172a !important;
  color: #fff !important;
  border: 2px solid #fff !important;
  display: flex !important;
  visibility: visible !important;
  opacity: 1 !important;
  align-items: center;
  justify-content: center;
  font-size: 12px !important;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(0,0,0,.35) !important;
  z-index: 5 !important;
}
.composer-inner .file-preview.file-preview-image .remove-file:hover {
  background: #dc2626 !important;
  color: #fff !important;
}
/* Image chip needs overflow visible so the floating X isn't clipped. */
.composer-inner .file-preview.file-preview-image {
  overflow: visible !important;
}
/* v52.7: X (remove) button on NON-IMAGE (file) chip → always visible
   at the end of the row. Bigger contrast so users can spot and click
   it to detach the file. */
.composer-inner .file-preview:not(.file-preview-image) .remove-file {
  position: relative !important;
  top: auto !important;
  right: auto !important;
  margin-left: 6px !important;
  width: 24px !important;
  height: 24px !important;
  min-width: 24px !important;
  padding: 0 !important;
  border-radius: 50% !important;
  background: rgba(15, 23, 42, .10) !important;
  color: var(--text-dark) !important;
  border: 0 !important;
  display: inline-flex !important;
  visibility: visible !important;
  opacity: 1 !important;
  align-items: center;
  justify-content: center;
  font-size: .85rem !important;
  line-height: 1;
  cursor: pointer;
  flex-shrink: 0;
  box-shadow: none !important;
  transition: background .15s, color .15s;
  z-index: 5 !important;
}
.composer-inner .file-preview:not(.file-preview-image) .remove-file:hover {
  background: #dc2626 !important;
  color: #fff !important;
}
body.dark-mode .composer-inner .file-preview:not(.file-preview-image) .remove-file {
  background: rgba(255, 255, 255, .10) !important;
  color: #ECECEC !important;
}
body.dark-mode .composer-inner .file-preview:not(.file-preview-image) .remove-file:hover {
  background: #dc2626 !important;
  color: #fff !important;
}
body.dark-mode .composer-inner .file-preview {
  background: #22242b;
  border-color: #33363d;
}
body.dark-mode .composer-inner .file-preview .file-thumb-doc {
  background: #2e313a;
  color: #cbd0d8;
}

/* --- 3) Kill any leftover filename display in sent tiles / chips ---- */
.message .sent-image-tile .sent-image-name,
.message .file-attachment-chip .file-meta,
.message .file-attachment-chip .fname,
.message .file-attachment-chip .fsize,
.message.user .user-attachments-row .file-attachment-chip .file-meta,
.message.user .user-attachments-row .file-attachment-chip .fname,
.message.user .user-attachments-row .file-attachment-chip .fsize {
  display: none !important;
}
/* Since the .file-meta is gone, tighten up the sent-file chip so it
   still looks balanced with just an icon + download button. */
.message .file-attachment-chip {
  padding: 8px 10px;
  gap: 8px;
}
.message.user .user-attachments-row .file-attachment-chip {
  min-width: 0;
  max-width: none;
}

/* --- 4) Assistant reply: attachments stack ABOVE the text ----------- */
.message.assistant .bubble .assistant-attachments-row {
  display: flex;
  flex-direction: column;   /* v52.1: image on top, next image below */
  align-items: flex-start;
  gap: 8px;
  margin: 0 0 10px 0;       /* space between images row and text below */
}
.message.assistant .bubble .assistant-attachments-row .sent-image-tile {
  margin: 0;
  max-width: 100%;
}
.message.assistant .bubble .assistant-attachments-row .file-attachment-chip {
  margin: 0;
}
/* When the bubble contains ONLY images (no text), remove the trailing
   margin so the bubble hugs the image tightly. */
.message.assistant .bubble .assistant-attachments-row:last-child {
  margin-bottom: 0;
}

/* =====================================================================
   v52.2 — Composer non-image file chip: filename restored
   ---------------------------------------------------------------------
   For non-image files queued in the composer preview strip the chip now
   shows: [icon] [filename + size] [× remove]. Image chips stay as pure
   thumbnails (no filename). Keeps the composer tidy while giving the
   user a clear label for CSVs / PDFs / code files.
   ===================================================================== */
.file-preview .file-preview-meta {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
  flex: 1 1 auto;
  gap: 2px;
  padding: 0 4px;
}
.file-preview .file-preview-name {
  font-size: .88rem;
  font-weight: 600;
  color: var(--text-dark);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 220px;
}
.file-preview .file-preview-size {
  font-size: .72rem;
  color: var(--text-muted);
  line-height: 1;
}
body.dark-mode .file-preview .file-preview-name { color: #ECECEC; }
body.dark-mode .file-preview .file-preview-size { color: #a8adb7; }
/* When it's an image chip (no meta block), keep the old compact layout. */
.file-preview.file-preview-image .file-preview-meta { display: none; }

/* =====================================================================
   v52.2 — Sent-message non-image chip: filename shown, no download icon
   ---------------------------------------------------------------------
   In the chat bubble (both live-sent and server-restored), non-image
   attachments now render as: [icon] [filename] [size]. The tiny floating
   download icon has been removed from BOTH image tiles and file chips.
   ===================================================================== */
.file-attachment-chip-named {
  display: inline-flex !important;
  align-items: center;
  gap: 10px;
  padding: 8px 12px !important;
  background: rgba(0,0,0,.03);
  border: 1px solid var(--border);
  border-radius: 12px;
  max-width: 320px;
}
.file-attachment-chip-named .file-thumb-doc {
  width: 34px;
  height: 34px;
  min-width: 34px;
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--brand-soft);
  color: var(--text-dark);
  font-size: 1.05rem;
}
.file-attachment-chip-named .sent-file-meta {
  display: flex;
  flex-direction: column;
  min-width: 0;
  gap: 2px;
}
.file-attachment-chip-named .sent-file-name {
  font-size: .9rem;
  font-weight: 600;
  color: var(--text-dark);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 240px;
}
.file-attachment-chip-named .sent-file-size {
  font-size: .74rem;
  color: var(--text-muted);
  line-height: 1;
}
body.dark-mode .file-attachment-chip-named {
  background: rgba(255,255,255,.05);
  border-color: rgba(255,255,255,.10);
}
body.dark-mode .file-attachment-chip-named .file-thumb-doc {
  background: rgba(255,255,255,.08);
  color: #ECECEC;
}
body.dark-mode .file-attachment-chip-named .sent-file-name { color: #ECECEC; }
body.dark-mode .file-attachment-chip-named .sent-file-size { color: #a8adb7; }

/* Sent image tiles no longer show the little download icon (v52.2). */
.sent-image-tile .attach-dl-btn { display: none !important; }

/* =====================================================================
   v52.2 — Three-dots menu on the composer + Prompt Enhance toggle
   ---------------------------------------------------------------------
   New "…" button next to the mic. Currently hosts a single toggle
   ("Prompt Enhance", default OFF). When ON, the composer reveals a
   sky-blue inline enhance button (see .enhance-btn below).
   ===================================================================== */
.threedots-menu-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.threedots-menu {
  position: absolute;
  bottom: calc(100% + 8px);
  right: 0;
  min-width: 240px;
  padding: 6px;
  background: var(--bg);
  color: var(--text-dark);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 12px 32px rgba(15, 23, 42, .12);
  display: none;
  z-index: 1000;
}
.threedots-menu.open { display: block; }
.threedots-menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 12px;
  background: transparent;
  border: 0;
  border-radius: 8px;
  color: var(--text-dark);
  font-size: .92rem;
  text-align: left;
  cursor: pointer;
}
.threedots-menu-item:hover { background: var(--brand-soft); }
.threedots-menu-item i {
  font-size: 1.05rem;
  color: #38bdf8; /* sky-blue accent for the enhance icon */
  opacity: .95;
}
.threedots-menu-item .threedots-menu-label { flex: 1; }
.threedots-menu-toggle {
  width: 32px;
  height: 18px;
  border-radius: 999px;
  background: #cbd0d8;
  position: relative;
  flex-shrink: 0;
  transition: background .15s ease;
}
.threedots-menu-toggle-dot {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 2px rgba(0,0,0,.15);
  transition: transform .15s ease;
}
.threedots-menu-item[aria-checked="true"] .threedots-menu-toggle {
  background: #38bdf8; /* ON = sky-blue */
}
.threedots-menu-item[aria-checked="true"] .threedots-menu-toggle-dot {
  transform: translateX(14px);
}
body.dark-mode .threedots-menu {
  background: #2a2b32;
  color: #ECECEC;
  border-color: #3a3c42;
  box-shadow: 0 12px 32px rgba(0,0,0,.45);
}
body.dark-mode .threedots-menu-item        { color: #ECECEC; }
body.dark-mode .threedots-menu-item:hover  { background: rgba(255,255,255,.06); }
body.dark-mode .threedots-menu-toggle      { background: #5a5d66; }

/* =====================================================================
   v52.2 — Inline Prompt-Enhance button in the composer
   ---------------------------------------------------------------------
   Sky-blue rounded button that appears inside the typing box when the
   user turns Prompt Enhance ON. Sits just before the mic/send buttons.
   ===================================================================== */
.composer-btn.enhance-btn {
  background: #38bdf8;   /* sky-blue */
  color: #fff;
  border-radius: 999px;
  transition: background .15s ease, transform .1s ease;
}
.composer-btn.enhance-btn:hover {
  background: #0ea5e9;   /* darker sky-blue on hover */
  color: #fff;
}
.composer-btn.enhance-btn:active {
  transform: scale(.95);
}
.composer-btn.enhance-btn.is-busy {
  background: #7dd3fc;
  cursor: progress;
  opacity: .85;
}
.composer-btn.enhance-btn.is-busy i {
  animation: enhance-spin .9s linear infinite;
  display: inline-block;
}
@keyframes enhance-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
body.dark-mode .composer-btn.enhance-btn { background: #38bdf8; color: #fff; }
body.dark-mode .composer-btn.enhance-btn:hover { background: #0ea5e9; }

/* =====================================================================
   v52.3 \u2014 Prompt Enhance pill (persistent) + flat inline enhance action
   ---------------------------------------------------------------------
   Layout: a small pill sitting on its own row directly beneath the
   composer row (visually below the + upload icon). The pill hosts:
   [wand icon] [Prompt Enhance] [ON/OFF toggle] [X close]
   The inline enhance action button inside the composer is now flat
   (transparent, no background box) per product request \u2014 the sky-blue
   background from v52.2 has been removed.
   ===================================================================== */
.composer-tools-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px 4px 8px;
  flex-wrap: wrap;
}
.composer-tools-row.is-hidden { display: none; }

.pe-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 6px 4px 10px;
  border-radius: 999px;
  background: var(--bg, #fff);
  border: 1px solid var(--border, #e5e7eb);
  box-shadow: 0 1px 2px rgba(0,0,0,.04);
  font-size: .82rem;
  color: var(--text-dark, #1f2937);
  line-height: 1;
  user-select: none;
}
.pe-pill.pe-pill-on {
  background: rgba(56, 189, 248, .10);
  border-color: rgba(56, 189, 248, .40);
  color: #0369a1;
}
.pe-pill .pe-pill-icon {
  font-size: .95rem;
  color: inherit;
  opacity: .9;
}
.pe-pill .pe-pill-label {
  font-weight: 600;
  white-space: nowrap;
}
.pe-pill .pe-pill-toggle {
  position: relative;
  width: 28px;
  height: 16px;
  border-radius: 999px;
  background: #cbd0d8;
  border: none;
  padding: 0;
  cursor: pointer;
  transition: background .15s ease;
  flex-shrink: 0;
}
.pe-pill .pe-pill-toggle-dot {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 12px;
  height: 12px;
  background: #fff;
  border-radius: 50%;
  transition: transform .15s ease;
  box-shadow: 0 1px 2px rgba(0,0,0,.15);
}
.pe-pill.pe-pill-on .pe-pill-toggle { background: #38bdf8; }
.pe-pill.pe-pill-on .pe-pill-toggle-dot { transform: translateX(12px); }
.pe-pill .pe-pill-close {
  background: transparent;
  border: none;
  color: inherit;
  opacity: .55;
  cursor: pointer;
  width: 22px; height: 22px;
  padding: 0;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: .7rem;
  transition: background .15s ease, opacity .15s ease;
}
.pe-pill .pe-pill-close:hover {
  opacity: 1;
  background: rgba(0,0,0,.06);
}

body.dark-mode .pe-pill {
  background: #2a2b30;
  border-color: rgba(255,255,255,.10);
  color: #ECECEC;
}
body.dark-mode .pe-pill.pe-pill-on {
  background: rgba(56, 189, 248, .15);
  border-color: rgba(56, 189, 248, .45);
  color: #7dd3fc;
}
body.dark-mode .pe-pill .pe-pill-toggle { background: #5a5d66; }
body.dark-mode .pe-pill.pe-pill-on .pe-pill-toggle { background: #38bdf8; }
body.dark-mode .pe-pill .pe-pill-close:hover { background: rgba(255,255,255,.08); }

/* v52.3 \u2014 Flat variant of the inline enhance action button.
   Overrides the v52.2 sky-blue filled style so the button reads as a
   plain icon (no background box). The tiny \"active/being used\" hint is
   a slightly tighter padding + soft ring, not a filled pill. */
.composer-btn.enhance-btn.enhance-btn-flat {
  background: transparent;
  color: #0ea5e9;
  border-radius: 999px;
  padding: 4px 6px;   /* v52.3: smaller front/back padding per request */
  box-shadow: none;
}
.composer-btn.enhance-btn.enhance-btn-flat:hover {
  background: rgba(56, 189, 248, .12);
  color: #0284c7;
}
.composer-btn.enhance-btn.enhance-btn-flat:active {
  transform: scale(.95);
}
.composer-btn.enhance-btn.enhance-btn-flat.is-busy {
  background: transparent;
  color: #7dd3fc;
  cursor: progress;
  opacity: .85;
}
body.dark-mode .composer-btn.enhance-btn.enhance-btn-flat {
  background: transparent;
  color: #38bdf8;
}
body.dark-mode .composer-btn.enhance-btn.enhance-btn-flat:hover {
  background: rgba(56, 189, 248, .18);
  color: #7dd3fc;
}

/* =====================================================================
   v52.4 \u2014 Prompt Enhance toggle inside the '+' menu
   ---------------------------------------------------------------------
   The old persistent Prompt-Enhance pill (which sat below the composer
   on its own row) has been retired. Prompt Enhance is now a real
   ON/OFF toggle switch inside the '+' popup menu, sitting directly
   below the Web Search row. It uses the base .plus-menu-toggle pill
   style (green ON / grey OFF) exactly like a mobile settings switch.
   ===================================================================== */
.plus-menu-item.plus-menu-enhance {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
}
.plus-menu-item.plus-menu-enhance .plus-menu-label { flex: 1; text-align: left; }
/* Keep the magic-wand icon a neutral dark colour, matching the globe. */
.plus-menu-item.plus-menu-enhance > i.bi-magic {
  color: #111827 !important;
  font-size: 1rem;
}
body.dark-mode .plus-menu-item.plus-menu-enhance > i.bi-magic {
  color: #f3f4f6 !important;
}

/* Force the legacy Prompt-Enhance pill row to stay hidden on every
   screen size (the markup is retained for backward-compat with older
   JS queries but the visible UI has moved into the '+' menu). */
.composer-tools-row[data-tools-row],
.composer-inner .composer-tools-row[data-tools-row] {
  display: none !important;
}

/* =====================================================================
   v52.4 \u2014 Sidebar brand: small "HANA" wordmark next to the logo
   ---------------------------------------------------------------------
   Adds a compact wordmark that sits tight against the left edge of the
   sidebar, right beside the brain logo. Kept intentionally small so it
   doesn't crowd the header, and glued to the left with zero extra gap.
   ===================================================================== */
.chat-sidebar .sidebar-header {
  padding-left: 6px !important;   /* hug the left edge */
  gap: 6px !important;             /* keep wordmark tight against the logo */
  justify-content: flex-start !important;
}
/* v52.5 — Push the "Close sidebar" toggle to the right edge of the header,
   while the logo + wordmark stay hugging the left. Mobile-friendly. */
.chat-sidebar .sidebar-header .sidebar-inner-toggle {
  margin-left: auto;
}
.chat-sidebar .sidebar-header .sidebar-brand-word {
  font-size: .95rem;
  font-weight: 800;
  letter-spacing: .5px;
  color: var(--brand, #16a34a);
  line-height: 1;
  margin: 0;
  padding: 0;
  white-space: nowrap;
  font-family: inherit;
}
body.dark-mode .chat-sidebar .sidebar-header .sidebar-brand-word {
  color: #4ade80;
}

/* =====================================================================
   v52.6 — Composer file chip: always show real filename for non-image
   ---------------------------------------------------------------------
   Any non-image attachment in the composer preview strip (code / text
   / pdf / doc / zip / etc.) must show its real filename + extension
   next to the file-type icon. Image chips still keep their filename
   HIDDEN (thumbnail-only), so only NON-image chips get this rule.

   These rules just harden what chat.js already renders: they make
   sure .file-meta actually lays out as a two-line label (name over
   size) inside a flex chip, and that the filename never disappears
   under any inherited display / visibility rule.
   ===================================================================== */
.composer-inner .file-preview:not(.file-preview-image) {
  /* Give the filename room to breathe on its own row inside the
     composer strip. Chip still keeps its rounded card look. */
  max-width: 340px;
}
.composer-inner .file-preview:not(.file-preview-image) .file-meta {
  display: flex !important;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
  max-width: 240px;
  line-height: 1.2;
}
.composer-inner .file-preview:not(.file-preview-image) .file-meta .fname {
  display: block !important;
  visibility: visible !important;
  font-weight: 600;
  font-size: .82rem;
  color: var(--text-dark);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.composer-inner .file-preview:not(.file-preview-image) .file-meta .fsize {
  display: block !important;
  visibility: visible !important;
  font-size: .72rem;
  color: var(--text-muted);
}
/* Image chips: keep filename hidden inside the composer preview
   (thumbnail-only) so only the picture + remove button are visible. */
.composer-inner .file-preview.file-preview-image .file-meta,
.composer-inner .file-preview.file-preview-image .fname,
.composer-inner .file-preview.file-preview-image .fsize {
  display: none !important;
}

/* =====================================================================
   v52.6 — Sidebar wordmark: "HANA" sits tight beside the logo
   ---------------------------------------------------------------------
   Re-affirms the v52.4 sidebar-header layout so the "HANA" wordmark is
   always visible next to the brain logo, in the app's own font family,
   hugging the left edge of the sidebar. The logo itself is untouched.
   ===================================================================== */
.chat-sidebar .sidebar-header .sidebar-brand-word {
  display: inline-block !important;
  visibility: visible !important;
  font-family: inherit;
}

/* =====================================================================
   v55 — Composer file chip: FINAL harden (per user spec)
   ---------------------------------------------------------------------
   Fix: For non-image files (HTML / code / PDF / DOC / TXT / ZIP / etc.)
   attached in the composer, ALWAYS show:
       [file-type icon] [real filename.ext] [size] [× remove button]
   Image chips (green AI-logo style) still hide their filename and
   only show the thumbnail + X, matching the earlier spec.
   Font is kept as the app default (inherit) — same look as everywhere
   else in Curious AI.
   These rules are appended AFTER all previous rules so they win the
   cascade — earlier v52.x rules cannot accidentally hide the filename
   or the X button any more.
   ===================================================================== */

/* ---------- Non-image chip: layout + visible filename ---------- */
.composer-inner .file-preview:not(.file-preview-image) {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: flex-start !important;
  gap: 10px !important;
  padding: 8px 10px 8px 8px !important;
  min-width: 220px !important;
  max-width: 360px !important;
  border: 1px solid var(--border) !important;
  border-radius: 12px !important;
  background: var(--bg) !important;
  overflow: visible !important;
  font-family: inherit !important;
}

/* File-type icon square on the left */
.composer-inner .file-preview:not(.file-preview-image) .file-thumb {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 36px !important;
  height: 36px !important;
  min-width: 36px !important;
  border-radius: 8px !important;
  background: var(--brand-light, #eef2ff) !important;
  color: var(--brand, #4f46e5) !important;
  font-size: 1.15rem !important;
  flex-shrink: 0 !important;
  overflow: hidden !important;
}
.composer-inner .file-preview:not(.file-preview-image) .file-thumb-doc {
  color: var(--brand, #4f46e5) !important;
}

/* Meta block: filename + size, stacked vertically */
.composer-inner .file-preview:not(.file-preview-image) .file-meta {
  display: flex !important;
  flex-direction: column !important;
  justify-content: center !important;
  align-items: flex-start !important;
  flex: 1 1 auto !important;
  min-width: 0 !important;
  max-width: 240px !important;
  line-height: 1.25 !important;
  gap: 2px !important;
  overflow: hidden !important;
}

/* Filename — FORCE VISIBLE */
.composer-inner .file-preview:not(.file-preview-image) .file-meta .fname,
.composer-inner .file-preview:not(.file-preview-image) .fname {
  display: block !important;
  visibility: visible !important;
  opacity: 1 !important;
  font-family: inherit !important;
  font-weight: 600 !important;
  font-size: .85rem !important;
  color: var(--text-dark) !important;
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  max-width: 100% !important;
  line-height: 1.25 !important;
  margin: 0 !important;
  padding: 0 !important;
}

/* File size */
.composer-inner .file-preview:not(.file-preview-image) .file-meta .fsize,
.composer-inner .file-preview:not(.file-preview-image) .fsize {
  display: block !important;
  visibility: visible !important;
  opacity: 1 !important;
  font-family: inherit !important;
  font-size: .72rem !important;
  color: var(--text-muted) !important;
  line-height: 1.2 !important;
  margin: 0 !important;
  padding: 0 !important;
}

/* X (remove) button — FORCE VISIBLE, always clickable */
.composer-inner .file-preview:not(.file-preview-image) .remove-file {
  position: relative !important;
  top: auto !important;
  right: auto !important;
  margin-left: 6px !important;
  width: 24px !important;
  height: 24px !important;
  min-width: 24px !important;
  padding: 0 !important;
  border: 0 !important;
  border-radius: 50% !important;
  background: rgba(15, 23, 42, .10) !important;
  color: var(--text-dark) !important;
  display: inline-flex !important;
  visibility: visible !important;
  opacity: 1 !important;
  align-items: center !important;
  justify-content: center !important;
  font-size: .85rem !important;
  line-height: 1 !important;
  cursor: pointer !important;
  flex-shrink: 0 !important;
  z-index: 5 !important;
  transition: background .15s ease, color .15s ease !important;
}
.composer-inner .file-preview:not(.file-preview-image) .remove-file:hover {
  background: #dc2626 !important;
  color: #fff !important;
}
body.dark-mode .composer-inner .file-preview:not(.file-preview-image) .remove-file {
  background: rgba(255, 255, 255, .12) !important;
  color: #ECECEC !important;
}
body.dark-mode .composer-inner .file-preview:not(.file-preview-image) .remove-file:hover {
  background: #dc2626 !important;
  color: #fff !important;
}

/* ---------- Image chip: keep filename hidden, X always visible ---------- */
.composer-inner .file-preview.file-preview-image .file-meta,
.composer-inner .file-preview.file-preview-image .fname,
.composer-inner .file-preview.file-preview-image .fsize {
  display: none !important;
}
.composer-inner .file-preview.file-preview-image .remove-file {
  display: flex !important;
  visibility: visible !important;
  opacity: 1 !important;
}

/* =====================================================================
   v57.1: File attachment chip — text (filename + size) BELOW the icon.
   -----------------------------------------------------------------
   Per user request, the file text (name + size) must appear on its
   own line UNDER the file icon/thumb — not to the right of it.
   Applies to both the compact chip and the promoted stand-alone card
   in the .user-attachments-row, and matches on the assistant side
   too. Only the layout direction and alignment change; font, colors,
   sizes, borders and everything else stay exactly the same.
   ===================================================================== */
.message .file-attachment-chip {
  flex-direction: column !important;
  align-items: center !important;
  text-align: center !important;
}
.message .file-attachment-chip .file-meta,
.message .file-attachment-chip .sent-file-meta {
  align-items: center !important;
  text-align: center !important;
}
.message .file-attachment-chip .fname,
.message .file-attachment-chip .sent-file-name {
  max-width: 100% !important;
  white-space: normal !important;
  overflow-wrap: anywhere !important;
  text-overflow: clip !important;
}

/* =====================================================================
   v52.4 — STACK ATTACHMENT ABOVE TEXT (ChatGPT-style)
   ---------------------------------------------------------------------
   For USER messages that contain BOTH an attachment (image/file) and
   a text caption, the attachment tile must sit ON TOP and the text
   bubble must sit BELOW it — exactly like ChatGPT. Previously the
   .message.user container used flex-direction:row, which made the
   attachment tile and the text bubble appear side-by-side (image on
   one side, text on the other). This override switches the layout
   to a vertical column and right-aligns both, matching the user
   bubble alignment. Only affects user messages that actually have
   a .user-attachments-row present; other messages are untouched.
   ===================================================================== */
.message.user:has(.user-attachments-row) {
  flex-direction: column !important;
  align-items: flex-end !important;
}
.message.user:has(.user-attachments-row) .user-attachments-row {
  order: 1;              /* image/file first (on top) */
  width: auto;
  max-width: 100%;
}
.message.user:has(.user-attachments-row) .bubble {
  order: 2;              /* text bubble second (below) */
  max-width: 100%;
  align-self: flex-end;  /* stay right-aligned like the user bubble */
}
