/* ===========================================================
   FEED — two panes: chat list and conversation
   Reference layout: Documents/MVP/robi_v1_cockpit.html:451-506 (R2.7)
   =========================================================== */

/* The shell caps every screen at 1100px and scrolls `.main` itself
   (frontend/shell.css:99-100). The feed takes the full height instead and
   scrolls inside its two panes, so `.main` is left with nothing to scroll. */
.screen--feed { max-width: 1200px; height: 100%; }

.feed2 { height: 100%; display: grid; grid-template-columns: 340px 1fr;
  background: var(--qb-surface); border: 1px solid var(--qb-border);
  border-radius: var(--qb-r-xl); overflow: hidden; }

/* --- Chat list pane ----------------------------------------- */
.chatlist { display: flex; flex-direction: column; min-height: 0;
  border-inline-end: 1px solid var(--qb-border); }
.chatlist__filter { padding: var(--qb-s-12); border-block-end: 1px solid var(--qb-border); }
.chatlist__filter .seg { display: flex; width: 100%; }
.chatlist__filter .seg button { flex: 1; padding: 0 6px; }
.chatlist__scroll { flex: 1; overflow-y: auto; }

/* --- Conversation pane -------------------------------------- */
.conv { display: flex; flex-direction: column; min-height: 0; }
.conv__head { height: var(--qb-topbar-h); flex: none; display: flex; align-items: center;
  gap: var(--qb-s-12); padding: 0 var(--qb-s-16); border-block-end: 1px solid var(--qb-border); }
.conv__thread { flex: 1; overflow-y: auto; padding: var(--qb-s-24); display: flex;
  flex-direction: column; gap: var(--qb-s-12); background: var(--qb-bg-app); }

/* The head of the "no chat selected" pane carries nothing but the back
   control, so it exists only where that control does — below the threshold. */
.conv__head--empty { display: none; }
.conv__back { display: none; }
html[dir="ltr"] .conv__back svg { transform: scaleX(-1); }

/* --- "No chat selected" (R2.5) ------------------------------- */
.feed-empty { flex: 1; display: grid; place-items: center; align-content: center;
  gap: var(--qb-s-12); padding: var(--qb-s-32); text-align: center;
  color: var(--qb-fg-3); background: var(--qb-bg-app); }
.feed-empty svg { width: 40px; height: 40px; color: var(--qb-fg-4); }

/* The same block inside the chat list pane (task 10). It fills the pane so the
   notice sits in the middle of it rather than at the top, and it keeps the
   pane's own surface: `--qb-bg-app` belongs to the thread, not here. */
.chatlist__scroll .feed-empty { min-height: 100%; box-sizing: border-box;
  background: var(--qb-surface); }

/* --- Filter, chat rows, chips (task 3) ----------------------
   Reference: Documents/MVP/robi_v1_cockpit.html:320-324, 466-489 (R2.7) */
.seg { display: inline-flex; background: var(--qb-surface-muted); border-radius: var(--qb-r-md);
  padding: 3px; gap: 2px; }
.seg button { border: 0; background: transparent; height: 30px; padding: 0 14px;
  border-radius: var(--qb-r-sm); font-size: 13px; font-weight: 600; color: var(--qb-fg-2);
  cursor: pointer; font-family: inherit; }
.seg button.is-active { background: var(--qb-surface); color: var(--qb-fg-1); box-shadow: var(--qb-shadow-sm); }

.chatrow { display: flex; gap: 12px; align-items: center; width: 100%; text-align: start; border: 0;
  background: transparent; cursor: pointer; padding: 12px 16px; font-family: inherit;
  border-block-end: 1px solid var(--qb-border); }
.chatrow:hover { background: var(--qb-surface-2); }
.chatrow__av { width: 40px; height: 40px; border-radius: 50%; background: var(--qb-surface-muted);
  color: var(--qb-fg-2); display: grid; place-items: center; font-weight: 700; font-size: 15px; flex: none; }
.chatrow__main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.chatrow__top { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.chatrow__name { font-weight: 600; font-size: 14px; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }
.chatrow__time { font-size: 11px; color: var(--qb-fg-3); flex: none; }
.chatrow__prev { display: flex; align-items: center; gap: 6px; color: var(--qb-fg-2); font-size: 13px;
  min-width: 0; }
.chatrow__prev svg { width: 14px; height: 14px; flex: none; }
.chatrow__prev .prevtext { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Direction mark of the last message: an icon, not a text prefix - the list is
   narrow and the mark must not eat the preview (R3.6). */
.chatrow__dir { display: inline-flex; flex: none; color: var(--qb-fg-3); }
.chatrow__meta { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.chatrow__chips { display: flex; align-items: center; gap: 6px; min-width: 0; }
/* Unread counter (task 8). Reference: robi_v1_cockpit.html:487-488, with one
   change - the fill is `--qb-orange-deep`, not `--qb-orange`. The token file
   says it in as many words (`frontend/tokens.css:7-13`): the spark orange is
   for fills, white on it is 3.28:1, and this badge is a number that has to be
   read. White on deep is 5.83:1. */
.unread { min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--qb-r-pill);
  background: var(--qb-orange-deep); color: var(--qb-fg-on-brand); font-size: 11px;
  font-weight: 700; display: grid; place-items: center; flex: none;
  font-variant-numeric: tabular-nums; }

.chip { display: inline-flex; align-items: center; gap: 5px; height: 22px; padding: 0 8px;
  border-radius: var(--qb-r-pill); background: var(--qb-surface-muted); color: var(--qb-fg-2);
  font-size: 11px; font-weight: 600; max-width: 100%; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }
.chip svg { width: 12px; height: 12px; flex: none; }
.chip__txt { overflow: hidden; text-overflow: ellipsis; }

/* --- Thread: message cards (task 4) --------------------------
   Reference: Documents/MVP/robi_v1_cockpit.html:329-338 (R2.7) */
.chatrow.is-active { background: var(--qb-orange-light); }
.chatrow.is-active .chatrow__av { background: var(--qb-orange); color: var(--qb-fg-on-brand); }

.conv__title { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.conv__name { font-weight: 600; font-size: 15px; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }

/* 660px is the reference width of a message (robi_v1_cockpit.html:499). The
   share is added on top of it: at 1280px the thread pane is about 600px wide,
   a 660px card fills it edge to edge, and an auto margin has no free space
   left to push anything with - the sides would stop differing at the very
   width the cockpit is used at (R5.2). */
.conv__thread .msg { width: 100%; max-width: min(660px, 85%); }
.msg { background: var(--qb-surface); border: 1px solid var(--qb-border);
  border-radius: var(--qb-r-xl); padding: var(--qb-s-16); }

/* Sides of the conversation, by logical properties only (design D9).
   `float` and `text-align: left|right` are banned by rule 6 of the gate, and
   the ban is not a formality: on Hebrew the screen mirrors, and a physical
   property would put our own message on the wrong side (R5.7). */
.msg { margin-inline-end: auto; }
.msg--out { margin-inline-start: auto; margin-inline-end: 0;
  background: var(--qb-orange-lighter); border-color: var(--qb-orange-light); }
.msg__head { display: flex; align-items: center; gap: var(--qb-s-12); margin-bottom: var(--qb-s-12); }
.msg__who { flex: 1; display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
.msg__name { font-size: 14px; font-weight: 600; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }
/* Kind of the message, taken from message_type: a photo with a caption is
   still a photo (R4.3). */
.msg__type { display: inline-flex; color: var(--qb-fg-3); flex: none; }
.msg__type svg { width: 16px; height: 16px; }
.msg__time { font-size: 12px; color: var(--qb-fg-3); flex: none; }
.msg__text { font-size: 15px; line-height: var(--qb-lh-relaxed); white-space: pre-wrap;
  overflow-wrap: anywhere; }

/* --- Paging the thread (task 9) ------------------------------
   The sentinel has height: a zero-height element sitting flush against the top
   of a scrolled container is a coin toss for the observer. 1px of margin above
   it keeps it inside the scrollable area. */
.thread__top { height: 24px; flex: none; }
.conv__thread:focus-visible { outline: 2px solid var(--qb-orange); outline-offset: -2px; }

/* The previous page did not load. Sits where the missing messages would have
   been, above the oldest one drawn (R9.3). Not a marker of an incomplete
   history - that one is forbidden (R9.6). */
.thread__pageerror { display: flex; align-items: center; justify-content: center;
  gap: var(--qb-s-8); flex-wrap: wrap; padding: var(--qb-s-8) var(--qb-s-12);
  border: 1px dashed var(--qb-danger); border-radius: var(--qb-r-md);
  background: var(--qb-danger-bg); color: var(--qb-danger); font-size: 13px; }
.thread__retry { font: inherit; color: inherit; background: transparent;
  border: 1px solid currentColor; border-radius: var(--qb-r-sm);
  padding: 2px var(--qb-s-8); cursor: pointer; }
.thread__retry:hover { background: var(--qb-surface); }

.msg__media { display: flex; flex-direction: column; gap: var(--qb-s-8); margin-block-start: var(--qb-s-12); }
.msg__att { display: flex; align-items: center; gap: var(--qb-s-8); padding: var(--qb-s-8) var(--qb-s-12);
  background: var(--qb-surface-2); border: 1px solid var(--qb-border); border-radius: var(--qb-r-md);
  color: var(--qb-fg-2); }
.msg__att svg { width: 18px; height: 18px; flex: none; }
.msg__badge { display: inline-flex; align-items: center; height: 22px; padding: 0 8px;
  border-radius: var(--qb-r-pill); font-size: 11px; font-weight: 600; }
.msg__badge--voice { background: var(--qb-orange-light); color: var(--qb-orange-deep); }

.msg__marks { display: flex; align-items: center; gap: var(--qb-s-8); margin-block-start: var(--qb-s-8); }
.msg__edited { font-size: 12px; color: var(--qb-fg-3); background: transparent; border: 0;
  padding: 0; font-family: inherit; }
.msg__edited--link { cursor: pointer; text-decoration: underline; }
.msg__edited--link:hover { color: var(--qb-fg-2); }
/* Momentary mark on the message an edit points at, so the jump lands
   somewhere the eye can find (R4.4). */
.msg.is-linked { outline: 2px solid var(--qb-orange); outline-offset: 2px; }

/* --- Voice note and transcription (task 6) -------------------
   Reference: Documents/MVP/robi_v1_cockpit.html:340-359 (R2.7). The prototype
   drew a fake waveform and its own play button; the player here is the
   browser's own `audio` element, per D11 - seeking is required (R7.2) and the
   native control brings it, along with its keyboard and its screen reader. */
.msg__att.voice { background: var(--qb-surface-3); border-color: transparent; }
.voice__audio { flex: 1; min-width: 0; height: 36px; }
.voice__dur { font-size: 12px; color: var(--qb-fg-2); flex: none; }

/* --- Photo and unavailable attachment (task 7) ---------------
   Reference: Documents/MVP/robi_v1_cockpit.html:361-366 (R2.7). The prototype
   drew a fixed 170px placeholder; a real photo is evidence, so it is scaled
   down to fit and never cropped - `object-fit: cover` would cut off the very
   corner of the wall the cablan photographed. */
.msg__att.photo { display: block; padding: 0; border: 0; background: none; }
.photo__img { display: block; max-width: 100%; max-height: 320px;
  border: 1px solid var(--qb-border); border-radius: var(--qb-r-md); }

/* A file that has not arrived, or whose request failed: a dashed row saying
   so. Not a player with nothing behind it and not a broken-image icon
   (R7.3, R7.4). */
.msg__att--off { border-style: dashed; color: var(--qb-fg-3); }
.msg__att-note { font-size: 12px; }

.stt { border: 1px solid var(--qb-border); border-radius: var(--qb-r-lg);
  padding: var(--qb-s-12); background: var(--qb-surface-2); margin-block-start: var(--qb-s-12); }
.stt__label { display: flex; align-items: center; gap: var(--qb-s-8); flex-wrap: wrap; }
.stt__text { font-size: 14px; line-height: var(--qb-lh-relaxed); margin-block-start: var(--qb-s-8);
  white-space: pre-wrap; overflow-wrap: anywhere; }
.stt__multiple { font-size: 11px; color: var(--qb-fg-3); }

.stt__badge { background: var(--qb-surface-muted); color: var(--qb-fg-2); }
.stt__badge--transcribed { background: var(--qb-success-bg); color: var(--qb-success); }
.stt__badge--processing { background: var(--qb-info-bg); color: var(--qb-info); }
.stt__badge--error { background: var(--qb-danger-bg); color: var(--qb-danger); }
/* `anomaly` gets the neutral badge and nothing else: it must not borrow the
   look of `processing` or of `transcribed` (R6.5), and it is not a failure the
   manager can act on either. */
.stt__badge--anomaly { background: var(--qb-surface-muted); color: var(--qb-fg-2); }

.stt--error { background: var(--qb-danger-bg); border-color: var(--qb-danger-bg); }
.stt--anomaly { background: var(--qb-surface-2); border-style: dashed; }

/* Skeleton instead of text while the transcript is on its way. */
.stt__skeleton { height: 12px; border-radius: 6px; margin-block-start: var(--qb-s-8);
  background: linear-gradient(90deg, var(--qb-surface-3), var(--qb-surface), var(--qb-surface-3));
  background-size: 200% 100%; animation: qb-stt-skeleton 1.2s linear infinite; }
.stt__skeleton.w80 { width: 80%; }
.stt__skeleton.w60 { width: 60%; }
@keyframes qb-stt-skeleton {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .stt__skeleton { animation: none; }
}

/* --- 769-900px: the list takes a share, not a fixed 340px -----
   Both panes split what is left of the window after the 240px sidebar. A
   fixed 340px list would squeeze the thread below reading width, which is
   the consequence design D5 leaves to the layout (task 2.6). */
@media (max-width: 900px) {
  .feed2 { grid-template-columns: 38% 1fr; }
}

/* --- ≤768px: one pane at a time ------------------------------
   Same threshold as the shell drawer (frontend/shell.css:108, design D5):
   the cockpit has one threshold, not two. */
@media (max-width: 768px) {
  .feed2 { grid-template-columns: 1fr; }
  .conv { display: none; }
  .feed2.is-reading .chatlist { display: none; }
  .feed2.is-reading .conv { display: flex; }
  .conv__head--empty { display: flex; }
  .conv__back { display: inline-flex; }
}
