/* ==========================================================================
   特拉拉市集 · 站內傳訊 · Component Styles
   --------------------------------------------------------------------------
   ALL selectors are prefixed `.tllm-` and namespaced inside `.tllm-root`.
   Drop the whole plugin shell inside <div class="tllm-root"> ... </div>
   and these styles will not collide with any WordPress theme.

   Naming: BEM-like
       .tllm-block                  block
       .tllm-block__element         element
       .tllm-block--modifier        modifier
       .tllm-is-state               state (active, open, unread, mine, etc.)
   ========================================================================== */


/* ========== 1. Reset (scoped to .tllm-root only) ========== */

.tllm-root,
.tllm-root *,
.tllm-root *::before,
.tllm-root *::after { box-sizing: border-box; }

.tllm-root {
  font-family: var(--tllm-font-zh);
  font-size: var(--tllm-fs-body);
  line-height: var(--tllm-lh-normal);
  color: var(--tllm-ink);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
.tllm-root button,
.tllm-root input,
.tllm-root textarea,
.tllm-root select {
  font: inherit;
  color: inherit;
  margin: 0;
}
.tllm-root button { background: none; border: 0; padding: 0; cursor: pointer; }
.tllm-root a { color: var(--tllm-brand); text-decoration: none; }
.tllm-root :focus-visible { outline: 0; box-shadow: var(--tllm-ring-focus); border-radius: 4px; }


/* ========== 2. Glass primitives ========== */

.tllm-glass {
  background: var(--tllm-glass-strong);
  -webkit-backdrop-filter: blur(var(--tllm-blur)) saturate(var(--tllm-blur-sat));
          backdrop-filter: blur(var(--tllm-blur)) saturate(var(--tllm-blur-sat));
  border: 1px solid var(--tllm-glass-border);
  box-shadow: var(--tllm-shadow-glass);
}
.tllm-glass--lg {
  background: var(--tllm-glass-strong);
  -webkit-backdrop-filter: blur(var(--tllm-blur)) saturate(var(--tllm-blur-sat));
          backdrop-filter: blur(var(--tllm-blur)) saturate(var(--tllm-blur-sat));
  border: 1px solid var(--tllm-glass-border);
  box-shadow: var(--tllm-shadow-glass-lg);
}
.tllm-glass--thin {
  background: var(--tllm-glass);
  -webkit-backdrop-filter: blur(calc(var(--tllm-blur) * 0.6)) saturate(160%);
          backdrop-filter: blur(calc(var(--tllm-blur) * 0.6)) saturate(160%);
  border: 1px solid var(--tllm-glass-border);
}

/* Blob canvas — the soft color clouds the glass refracts.
   Apply to a wrapper; glass children show colored light through. */
.tllm-blob-canvas {
  position: relative;
  background: var(--tllm-bg);
  isolation: isolate;
  overflow: hidden;
}
.tllm-blob-canvas::before {
  content: "";
  position: absolute; inset: -10%;
  z-index: 0;
  background:
    radial-gradient(28% 22% at 12% 18%, var(--tllm-blob-blue) 0%, transparent 70%),
    radial-gradient(26% 24% at 88% 22%, var(--tllm-blob-violet) 0%, transparent 70%),
    radial-gradient(24% 22% at 18% 86%, var(--tllm-blob-mint) 0%, transparent 70%),
    radial-gradient(30% 26% at 82% 84%, var(--tllm-blob-rose) 0%, transparent 70%),
    radial-gradient(20% 18% at 50% 50%, var(--tllm-blob-cyan) 0%, transparent 70%);
  filter: saturate(110%);
  pointer-events: none;
}
.tllm-blob-canvas > * { position: relative; z-index: 1; }


/* ========== 3. Typography helpers ========== */

.tllm-h1   { font-size: var(--tllm-fs-h1); font-weight: var(--tllm-fw-bold); line-height: var(--tllm-lh-tight); color: var(--tllm-ink); letter-spacing: -0.01em; margin: 0; }
.tllm-h2   { font-size: var(--tllm-fs-h2); font-weight: var(--tllm-fw-semibold); line-height: var(--tllm-lh-snug); color: var(--tllm-ink); margin: 0; }
.tllm-h3   { font-size: var(--tllm-fs-h3); font-weight: var(--tllm-fw-semibold); line-height: var(--tllm-lh-snug); color: var(--tllm-ink); margin: 0; }
.tllm-text { font-size: var(--tllm-fs-body); color: var(--tllm-ink-2); margin: 0; }
.tllm-meta { font-size: var(--tllm-fs-sm); color: var(--tllm-ink-3); margin: 0; }
.tllm-muted { color: var(--tllm-ink-3); }
.tllm-num  { font-family: var(--tllm-font-num); font-variant-numeric: tabular-nums; }


/* ========== 4. Buttons ========== */

.tllm-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 10px 18px;
  font-size: var(--tllm-fs-body);
  font-weight: var(--tllm-fw-semibold);
  line-height: 1;
  border-radius: var(--tllm-r-md);
  border: 1px solid transparent;
  transition: background var(--tllm-dur-fast) var(--tllm-ease),
              border-color var(--tllm-dur-fast) var(--tllm-ease),
              transform var(--tllm-dur-fast) var(--tllm-ease),
              box-shadow var(--tllm-dur-fast) var(--tllm-ease);
  white-space: nowrap;
  user-select: none;
}
.tllm-btn:active { transform: scale(0.98); }

.tllm-btn--primary {
  background: var(--tllm-brand);
  color: var(--tllm-ink-on-brand);
  box-shadow: 0 1px 0 rgba(255,255,255,.18) inset, 0 6px 18px rgba(15,76,129,.30);
}
.tllm-btn--primary:hover { background: var(--tllm-brand-hover); }
.tllm-btn--primary:active { background: var(--tllm-brand-pressed); }

.tllm-btn--ghost {
  background: var(--tllm-surface);
  color: var(--tllm-ink);
  border-color: var(--tllm-divider);
}
.tllm-btn--ghost:hover { background: var(--tllm-surface-3); }

.tllm-btn--glass {
  background: rgba(255,255,255,0.6);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
          backdrop-filter: blur(20px) saturate(180%);
  color: var(--tllm-ink);
  border-color: var(--tllm-glass-border);
}
.tllm-btn--glass:hover { background: rgba(255,255,255,0.78); }

.tllm-btn--lg { padding: 14px 22px; font-size: 16px; border-radius: var(--tllm-r-md); }
.tllm-btn--sm { padding: 7px 12px; font-size: var(--tllm-fs-sm); border-radius: var(--tllm-r-sm); }
.tllm-btn--block { display: flex; width: 100%; }
.tllm-btn--icon  { padding: 10px; aspect-ratio: 1; }

/* Danger variant for report/block */
.tllm-btn--danger {
  background: var(--tllm-surface);
  color: var(--tllm-danger);
  border-color: var(--tllm-divider);
}
.tllm-btn--danger:hover { background: var(--tllm-danger-soft); border-color: var(--tllm-danger-soft); }


/* ========== 5. Inputs ========== */

.tllm-input,
.tllm-textarea {
  display: block;
  width: 100%;
  padding: 12px 14px;
  font-size: var(--tllm-fs-body);
  background: var(--tllm-surface);
  color: var(--tllm-ink);
  border: 1px solid var(--tllm-divider);
  border-radius: var(--tllm-r-md);
  transition: border-color var(--tllm-dur-fast) var(--tllm-ease),
              box-shadow var(--tllm-dur-fast) var(--tllm-ease);
}
.tllm-input::placeholder,
.tllm-textarea::placeholder { color: var(--tllm-ink-4); }
.tllm-input:focus,
.tllm-textarea:focus { outline: 0; border-color: var(--tllm-brand); box-shadow: var(--tllm-ring-focus); }
.tllm-textarea { resize: none; line-height: var(--tllm-lh-snug); }


/* ========== 6. Chips & Badges ========== */

.tllm-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  font-size: var(--tllm-fs-xs);
  font-weight: var(--tllm-fw-semibold);
  letter-spacing: 0.02em;
  border-radius: var(--tllm-r-pill);
  background: var(--tllm-surface-3);
  color: var(--tllm-ink-2);
  border: 1px solid var(--tllm-divider);
  line-height: 1;
  white-space: nowrap;
}
.tllm-chip--brand   { background: var(--tllm-brand-soft); color: var(--tllm-brand-pressed); border-color: transparent; }
.tllm-chip--success { background: var(--tllm-success-soft); color: #047857; border-color: transparent; }
.tllm-chip--warn    { background: var(--tllm-warning-soft); color: #92400E; border-color: transparent; }
.tllm-chip--danger  { background: var(--tllm-danger-soft); color: #B91C1C; border-color: transparent; }
.tllm-chip--ghost   { background: transparent; }
.tllm-chip__dot     { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }

.tllm-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px;
  font-size: 10px; font-weight: 700;
  background: var(--tllm-danger); color: white;
  border-radius: var(--tllm-r-pill);
  border: 2px solid var(--tllm-surface);
  line-height: 1;
}
.tllm-badge--brand { background: var(--tllm-brand); }


/* ========== 7. Avatars ========== */

.tllm-avatar {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--tllm-blob-blue), var(--tllm-blob-violet));
  color: var(--tllm-ink-navy);
  font-weight: var(--tllm-fw-bold);
  font-size: 14px;
  flex: none;
  overflow: hidden;
}
.tllm-avatar--sm { width: 32px; height: 32px; font-size: 12px; }
.tllm-avatar--lg { width: 56px; height: 56px; font-size: 18px; }
.tllm-avatar__online {
  position: absolute; right: -1px; bottom: -1px;
  width: 12px; height: 12px;
  background: var(--tllm-success);
  border: 2px solid var(--tllm-surface);
  border-radius: 50%;
}
.tllm-avatar--sm .tllm-avatar__online { width: 10px; height: 10px; }


/* ========== 8. Icon button ========== */

.tllm-icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px;
  border-radius: var(--tllm-r-md);
  color: var(--tllm-ink-2);
  transition: background var(--tllm-dur-fast) var(--tllm-ease),
              color var(--tllm-dur-fast) var(--tllm-ease);
  position: relative;
}
.tllm-icon-btn:hover { background: var(--tllm-surface-3); color: var(--tllm-ink); }
.tllm-icon-btn--sm   { width: 32px; height: 32px; border-radius: var(--tllm-r-sm); }
.tllm-icon-btn__badge {
  position: absolute; top: 4px; right: 4px;
}


/* ========== 9. Modal scrim + container ========== */

.tllm-scrim {
  position: absolute; inset: 0;
  background: var(--tllm-scrim);
  -webkit-backdrop-filter: blur(2px);
          backdrop-filter: blur(2px);
  z-index: var(--tllm-z-scrim);
  display: flex; align-items: center; justify-content: center;
}


/* ========== 13. Chat popup (single-thread modal) ========== */

.tllm-chat {
  display: flex; flex-direction: column;
  width: 100%; max-width: 460px; height: 640px;
  background: var(--tllm-glass-strong);
  -webkit-backdrop-filter: blur(var(--tllm-blur)) saturate(var(--tllm-blur-sat));
          backdrop-filter: blur(var(--tllm-blur)) saturate(var(--tllm-blur-sat));
  border: 1px solid var(--tllm-glass-border);
  box-shadow: var(--tllm-shadow-glass-lg);
  border-radius: var(--tllm-r-xl);
  overflow: hidden;
}

.tllm-chat__head {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--tllm-glass-border);
}
.tllm-chat__head-body { flex: 1; min-width: 0; line-height: 1.25; }
.tllm-chat__head-name { font-weight: var(--tllm-fw-semibold); color: var(--tllm-ink); font-size: var(--tllm-fs-h3); }
.tllm-chat__head-sub  { font-size: var(--tllm-fs-xs); color: var(--tllm-ink-3); margin-top: 2px; display: flex; align-items: center; gap: 6px; }
.tllm-chat__head-actions { display: flex; gap: 2px; }

/* Pinned product reference at top of thread */
.tllm-chat__pinned {
  display: flex; gap: 12px; align-items: center;
  padding: 10px 16px;
  /* Never let this row exceed its column; the title inside ellipsises. */
  min-width: 0; max-width: 100%;
  background: rgba(255,255,255,0.55);
  border-bottom: 1px solid var(--tllm-glass-border);
}
.tllm-chat__pinned-thumb {
  width: 44px; height: 44px; border-radius: var(--tllm-r-sm);
  background: var(--tllm-surface-3);
  display: grid; place-items: center;
  font-size: 10px; color: var(--tllm-ink-4);
  flex: none; overflow: hidden;
}
.tllm-chat__pinned-body { flex: 1; min-width: 0; line-height: 1.25; }
.tllm-chat__pinned-title { font-size: var(--tllm-fs-sm); color: var(--tllm-ink); font-weight: var(--tllm-fw-semibold); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tllm-chat__pinned-price { font-family: var(--tllm-font-num); font-size: var(--tllm-fs-sm); color: var(--tllm-brand); font-weight: var(--tllm-fw-semibold); margin-top: 2px; }

/* Scam/fraud warning banner */
.tllm-chat__warn {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 10px 16px;
  background: rgba(254, 243, 199, 0.85);
  -webkit-backdrop-filter: blur(8px);
          backdrop-filter: blur(8px);
  font-size: var(--tllm-fs-xs);
  color: #92400E;
  line-height: 1.45;
  border-bottom: 1px solid rgba(245, 158, 11, 0.25);
}
.tllm-chat__warn-icon { color: var(--tllm-warning); flex: none; margin-top: 1px; }
.tllm-chat__warn-close { color: #92400E; opacity: 0.7; }

/* Thread (scroll area) */
.tllm-chat__thread {
  flex: 1; min-height: 0;
  overflow-y: auto;
  padding: 16px;
  display: flex; flex-direction: column; gap: 8px;
}
.tllm-chat__daysep {
  display: flex; align-items: center; gap: 10px;
  margin: 6px 0 8px;
  font-size: 11px; color: var(--tllm-ink-3);
  text-align: center;
}
.tllm-chat__daysep::before,
.tllm-chat__daysep::after { content: ""; height: 1px; flex: 1; background: var(--tllm-divider); }

/* Bubble */
.tllm-bubble {
  display: flex; gap: 8px;
  max-width: 80%;
}
.tllm-bubble--mine  { align-self: flex-end; flex-direction: row-reverse; }
.tllm-bubble--theirs{ align-self: flex-start; }
.tllm-bubble__body  {
  padding: 10px 14px;
  border-radius: 16px;
  font-size: var(--tllm-fs-body);
  line-height: var(--tllm-lh-snug);
  word-wrap: break-word;
  position: relative;
}
.tllm-bubble--theirs .tllm-bubble__body {
  background: rgba(255,255,255,0.85);
  color: var(--tllm-ink);
  border-bottom-left-radius: 6px;
  box-shadow: 0 1px 2px rgba(15,23,42,.04);
}
.tllm-bubble--mine .tllm-bubble__body {
  background: var(--tllm-brand);
  color: var(--tllm-ink-on-brand);
  border-bottom-right-radius: 6px;
  box-shadow: 0 4px 14px rgba(15,76,129,.25);
}
.tllm-bubble__meta {
  display: flex; gap: 4px; align-items: center;
  font-size: 10px; color: var(--tllm-ink-4);
  align-self: flex-end;
  padding: 0 2px 4px;
  white-space: nowrap;
}
.tllm-bubble__meta--mine { color: var(--tllm-ink-3); }
.tllm-bubble__check { color: var(--tllm-brand); }
.tllm-bubble__check--unread { color: var(--tllm-ink-4); }

/* Typing indicator */
.tllm-typing {
  display: inline-flex; gap: 4px; padding: 12px 14px;
  background: rgba(255,255,255,0.85);
  border-radius: 16px;
  border-bottom-left-radius: 6px;
  align-self: flex-start;
  align-items: center;
}
.tllm-typing__dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--tllm-ink-4);
  animation: tllm-bounce 1.2s infinite ease-in-out;
}
.tllm-typing__dot:nth-child(2) { animation-delay: 0.15s; }
.tllm-typing__dot:nth-child(3) { animation-delay: 0.3s; }
@keyframes tllm-bounce {
  0%, 80%, 100% { transform: translateY(0); opacity: 0.5; }
  40% { transform: translateY(-4px); opacity: 1; }
}

/* Product card embed inside chat */
.tllm-prodcard {
  display: flex; gap: 10px; align-items: center;
  padding: 10px;
  background: var(--tllm-surface);
  border: 1px solid var(--tllm-divider);
  border-radius: var(--tllm-r-md);
  max-width: 280px;
  box-shadow: 0 1px 2px rgba(15,23,42,.04);
}
.tllm-prodcard__thumb {
  width: 56px; height: 56px; border-radius: var(--tllm-r-sm);
  background: var(--tllm-surface-3);
  display: grid; place-items: center;
  font-size: 11px; color: var(--tllm-ink-4);
  flex: none;
}
.tllm-prodcard__body { flex: 1; min-width: 0; line-height: 1.3; }
.tllm-prodcard__title { font-size: var(--tllm-fs-sm); font-weight: var(--tllm-fw-semibold); color: var(--tllm-ink); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.tllm-prodcard__price { font-family: var(--tllm-font-num); font-size: var(--tllm-fs-sm); font-weight: var(--tllm-fw-bold); color: var(--tllm-brand); margin-top: 4px; }

/* Offer / price-negotiation card */
.tllm-offer {
  width: 280px;
  background: var(--tllm-surface);
  border: 1px solid var(--tllm-brand-soft);
  border-radius: var(--tllm-r-md);
  padding: 12px 14px;
  box-shadow: 0 4px 16px rgba(15,76,129,.12);
}
.tllm-offer__lbl { display: flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 700; color: var(--tllm-brand); letter-spacing: 0.06em; text-transform: uppercase; }
.tllm-offer__price { font-family: var(--tllm-font-num); font-size: 26px; font-weight: 800; color: var(--tllm-ink); margin-top: 4px; line-height: 1; }
.tllm-offer__list { font-size: var(--tllm-fs-xs); color: var(--tllm-ink-3); margin-top: 4px; }
.tllm-offer__list .tllm-strike { text-decoration: line-through; }
.tllm-offer__actions { display: flex; gap: 8px; margin-top: 12px; }
.tllm-offer__actions .tllm-btn { flex: 1; }
.tllm-offer--accepted { border-color: var(--tllm-success); background: linear-gradient(180deg, var(--tllm-success-soft) 0%, var(--tllm-surface) 80%); }
.tllm-offer--accepted .tllm-offer__lbl { color: #047857; }
.tllm-offer--declined { border-color: var(--tllm-danger-soft); }
.tllm-offer--declined .tllm-offer__lbl { color: #B91C1C; }
.tllm-offer__status {
  display: flex; align-items: center; gap: 6px;
  font-size: var(--tllm-fs-xs); font-weight: 600;
  margin-top: 8px;
}

/* Composer */
.tllm-chat__composer {
  display: flex; gap: 8px; align-items: flex-end;
  padding: 12px 14px calc(12px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--tllm-glass-border);
  background: rgba(255,255,255,0.6);
}
.tllm-chat__composer-input {
  flex: 1;
  display: flex; align-items: center; gap: 4px;
  padding: 4px 6px 4px 14px;
  background: var(--tllm-surface);
  border: 1px solid var(--tllm-divider);
  border-radius: var(--tllm-r-pill);
}
.tllm-chat__composer-input textarea {
  flex: 1; resize: none; border: 0; outline: 0; background: transparent;
  font-size: var(--tllm-fs-body); padding: 8px 0; max-height: 80px;
  line-height: 1.4;
}
.tllm-chat__composer-send {
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--tllm-brand); color: white;
  display: grid; place-items: center;
  box-shadow: 0 6px 16px rgba(15,76,129,.30);
  transition: background var(--tllm-dur-fast);
}
.tllm-chat__composer-send:hover { background: var(--tllm-brand-hover); }
.tllm-chat__composer-send:disabled { background: var(--tllm-ink-4); box-shadow: none; cursor: not-allowed; }

/* Empty / first-message state */
.tllm-chat__empty {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 24px; text-align: center; gap: 12px;
}
.tllm-chat__empty-icon {
  width: 56px; height: 56px; border-radius: 50%;
  background: var(--tllm-brand-tint); color: var(--tllm-brand);
  display: grid; place-items: center;
}
.tllm-chat__quick {
  display: flex; flex-wrap: wrap; gap: 6px; justify-content: center;
  max-width: 320px;
}
.tllm-quick-chip {
  padding: 7px 12px;
  border: 1px solid var(--tllm-divider);
  background: var(--tllm-surface);
  border-radius: var(--tllm-r-pill);
  font-size: var(--tllm-fs-sm);
  color: var(--tllm-ink-2);
  cursor: pointer;
  transition: all var(--tllm-dur-fast);
}
.tllm-quick-chip:hover { border-color: var(--tllm-brand); color: var(--tllm-brand); background: var(--tllm-brand-tint); }


/* ========== 14. Chat Dashboard (modal: list + thread) ========== */

.tllm-dashboard {
  display: flex;
  width: 100%; max-width: 1080px; height: min(720px, 90vh);
  background: var(--tllm-glass-strong);
  -webkit-backdrop-filter: blur(var(--tllm-blur)) saturate(var(--tllm-blur-sat));
          backdrop-filter: blur(var(--tllm-blur)) saturate(var(--tllm-blur-sat));
  border: 1px solid var(--tllm-glass-border);
  border-radius: var(--tllm-r-xl);
  box-shadow: var(--tllm-shadow-glass-lg);
  overflow: hidden;
}

.tllm-dashboard__list {
  width: 340px;
  display: flex; flex-direction: column;
  border-right: 1px solid var(--tllm-glass-border);
  background: rgba(255,255,255,0.30);
}
.tllm-dashboard__head {
  padding: 18px 18px 14px;
  display: flex; align-items: center; gap: 10px;
  border-bottom: 1px solid var(--tllm-glass-border);
}
.tllm-dashboard__title { flex: 1; font-size: var(--tllm-fs-h1); font-weight: var(--tllm-fw-bold); color: var(--tllm-ink); }
.tllm-dashboard__title-count { color: var(--tllm-ink-3); font-weight: var(--tllm-fw-medium); font-size: var(--tllm-fs-sm); margin-left: 6px; }

.tllm-dashboard__filters {
  display: flex; gap: 4px; padding: 10px 14px;
  border-bottom: 1px solid var(--tllm-divider-2);
}
.tllm-dashboard__filter {
  padding: 6px 12px; border-radius: var(--tllm-r-pill);
  font-size: var(--tllm-fs-sm); color: var(--tllm-ink-3);
  cursor: pointer;
  transition: all var(--tllm-dur-fast);
}
.tllm-dashboard__filter.tllm-is-active { background: var(--tllm-ink); color: white; }
.tllm-dashboard__filter:hover:not(.tllm-is-active) { background: var(--tllm-surface-3); color: var(--tllm-ink); }

.tllm-dashboard__search {
  padding: 10px 14px;
}
.tllm-dashboard__search-input {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px;
  background: rgba(255,255,255,0.75);
  border: 1px solid var(--tllm-divider);
  border-radius: var(--tllm-r-pill);
}
.tllm-dashboard__search-input input {
  flex: 1; border: 0; background: transparent; outline: 0;
  font-size: var(--tllm-fs-sm);
}
.tllm-dashboard__search-input svg { color: var(--tllm-ink-4); }

.tllm-dashboard__items {
  flex: 1; overflow-y: auto;
  padding: 4px 8px 12px;
}
.tllm-convo {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 12px 10px;
  border-radius: var(--tllm-r-md);
  cursor: pointer;
  transition: background var(--tllm-dur-fast);
}
.tllm-convo:hover { background: rgba(255,255,255,0.5); }
.tllm-convo.tllm-is-active { background: rgba(255,255,255,0.85); box-shadow: 0 1px 2px rgba(15,23,42,.04); }
.tllm-convo__body { flex: 1; min-width: 0; line-height: 1.3; }
.tllm-convo__top { display: flex; align-items: baseline; gap: 6px; }
.tllm-convo__name { font-weight: var(--tllm-fw-semibold); color: var(--tllm-ink); font-size: var(--tllm-fs-h3); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tllm-convo__time { font-size: 11px; color: var(--tllm-ink-3); white-space: nowrap; flex: none; }
.tllm-convo__product {
  display: flex; align-items: center; gap: 4px;
  font-size: 11px; color: var(--tllm-brand);
  margin-top: 3px;
  font-weight: var(--tllm-fw-medium);
}
.tllm-convo__product-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.tllm-convo__preview {
  display: flex; align-items: center; gap: 6px;
  margin-top: 4px;
  font-size: var(--tllm-fs-sm); color: var(--tllm-ink-3);
}
.tllm-convo__preview-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 1; }
.tllm-convo.tllm-is-unread .tllm-convo__preview-text,
.tllm-convo.tllm-is-unread .tllm-convo__name { color: var(--tllm-ink); font-weight: var(--tllm-fw-semibold); }
.tllm-convo__unread {
  min-width: 18px; height: 18px;
  background: var(--tllm-brand);
  border-radius: var(--tllm-r-pill);
  color: white; font-size: 10px; font-weight: 700;
  display: grid; place-items: center;
  padding: 0 5px;
  flex: none;
}

/* dashboard right pane: full chat thread, but rendered without modal chrome */
.tllm-dashboard__thread {
  flex: 1; display: flex; flex-direction: column;
  /* min-width:0 is the missing link in the flex chain. Without it the pane's
     default min-width:auto refuses to shrink below the pinned product title's
     intrinsic width, so a long title pushes the pane past the viewport and the
     dashboard's overflow:hidden clips it (查看商品 button vanishes off-screen).
     Blink collapses it via the title's overflow:hidden, but iOS WebKit webviews
     (LINE / Mail in-app browsers) don't — hence the report from both. */
  min-width: 0;
  background: rgba(255,255,255,0.45);
}

/* dashboard empty state */
.tllm-dashboard__empty {
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 14px;
  padding: 40px; text-align: center;
}
.tllm-dashboard__empty-icon {
  width: 72px; height: 72px; border-radius: 50%;
  background: var(--tllm-brand-tint);
  color: var(--tllm-brand);
  display: grid; place-items: center;
}


/* ========== 15. Seller backend toggle ========== */

.tllm-settings {
  background: var(--tllm-surface);
  border: 1px solid var(--tllm-divider);
  border-radius: var(--tllm-r-lg);
  padding: var(--tllm-sp-6);
}
.tllm-settings__row {
  display: flex; align-items: flex-start; gap: var(--tllm-sp-4);
  padding: var(--tllm-sp-4) 0;
  border-bottom: 1px solid var(--tllm-divider-2);
}
.tllm-settings__row:last-child { border-bottom: 0; }
.tllm-settings__row-body { flex: 1; }
.tllm-settings__row-label { font-weight: var(--tllm-fw-semibold); color: var(--tllm-ink); font-size: var(--tllm-fs-body); }
.tllm-settings__row-desc { font-size: var(--tllm-fs-sm); color: var(--tllm-ink-3); margin-top: 4px; line-height: 1.5; }

.tllm-toggle {
  position: relative;
  width: 44px; height: 26px;
  background: var(--tllm-ink-4);
  border-radius: var(--tllm-r-pill);
  cursor: pointer;
  flex: none;
  transition: background var(--tllm-dur-base);
}
.tllm-toggle::after {
  content: "";
  position: absolute; top: 3px; left: 3px;
  width: 20px; height: 20px;
  background: white;
  border-radius: 50%;
  box-shadow: 0 1px 2px rgba(0,0,0,0.2);
  transition: transform var(--tllm-dur-base) var(--tllm-ease);
}
.tllm-toggle.tllm-is-on { background: var(--tllm-brand); }
.tllm-toggle.tllm-is-on::after { transform: translateX(18px); }

/* Mode radio block for seller (chat / phone only / both) */
.tllm-mode-grid { display: grid; gap: 10px; margin-top: 12px; }
.tllm-mode {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 14px;
  background: var(--tllm-surface);
  border: 1px solid var(--tllm-divider);
  border-radius: var(--tllm-r-md);
  cursor: pointer;
  transition: all var(--tllm-dur-fast);
}
.tllm-mode:hover { border-color: var(--tllm-brand); }
.tllm-mode.tllm-is-selected {
  border-color: var(--tllm-brand);
  background: var(--tllm-brand-tint);
  box-shadow: 0 0 0 1px var(--tllm-brand) inset;
}
.tllm-mode__radio {
  width: 18px; height: 18px; border: 2px solid var(--tllm-ink-4);
  border-radius: 50%; flex: none; margin-top: 1px;
  display: grid; place-items: center;
}
.tllm-mode.tllm-is-selected .tllm-mode__radio { border-color: var(--tllm-brand); }
.tllm-mode.tllm-is-selected .tllm-mode__radio::after {
  content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--tllm-brand);
}
.tllm-mode__body { flex: 1; }
.tllm-mode__title { font-weight: var(--tllm-fw-semibold); color: var(--tllm-ink); }
.tllm-mode__desc  { font-size: var(--tllm-fs-sm); color: var(--tllm-ink-3); margin-top: 2px; }


/* ========== 16. Misc utilities ========== */

.tllm-divider-line { height: 1px; background: var(--tllm-divider); }
.tllm-sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.tllm-stack { display: flex; flex-direction: column; }
.tllm-row   { display: flex; align-items: center; }
.tllm-grow  { flex: 1; }


/* ========== 17. Responsive overrides ========== */

@media (max-width: 480px) {
  .tllm-chat {
    max-width: none; height: 100%; border-radius: 0;
    box-shadow: none;
  }
}


/* ==========================================================================
   18. TSHP integration additions (extends spec — popup portal + dashboard
       mobile state toggle + optimistic-render bubble states + status line)
   ========================================================================== */

/* Popup portal — fixed full-viewport host for the scrim+chat. The spec's
   .tllm-scrim is `position: absolute; inset: 0`, so the portal must provide
   a positioned full-viewport box for it to anchor against. */
.tshp-chat-portal {
  position: fixed;
  inset: 0;
  z-index: 100000;
  pointer-events: auto;
}
.tshp-chat-portal[hidden] { display: none; }

/* Popup loading state inside the thread before first fetch resolves. */
.tllm-chat__loading {
  align-self: center;
  margin: 24px auto;
  color: var(--tllm-ink-3);
  font-size: var(--tllm-fs-sm);
}

/* Composer status line (errors, rate-limit notices). */
.tllm-chat__status {
  padding: 8px 16px;
  margin: 0 16px 12px;
  border-radius: var(--tllm-r-sm);
  background: var(--tllm-surface-3);
  color: var(--tllm-ink-2);
  font-size: var(--tllm-fs-sm);
  line-height: 1.5;
}
.tllm-chat__status--error {
  background: var(--tllm-danger-soft);
  color: #B91C1C;
}

/* Optimistic bubble states */
.tllm-bubble--pending .tllm-bubble__body { opacity: 0.78; }
.tllm-bubble--pending .tllm-bubble__meta { color: var(--tllm-ink-4); }
.tllm-bubble--failed { opacity: 0.85; outline: 1px dashed var(--tllm-danger); }
.tllm-bubble--failed .tllm-bubble__meta { color: var(--tllm-danger); }

/* Admin role bubble — accent border so it's clearly not buyer/seller. */
.tllm-bubble--admin {
  outline: 1px solid var(--tllm-info);
  outline-offset: -1px;
}

/* Empty state for popup (structured title + sub + chip row) */
.tllm-chat__empty-title {
  font-size: var(--tllm-fs-h3);
  font-weight: var(--tllm-fw-semibold);
  color: var(--tllm-ink);
  margin: 0;
}
.tllm-chat__empty-sub {
  font-size: var(--tllm-fs-sm);
  color: var(--tllm-ink-3);
  margin: 0;
  line-height: 1.55;
}
.tllm-chat__empty-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
  margin-top: 4px;
}

/* Dashboard empty for thread pane (no convo selected) */
.tllm-dashboard__empty--inner { padding: 60px 40px; }

/* Dashboard mobile back button — hidden on desktop, shown in thread view.
   Higher specificity (+ .tllm-dashboard) so it beats .tshp-chat-xbtn's
   display:inline-flex (the back button shares xbtn's circular look but its
   visibility is responsive). */
.tllm-root .tllm-dashboard .tllm-dashboard__mobile-back { display: none !important; margin-right: 8px; }


/* ==========================================================================
   19. WoodMart defense — STRIP theme pollution from chat module
   ==========================================================================
   WoodMart aggressively styles <button> and <textarea> with:
     • border-radius: 0
     • min-height: 42px on buttons (square buttons everywhere)
     • min-height: 190px / padding: 10px 15px / resize: vertical on textarea
   These pollute the .tllm-* design system. We reset with high-specificity
   + !important, then re-apply spec values for elements that need them.
*/

/* Base reset — surgical, only override what WoodMart pollutes */
.tllm-root button,
.tllm-root .tllm-root button {
  background: none !important;
  border: 0 !important;
  border-radius: 0 !important;
  padding: 0 !important;
  min-height: 0 !important;
  min-width: 0 !important;
  height: auto !important;
  width: auto !important;
  box-shadow: none !important;
  text-shadow: none !important;
  text-transform: none !important;
  letter-spacing: normal !important;
  line-height: 1 !important;
  cursor: pointer;
  font: inherit !important;
  color: inherit !important;
}

.tllm-root textarea,
.tllm-root .tllm-root textarea {
  background: transparent !important;
  border: 0 !important;
  border-radius: 0 !important;
  padding: 0 !important;
  min-height: 0 !important;
  max-height: none !important;
  height: auto !important;
  outline: 0 !important;
  box-shadow: none !important;
  resize: none !important;
  font: inherit !important;
  color: inherit !important;
  line-height: var(--tllm-lh-snug) !important;
  -webkit-appearance: none !important;
  appearance: none !important;
}

.tllm-root input[type="text"],
.tllm-root input[type="search"] {
  background: transparent !important;
  border: 0 !important;
  border-radius: 0 !important;
  padding: 0 !important;
  min-height: 0 !important;
  height: auto !important;
  outline: 0 !important;
  box-shadow: none !important;
  font: inherit !important;
  color: inherit !important;
  -webkit-appearance: none !important;
  appearance: none !important;
}

/* Re-apply spec values on top of the nuked baseline */

.tllm-root .tllm-icon-btn {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 40px !important;
  height: 40px !important;
  border-radius: var(--tllm-r-md) !important;
  color: var(--tllm-ink-2) !important;
}
.tllm-root .tllm-icon-btn--sm {
  width: 32px !important;
  height: 32px !important;
  border-radius: var(--tllm-r-sm) !important;
}
.tllm-root .tllm-icon-btn:hover {
  background: var(--tllm-surface-3) !important;
  color: var(--tllm-ink) !important;
}
.tllm-root .tllm-icon-btn:disabled,
.tllm-root .tllm-icon-btn[disabled] {
  opacity: 0.45 !important;
  cursor: not-allowed !important;
}

.tllm-root .tllm-chat__composer-send {
  width: 40px !important;
  height: 40px !important;
  border-radius: 50% !important;
  background: var(--tllm-brand) !important;
  color: white !important;
  display: grid !important;
  place-items: center !important;
  box-shadow: 0 6px 16px rgba(15,76,129,.30) !important;
  flex: none !important;
}
.tllm-root .tllm-chat__composer-send:hover {
  background: var(--tllm-brand-hover) !important;
}

/* The textarea inside the composer needs its own spec value re-applied */
.tllm-root .tllm-chat__composer-input textarea {
  flex: 1 !important;
  max-height: 80px !important;
  padding: 8px 0 !important;
  font-size: var(--tllm-fs-body) !important;
  line-height: 1.4 !important;
  resize: none !important;
}

/* Buttons (.tllm-btn family) */
.tllm-root .tllm-btn {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 6px !important;
  padding: 10px 16px !important;
  border-radius: var(--tllm-r-md) !important;
  font-weight: var(--tllm-fw-semibold) !important;
  font-size: var(--tllm-fs-sm) !important;
  background: var(--tllm-surface) !important;
  color: var(--tllm-ink) !important;
  border: 1px solid var(--tllm-divider) !important;
  cursor: pointer !important;
  line-height: 1.4 !important;
}
.tllm-root .tllm-btn--sm { padding: 6px 12px !important; font-size: var(--tllm-fs-xs) !important; }
.tllm-root .tllm-btn--lg { padding: 14px 22px !important; font-size: var(--tllm-fs-body) !important; }
.tllm-root .tllm-btn--primary {
  background: var(--tllm-brand) !important;
  color: white !important;
  border-color: transparent !important;
  box-shadow: 0 4px 12px rgba(15,76,129,.25) !important;
}
.tllm-root .tllm-btn--primary:hover { background: var(--tllm-brand-hover) !important; }
.tllm-root .tllm-btn--ghost {
  background: transparent !important;
  border-color: var(--tllm-divider) !important;
  color: var(--tllm-ink-2) !important;
}
.tllm-root .tllm-btn--ghost:hover { background: var(--tllm-surface-3) !important; color: var(--tllm-ink) !important; }
.tllm-root .tllm-btn--danger {
  background: transparent !important;
  border-color: var(--tllm-divider) !important;
  color: var(--tllm-danger) !important;
}

/* Quick chip (empty state) */
.tllm-root .tllm-quick-chip {
  display: inline-flex !important;
  align-items: center !important;
  padding: 7px 12px !important;
  background: var(--tllm-surface) !important;
  border: 1px solid var(--tllm-divider) !important;
  border-radius: var(--tllm-r-pill) !important;
  color: var(--tllm-ink-2) !important;
  font-size: var(--tllm-fs-sm) !important;
  cursor: pointer !important;
  line-height: 1.4 !important;
}
.tllm-root .tllm-quick-chip:hover {
  border-color: var(--tllm-brand) !important;
  color: var(--tllm-brand) !important;
  background: var(--tllm-brand-tint) !important;
}

/* Dashboard convo items (we render as <button> not <div>) */
.tllm-root .tllm-convo {
  width: 100% !important;
  text-align: left !important;
  border-radius: var(--tllm-r-md) !important;
}

/* Dashboard filter chips (also rendered as <button>) */
.tllm-root .tllm-dashboard__filter {
  padding: 6px 12px !important;
  border-radius: var(--tllm-r-pill) !important;
  font-size: var(--tllm-fs-sm) !important;
  color: var(--tllm-ink-3) !important;
}
.tllm-root .tllm-dashboard__filter.tllm-is-active {
  background: var(--tllm-ink) !important;
  color: white !important;
}

/* Warn banner close (.tllm-chat__warn-close is a button — make sure it stays icon-shaped) */
.tllm-root .tllm-chat__warn-close {
  width: 24px !important;
  height: 24px !important;
  border-radius: var(--tllm-r-sm) !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  flex-shrink: 0 !important;
}


/* ==========================================================================
   20. Visual refinements (v1.5.85)
   --------------------------------------------------------------------------
   Per usability feedback:
     - Solid white background instead of glass blur (cleaner against
       page chrome, no more "gray-dirty" look)
     - Remove admin-bubble blue outline (looked like focus/error state)
     - Larger warn banner text + actual working X close
     - Composer icon-btn 「附加」 repurposed as decorative message hint
*/

/* The [hidden] attribute must win. Several chat elements (warn banner,
   empty/loading states, badges) carry an explicit `display` from the spec
   CSS, whose class specificity beats the UA `[hidden]{display:none}` rule —
   so toggling `.hidden = true` did NOT hide them (e.g. the fraud-warn close
   button "始終無法關閉"). This makes hidden authoritative module-wide. */
.tllm-root [hidden] { display: none !important; }

/* Solid white surface — drop the glass blur, keep a soft border + shadow */
.tllm-root .tllm-chat,
.tllm-root .tllm-dashboard {
  background: #ffffff !important;
  -webkit-backdrop-filter: none !important;
          backdrop-filter: none !important;
  border-color: var(--tllm-divider) !important;
}
.tllm-root .tllm-dashboard__list {
  background: var(--tllm-surface-2) !important;
}
.tllm-root .tllm-dashboard__thread {
  background: #ffffff !important;
}
.tllm-root .tllm-chat__composer {
  background: var(--tllm-surface-2) !important;
}

/* Remove the blue outline on admin-role bubbles — looked like focus state */
.tllm-root .tllm-bubble--admin {
  outline: 0 !important;
}

/* Warn banner — larger text, padding, more readable */
.tllm-root .tllm-chat__warn {
  padding: 14px 16px !important;
  gap: 10px !important;
  align-items: flex-start !important;
}
.tllm-root .tllm-chat__warn > div {
  font-size: var(--tllm-fs-sm) !important;     /* 16px after v1.5.85 lift */
  line-height: 1.55 !important;
  color: #92400E !important;
}
.tllm-root .tllm-chat__warn-icon { flex-shrink: 0 !important; margin-top: 2px; }

/* Bubble meta time — was 10px hard-coded, lift to readable 12px floor */
.tllm-root .tllm-bubble__meta {
  font-size: 12px !important;
  gap: 6px !important;
}

/* Read receipt checks — keep the SVG aspect ratio (was squished). */
.tllm-root .tllm-bubble__check {
  flex-shrink: 0 !important;
}
/* Sent (not yet read) — single gray ✓ */
.tllm-root .tllm-bubble__check--unread {
  color: var(--tllm-ink-4) !important;
}
/* Read — green ✓✓ + 「已讀」 text label (v1.5.95) */
.tllm-root .tllm-bubble__check--read {
  color: var(--tllm-success) !important;
}
.tllm-root .tllm-bubble__read-label {
  color: var(--tllm-success) !important;
  font-size: 12px !important;
  font-weight: var(--tllm-fw-medium) !important;
  white-space: nowrap !important;
  flex-shrink: 0 !important;
}

/* === 對方泡泡視覺加強 (v1.5.88 → v1.5.89) ===
   surface-3 (#EEF2F7) 太接近白底,實機看不出泡泡邊界。改用 #E5E7EB
   (gray-200) 並加更明顯的 border + 細微 shadow。 */
.tllm-root .tllm-bubble--theirs .tllm-bubble__body {
  /* Lighter, more refined gray (v1.5.101) — #E5E7EB read a touch heavy.
     A pale cool gray with a hairline border + faint shadow keeps it defined
     against the white thread without feeling like a solid block. */
  background: #F2F4F7 !important;
  border: 1px solid rgba(15, 23, 42, 0.06) !important;
  box-shadow: 0 1px 1.5px rgba(15, 23, 42, 0.04) !important;
  color: var(--tllm-ink) !important;
}

/* Auto-size check container per icon — single ✓ is square, double ✓✓ is 24x16 */
.tllm-root .tllm-bubble__check { width: auto !important; height: auto !important; }

/* Composer left icon — decorative message hint (no longer a + button).
   We swap the SVG via template; here we just style it as non-interactive. */
.tllm-root .tllm-chat__composer-hint {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 32px !important;
  height: 32px !important;
  color: var(--tllm-ink-4) !important;
  cursor: default !important;
  pointer-events: none;
  flex-shrink: 0;
}


/* ==========================================================================
   21. Dashboard page redesign (v1.5.90)
   --------------------------------------------------------------------------
   The dashboard lives on a full /parts/messages/ page, NOT a modal — so the
   spec's fixed 1080×720 box left dead space and a cramped sidebar, and the
   v1.5.85 type-scale lift (15px floor) made the sidebar text overflow its
   old spacing. This section:
     • fills the page container (drops the 1080 max-width cap)
     • re-aligns the sidebar header / search / filters / convo cards
     • collapses to a single pane below 860px (tablet + mobile)
   ========================================================================== */

/* ---- Shell: fill container, sensible page height ---- */
.tllm-root .tllm-dashboard {
  max-width: none !important;
  width: 100% !important;
  height: min(78vh, 820px) !important;
  min-height: 520px !important;
  border-radius: var(--tllm-r-lg) !important;
  box-shadow: var(--tllm-shadow-card) !important;
}

/* ---- Sidebar shell — scales with container, never too wide/narrow ---- */
.tllm-root .tllm-dashboard__list {
  width: clamp(300px, 32%, 380px) !important;
  flex: none !important;
  background: var(--tllm-surface-2) !important;
  border-right: 1px solid var(--tllm-divider) !important;
}

/* Header: title + count chip on one baseline */
.tllm-root .tllm-dashboard__head {
  padding: 18px 20px 14px !important;
  border-bottom: 1px solid var(--tllm-divider) !important;
}
.tllm-root .tllm-dashboard__title {
  display: flex !important;
  align-items: center !important;
  gap: 8px !important;
  font-size: var(--tllm-fs-h2) !important;   /* 22 — fs-h1 (28) was oversized in a 340px rail */
  font-weight: var(--tllm-fw-bold) !important;
  line-height: 1 !important;                 /* 1.2 made the text box taller than the
                                                badge, so center-alignment pushed the
                                                count visually lower ("數字往下掉") */
}
.tllm-root .tllm-dashboard__title-count {
  /* Vertical centering of the digit via line-height == height is the most
     reliable for a single glyph (flex `align-items:center` left the "1"
     sitting low because the line box descent isn't symmetric). The badge
     itself centers in the title row as a 22px flex item. */
  display: inline-block !important;
  align-self: center !important;
  box-sizing: border-box !important;
  min-width: 22px !important;
  height: 22px !important;
  padding: 0 7px !important;
  margin: 0 !important;
  background: var(--tllm-brand) !important;
  color: #fff !important;
  font-size: var(--tllm-fs-xs) !important;
  font-weight: var(--tllm-fw-bold) !important;
  border-radius: var(--tllm-r-pill) !important;
  line-height: 22px !important;              /* == height → digit vertically centered */
  text-align: center !important;             /* horizontal center */
}

/* Search box — flat card, not a floating pill */
.tllm-root .tllm-dashboard__search { padding: 12px 16px 8px !important; }
.tllm-root .tllm-dashboard__search-input {
  background: #fff !important;
  border: 1px solid var(--tllm-divider) !important;
  border-radius: var(--tllm-r-md) !important;
  padding: 9px 12px !important;
  gap: 8px !important;
}
.tllm-root .tllm-dashboard__search-input input {
  font-size: var(--tllm-fs-sm) !important;
}

/* Filter pill tabs */
.tllm-root .tllm-dashboard__filters {
  padding: 4px 16px 12px !important;
  gap: 6px !important;
  border-bottom: 1px solid var(--tllm-divider) !important;
}

/* Items list — vertical rhythm with small gaps */
.tllm-root .tllm-dashboard__items {
  padding: 8px 10px 16px !important;
  display: flex !important;
  flex-direction: column !important;
  /* 2px read as "stuck together" — the preview line of one card almost touched
     the next card's name. 8px gives each conversation card clear breathing room
     below its preview text without making the list feel sparse. */
  gap: 8px !important;
}

/* ---- Convo card ---- */
.tllm-root .tllm-convo {
  width: 100% !important;
  display: flex !important;
  gap: 12px !important;
  align-items: flex-start !important;
  padding: 12px !important;
  border-radius: var(--tllm-r-md) !important;
  text-align: left !important;
  background: transparent !important;
  border: 1px solid transparent !important;
  position: relative !important;
  transition: background var(--tllm-dur-fast) !important;
  /* The list (.tllm-dashboard__items / .tshp-chat-mini__items) is a fixed-height
     flex column with overflow-y:auto. Without this, the rows are flex children
     with the default flex-shrink:1, so once the conversations overflow the
     panel the browser COMPRESSES each row below its 3-line content — the
     preview text spills out the bottom and overlaps the next row, and the
     hover/active highlight (sized to the squashed row) no longer wraps the
     content. flex-shrink:0 keeps every row at its natural height and lets the
     container scroll instead. (Verified live on production — a static harness
     can't reproduce it because an unconstrained list never triggers shrink.) */
  flex-shrink: 0 !important;
}
.tllm-root .tllm-convo:hover { background: rgba(15, 23, 42, 0.04) !important; }
.tllm-root .tllm-convo.tllm-is-active {
  background: #fff !important;
  border-color: var(--tllm-divider) !important;
  box-shadow: var(--tllm-shadow-card) !important;
}
/* Active accent bar on the left edge */
.tllm-root .tllm-convo.tllm-is-active::before {
  content: "" !important;
  position: absolute !important;
  left: 0;
  top: 12px;
  bottom: 12px;
  width: 3px !important;
  border-radius: 0 3px 3px 0 !important;
  background: var(--tllm-brand) !important;
}

/* Conversation row media: product thumbnail (primary) + small seller avatar
   overlapping the corner — so same-seller-different-product rows are told
   apart at a glance by the product image. */
.tllm-root .tllm-convo__media {
  position: relative !important;
  flex: none !important;
  width: 48px !important;
  height: 48px !important;
}
.tllm-root .tllm-convo__thumb {
  width: 48px !important;
  height: 48px !important;
  border-radius: 12px !important;
  overflow: hidden !important;
  background: var(--tllm-surface-3) !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  color: var(--tllm-ink-4) !important;
}
.tllm-root .tllm-convo__thumb img {
  width: 100% !important;
  height: 100% !important;
  object-fit: cover !important;
  display: block !important;
}
/* Small seller avatar overlay — override the generic 44px convo-avatar size */
.tllm-root .tllm-convo__avatar {
  position: absolute !important;
  right: -5px !important;
  bottom: -5px !important;
  width: 24px !important;
  height: 24px !important;
  min-width: 0 !important;
  font-size: 10px !important;
  font-weight: 700 !important;
  border: 2px solid #fff !important;
  box-sizing: border-box !important;
}

.tllm-root .tllm-convo__body { flex: 1 !important; min-width: 0 !important; line-height: 1.35 !important; }
.tllm-root .tllm-convo__top { display: flex !important; align-items: baseline !important; gap: 8px !important; }
.tllm-root .tllm-convo__name {
  flex: 1 !important;
  min-width: 0 !important;
  font-size: var(--tllm-fs-body) !important;   /* 17 */
  font-weight: var(--tllm-fw-semibold) !important;
  color: var(--tllm-ink) !important;
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
}
.tllm-root .tllm-convo__time {
  font-size: var(--tllm-fs-xs) !important;       /* 15 */
  color: var(--tllm-ink-4) !important;
  white-space: nowrap !important;
  flex: none !important;
}

/* Product reference — inline icon + text (matches spec dashboard mock).
   v1.5.90 made this a filled brand pill which read too heavy; reverted to
   the spec's subtle inline treatment per 站主 reference screenshot. */
.tllm-root .tllm-convo__product {
  display: flex !important;
  align-items: center !important;
  gap: 5px !important;
  margin-top: 5px !important;
  max-width: 100% !important;
  padding: 0 !important;
  background: transparent !important;
  border-radius: 0 !important;
  font-size: var(--tllm-fs-xs) !important;       /* 15 */
  color: var(--tllm-brand) !important;
  font-weight: var(--tllm-fw-medium) !important;
}
.tllm-root .tllm-convo__product svg { flex: none !important; opacity: 0.9; }
.tllm-root .tllm-convo__product-title {
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  white-space: nowrap !important;
  min-width: 0 !important;
}

.tllm-root .tllm-convo__preview {
  display: flex !important;
  align-items: center !important;
  gap: 6px !important;
  margin-top: 7px !important;
}
.tllm-root .tllm-convo__preview-text {
  flex: 1 !important;
  min-width: 0 !important;
  font-size: var(--tllm-fs-xs) !important;       /* 15 */
  color: var(--tllm-ink-3) !important;
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
}
.tllm-root .tllm-convo.tllm-is-unread .tllm-convo__name,
.tllm-root .tllm-convo.tllm-is-unread .tllm-convo__preview-text {
  color: var(--tllm-ink) !important;
  font-weight: var(--tllm-fw-bold) !important;
}
.tllm-root .tllm-convo__unread {
  /* Vertically center the digit via line-height == height (NOT flex —
     flex/align-items:center left the number sitting low, the recurring
     badge-centering bug). No border here, so line-height = full height. */
  flex: none !important;
  display: inline-block !important;
  box-sizing: border-box !important;
  min-width: 20px !important;
  height: 20px !important;
  padding: 0 6px !important;
  background: var(--tllm-brand) !important;
  color: #fff !important;
  border-radius: var(--tllm-r-pill) !important;
  font-size: 12px !important;
  font-weight: var(--tllm-fw-bold) !important;
  line-height: 20px !important;
  text-align: center !important;
}

/* Sidebar empty state (no conversations) — center, breathing room */
.tllm-root .tllm-dashboard__list .tllm-dashboard__empty {
  padding: 48px 24px !important;
}

/* ---- RWD: collapse to single pane below 860px (tablet + mobile) ----
   Bumped from the spec's 768 because a 300px sidebar + thread gets cramped
   sooner than that on the embedded page. Must also reveal the back button
   here so the user isn't stranded in thread view between 768–860. */
@media (max-width: 860px) {
  .tllm-root .tllm-dashboard {
    height: min(82vh, 760px) !important;
    border-radius: var(--tllm-r-md) !important;
  }
  .tllm-root .tllm-dashboard__list {
    width: 100% !important;
  }
  .tllm-root .tllm-dashboard .tllm-dashboard__mobile-back { display: inline-flex !important; }
  .tllm-root .tllm-dashboard.is-list-view .tllm-dashboard__thread { display: none !important; }
  .tllm-root .tllm-dashboard.is-thread-view .tllm-dashboard__list { display: none !important; }

  /* Thread view = full-screen fixed overlay on mobile. Kills the nested-scroll
     jank (page scroll + inner thread scroll fighting, footer peeking below).
     Now there's ONE scroll context — the message thread — with the composer
     pinned at the bottom; nothing else is visible to scroll. The ← back
     button (data-tshp-thread-back) drops it back to the in-flow list view. */
  .tllm-root .tllm-dashboard.is-thread-view {
    position: fixed !important;
    inset: 0 !important;
    width: 100% !important;
    max-width: none !important;
    height: 100vh !important;
    height: 100dvh !important;           /* excludes mobile browser chrome */
    min-height: 0 !important;
    border-radius: 0 !important;
    z-index: 100000 !important;
  }
  /* The thread is the single scrollable area; composer stays pinned (flex). */
  .tllm-root .tllm-dashboard.is-thread-view .tllm-dashboard__thread {
    height: 100% !important;
    min-height: 0 !important;
    min-width: 0 !important;   /* belt-and-suspenders for iOS WebKit webviews */
  }
  /* Keep 查看商品 on its line; the title beside it takes the ellipsis instead. */
  .tllm-root .tllm-dashboard.is-thread-view .tllm-chat__pinned .tllm-btn {
    flex: none !important;
  }
}


/* ==========================================================================
   22. Floating chat launcher (FAB) — single product pages (v1.5.97)
   --------------------------------------------------------------------------
   Persistent always-visible entry to the chat popup on listings that accept
   站內傳訊. Sits at bottom-right ABOVE the theme's back-to-top button
   (bottom:100px clearance). Unread count shows as a circular badge on the
   outer top-right edge.
   ========================================================================== */
.tshp-chat-fab-root { position: static; }

.tllm-root .tshp-chat-fab {
  position: fixed !important;
  right: 24px !important;
  bottom: 100px !important;            /* clears the ~40x40 back-to-top below it */
  z-index: 99990 !important;
  width: 52px !important;
  height: 52px !important;
  min-width: 0 !important;
  min-height: 0 !important;
  padding: 0 !important;
  border-radius: 50% !important;
  border: 0 !important;
  background: var(--tllm-brand) !important;
  color: #fff !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  box-shadow: 0 6px 20px rgba(15, 76, 129, 0.40), 0 2px 6px rgba(15, 23, 42, 0.18) !important;
  cursor: pointer !important;
  transition: transform var(--tllm-dur-fast) var(--tllm-ease),
              background var(--tllm-dur-fast) var(--tllm-ease),
              box-shadow var(--tllm-dur-fast) var(--tllm-ease) !important;
}
.tllm-root .tshp-chat-fab:hover {
  background: var(--tllm-brand-hover) !important;
  transform: translateY(-2px) !important;
  box-shadow: 0 10px 28px rgba(15, 76, 129, 0.46), 0 3px 8px rgba(15, 23, 42, 0.20) !important;
}
.tllm-root .tshp-chat-fab:active { transform: translateY(0) scale(0.96) !important; }
.tllm-root .tshp-chat-fab svg { width: 26px !important; height: 26px !important; flex: none !important; }

/* Gentle attention pulse on first paint (stops after a few cycles) */
.tllm-root .tshp-chat-fab::after {
  content: "" !important;
  position: absolute !important;
  inset: 0 !important;
  border-radius: 50% !important;
  border: 2px solid var(--tllm-brand) !important;
  opacity: 0 !important;
  animation: tshp-fab-pulse 2.4s ease-out 3 !important;
  pointer-events: none !important;
}
@keyframes tshp-fab-pulse {
  0%   { opacity: 0.55; transform: scale(1); }
  70%  { opacity: 0;    transform: scale(1.6); }
  100% { opacity: 0;    transform: scale(1.6); }
}

/* Unread badge — circular label on the outer top-right edge.
   Center the digit via line-height == CONTENT height. Box is 20px tall with a
   2px white border (border-box) → content area = 16px → line-height: 16px.
   (Same line-height technique as the convo + header badges — the reliable fix
   for the recurring "數字往下掉" bug.) */
.tllm-root .tshp-chat-fab__badge {
  position: absolute !important;
  top: -4px !important;
  right: -4px !important;
  min-width: 20px !important;
  height: 20px !important;
  padding: 0 4px !important;
  box-sizing: border-box !important;
  display: inline-block !important;
  border-radius: var(--tllm-r-pill) !important;
  background: var(--tllm-danger) !important;
  color: #fff !important;
  font-size: 12px !important;
  font-weight: var(--tllm-fw-bold) !important;
  line-height: 16px !important;   /* 20px box − 2*2px border */
  text-align: center !important;
  border: 2px solid #fff !important;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.25) !important;
}
.tllm-root .tshp-chat-fab__badge[hidden] { display: none !important; }

/* Mobile: compact 40x40 to match the back-to-top, lifted to 120px, flat
   (no box-shadow per 站主 spec). */
@media (max-width: 768px) {
  .tllm-root .tshp-chat-fab {
    right: 12px !important;
    bottom: 120px !important;
    width: 40px !important;
    height: 40px !important;
    box-shadow: none !important;
  }
  .tllm-root .tshp-chat-fab:hover { box-shadow: none !important; }
  .tllm-root .tshp-chat-fab svg { width: 20px !important; height: 20px !important; }
}

/* Respect reduced-motion */
@media (prefers-reduced-motion: reduce) {
  .tllm-root .tshp-chat-fab::after { animation: none !important; }
  .tllm-root .tshp-chat-fab { transition: none !important; }
}


/* ==========================================================================
   23. Mini conversations launcher panel (v1.5.100)
   --------------------------------------------------------------------------
   Opened from the marketplace bubble FAB. A compact .tllm-chat-sized overlay
   showing the conversations list; picking one opens it in the chat popup.
   ========================================================================== */
.tshp-chat-mini {
  position: fixed !important;
  inset: 0 !important;
  z-index: 100000 !important;
}
.tshp-chat-mini[hidden] { display: none !important; }

/* The mini panel is the chat shell sized for a list — softer, rounder. */
.tllm-root .tshp-chat-mini__panel {
  height: min(640px, 86vh) !important;
  border-radius: var(--tllm-r-xl) !important;   /* 28px — softer, "圓潤" */
  overflow: hidden !important;
}

/* Refined header (v1.5.113): leading soft-rounded chat icon, cleaner title,
   pill close button — replaces the plain left-aligned title + bare X. */
.tllm-root .tshp-chat-mini__head {
  align-items: center !important;
  gap: 12px !important;
  padding: 16px 16px 14px !important;
  background: var(--tllm-surface-2) !important;
  border-bottom: 1px solid var(--tllm-divider) !important;
}
.tllm-root .tshp-chat-mini__head-icon {
  flex: none !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 40px !important;
  height: 40px !important;
  border-radius: 14px !important;
  background: var(--tllm-brand-tint) !important;
  color: var(--tllm-brand) !important;
}
.tllm-root .tshp-chat-mini__head .tllm-chat__head-name {
  font-size: var(--tllm-fs-h2) !important;   /* 22 — a touch bolder */
  font-weight: var(--tllm-fw-bold) !important;
}
.tllm-root .tshp-chat-mini__head .tllm-chat__head-sub {
  color: var(--tllm-ink-3) !important;
  margin-top: 1px !important;
}
/* Soft circular close button (image-2 style) — SHARED by the mini list
   header and the 1-on-1 popup header so the X looks identical in both. */
.tllm-root .tshp-chat-xbtn {
  flex: none !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 36px !important;
  height: 36px !important;
  min-width: 0 !important;
  min-height: 0 !important;
  border-radius: 50% !important;
  background: var(--tllm-surface-3) !important;
  color: var(--tllm-ink-2) !important;
  border: 0 !important;
  padding: 0 !important;
  cursor: pointer !important;
  transition: background var(--tllm-dur-fast), color var(--tllm-dur-fast) !important;
}
.tllm-root .tshp-chat-xbtn:hover {
  background: var(--tllm-divider) !important;
  color: var(--tllm-ink) !important;
}
/* `[hidden]` must beat the inline-flex !important above (back button toggles
   on only when the popup was opened from the mini conversations list). */
.tllm-root .tshp-chat-xbtn[hidden] { display: none !important; }
/* Back button sits at the head's left edge — small gap before the avatar. */
.tllm-root .tshp-chat-backbtn { margin-right: 2px !important; }

/* List scroll area inside the mini panel.
   gap matches .tllm-dashboard__items (8px) so the popup "bubble list" and the
   full-page dashboard list read identically — previously 2px here made the
   popup rows look cramped next to the dashboard's roomier cards. */
.tllm-root .tshp-chat-mini__items {
  flex: 1 !important;
  overflow-y: auto !important;
  padding: 8px 10px 16px !important;
  display: flex !important;
  flex-direction: column !important;
  gap: 8px !important;
}

/* Empty state */
.tllm-root .tshp-chat-mini__empty {
  flex: 1 !important;
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: center !important;
  text-align: center !important;
  gap: 10px !important;
  padding: 40px 28px !important;
}
.tllm-root .tshp-chat-mini__empty .tllm-meta { line-height: 1.6 !important; }

/* Mobile: full-screen like the chat popup */
@media (max-width: 480px) {
  .tllm-root .tshp-chat-mini__panel {
    max-width: none !important;
    width: 100% !important;
    height: 100% !important;
    border-radius: 0 !important;
  }
}


/* ==========================================================================
   24. Chat header / thread separation (v1.5.104)
   --------------------------------------------------------------------------
   The spec borders used --tllm-glass-border (white, for frosted surfaces).
   After v1.5.85 switched the panel to SOLID white, those borders went
   invisible (white-on-white) so the header zone (name + pinned product)
   blended into the message thread. Give the header zone a faint tint + a
   crisp hairline so it reads as a distinct, refined chat-box header.
   ========================================================================== */
.tllm-root .tllm-chat__head {
  background: var(--tllm-surface-2) !important;          /* #F8FAFC barely-off-white */
  border-bottom: 1px solid var(--tllm-divider-2) !important;  /* faint line within header zone */
}
.tllm-root .tllm-chat__pinned {
  background: var(--tllm-surface-2) !important;
  border-bottom: 1px solid var(--tllm-divider) !important;    /* the clear separator before the thread */
}
/* Thread sits on pure white below the hairline */
.tllm-root .tllm-chat__thread {
  background: #ffffff !important;
  /* Keep over-scroll inside the thread — don't chain to the page/body behind
     (prevents the mobile "scroll thread then the whole page scrolls" jank). */
  overscroll-behavior: contain !important;
}
