.thread-pane { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.inbox-shell > .thread-pane { overflow: hidden; } /* the messages area scrolls, never the pane: the composer stays in view */

.thread-header { flex-shrink: 0; display: flex; flex-direction: column; border-bottom: 1px solid var(--line); background: var(--surface); }
.thread-header:focus-visible { outline: none; } /* focusable by script only (tabindex -1), so it needs no ring of its own */
.thread-header-top { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); padding: var(--sp-3); }
.thread-header-info { flex: 1 1 140px; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.thread-header-name { margin: 0; font-family: var(--serif); font-size: var(--fs-xl); font-weight: 600; line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.thread-header-phone { font-size: var(--fs-sm); }
.window-chip { display: inline-flex; align-items: center; padding: 1px var(--sp-2); border-radius: var(--r-pill); font-size: var(--fs-sm); width: fit-content; white-space: nowrap; }
.window-chip.open { background: var(--ok-soft); color: var(--ok); }
.window-chip.closed { background: var(--neutral-soft); color: var(--muted); }
.thread-lock-banner, .thread-banner { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-2); padding: var(--sp-2) var(--sp-3); background: linear-gradient(var(--warn-soft), var(--warn-soft)), var(--surface-2); color: var(--warn); font-size: var(--fs-sm); }
.avatar.skeleton { background: var(--surface-2); } /* the header's stand-in while the contact is not known yet */
/* A claim, release or retry in flight: the button keeps focus but does nothing until the request ends. */
.thread-pane .btn[aria-disabled="true"], .thread-pane .btn[aria-disabled="true"]:hover { opacity: 0.5; cursor: progress; background: var(--surface-2); }

/* Rows are rebuilt on every thread change and the scroll offset is set by script: browser scroll anchoring must stay out of it. */
/* The messages band is inset one step below the header and composer. That is what lets an incoming bubble
   read as raised paper without needing a border: --bubble-in is lighter than --surface-2 in both themes. */
.thread-messages { flex: 1; min-height: 0; overflow-y: auto; overflow-anchor: none; display: flex; flex-direction: column; padding: var(--sp-3); background: var(--surface-2); }
.thread-messages:focus-visible { outline-offset: -2px; }
.thread-older { flex: none; align-self: center; min-height: 32px; display: flex; align-items: center; margin-bottom: var(--sp-2); }
.thread-older:empty { display: none; }
.thread-older .state { padding: var(--sp-1) var(--sp-3); }
.thread-list { flex: 1 0 auto; display: flex; flex-direction: column; gap: var(--sp-2); }
.day-divider { align-self: center; font-size: var(--fs-sm); color: var(--muted); background: var(--neutral-soft); padding: 1px var(--sp-3); border-radius: var(--r-pill); margin: var(--sp-2) 0; }
.bubble-row { display: flex; }
.bubble-row.out { justify-content: flex-end; }
/* --r-lg belongs to speech bubbles and nothing else. Chrome is 8px, containers 12px: the radius tells you
   which of the three you are looking at. */
.bubble { max-width: 70%; padding: var(--sp-2) var(--sp-3); border-radius: var(--r-lg); display: flex; flex-direction: column; gap: 2px; }
.bubble.in { background: var(--bubble-in); }
.bubble.out { background: var(--bubble-out); }
.bubble-text { white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word; margin: 0; }
.bubble-revoked { font-style: italic; color: var(--muted); }
/* Sits inside either bubble color, so it carries a border as well as a fill: no single fill separates from
   both --bubble-in and --bubble-out in both themes. */
.bubble-media { display: flex; flex-direction: column; gap: 2px; padding: var(--sp-2); border-radius: var(--r-sm); border: 1px solid var(--line); background: var(--neutral-soft); }
.bubble-error { margin: 0; font-size: var(--fs-sm); color: var(--danger); }
.bubble-meta { display: flex; align-items: center; gap: var(--sp-1); font-size: 11px; color: var(--muted); align-self: flex-end; }
.tick-double-read { color: var(--info); }
.tick-failed { color: var(--danger); }

.thread-composer { flex-shrink: 0; border-top: 1px solid var(--line); padding: var(--sp-3); display: flex; flex-direction: column; gap: var(--sp-2); }
.composer-hint { margin: 0; font-size: var(--fs-sm); color: var(--muted); }
.composer-row { display: flex; gap: var(--sp-2); }
.composer-row textarea { flex: 1; resize: none; min-height: 40px; padding: var(--sp-2) var(--sp-3); border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--bg); }
.composer-row textarea:disabled { cursor: not-allowed; opacity: 0.6; }

@media (max-width: 899px) {
  /* The thread's height comes from the single-pane shell (app.css); only the bubble width changes here. */
  .bubble { max-width: 85%; }
}
