/**
 * @file chat.css
 * @description Styles for the chat page: the conversation list, the turns, the work log under each
 *   one, and the composer. Two panes on a desktop, one at a time on a phone.
 *
 *   The work log is styled to be read, not hidden. It is the evidence that what the agent said it
 *   did, it did, and folding it away by default would turn the page back into something a person has
 *   to take on trust. All colours and spacing come from theme.css so it flips with the theme.
 *
 *   NOTE: this file must be linked in spa.html (useViewCSS is a no-op).
 * @version-history
 *   v1.5.0 — 2026-08-18 — A phone could not LEAVE: the chat owns the whole screen and hides the
 *     site nav, and nothing led back out (found by Jouni on his phone). .chat-back is the door,
 *     mobile-only. Plus air: roomier scroll padding and turn gap, the long model id ellipsized to
 *     40vw (full string stays in the tooltip), the thread title ellipsized so the head keeps one
 *     row.
 *   v1.4.0 — 2026-08-17 — .chat-status-ownkey (the own-key door on the payer line) and
 *     .chat-welcome-trust (the one boundary sentence under the welcome). The status agent label is
 *     now a plain word, so it drops the monospace styling.
 *   v1.3.0 — 2026-08-17 — Phones: the composer wraps into two rows (the textarea was the smallest
 *     thing on its own row), the GAII line yields its row, and a wide markdown table scrolls inside
 *     the bubble instead of crushing its columns.
 *   v1.2.0 — 2026-08-16 — .chat-status-model: which model answered, beside the payer line.
 *   v1.1.0 — 2026-08-16 — The recorder beside the send button, and the read-aloud control on a turn.
 *   v1.0.0 — 2026-08-16 — Initial.
 */

/* ── Layout ── */
.chat-view {
  display: grid;
  grid-template-columns: 260px 1fr;
  gap: 16px;
  max-width: 1100px;
  margin: 0 auto;
  padding: 16px;
  height: calc(100dvh - 120px);
  /* Low enough that a short window (a laptop with a docked terminal, 1280x460) still puts the
     composer on screen. A taller floor pushed it 70px below the fold, and the composer is the one
     control the page exists for. */
  min-height: 320px;
}

.chat-view--signin {
  display: block;
  height: auto;
}

/* ── The conversation list ── */
.chat-threads {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
  overflow-y: auto;
  padding-right: 4px;
}

.chat-new { width: 100%; }

/* The way back out of the list. Only a phone needs it: on a desktop the list and the conversation
   are both on screen, so there is nothing to go back from. */
.chat-threads-close { display: none; }

.chat-threads-empty {
  color: var(--text-muted);
  font-size: 0.85rem;
  line-height: 1.5;
  margin: 0;
}

.chat-thread-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.chat-thread {
  display: flex;
  align-items: center;
  gap: 4px;
  border-radius: var(--radius-sm);
}

.chat-thread--active { background: var(--bg-surface); }

.chat-thread-open {
  flex: 1 1 auto;
  min-width: 0;
  text-align: left;
  background: none;
  border: none;
  cursor: pointer;
  padding: 8px 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  color: inherit;
  font: inherit;
}

.chat-thread-title {
  font-size: 0.9rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chat-thread-sub {
  font-size: 0.75rem;
  color: var(--text-muted);
}

.chat-thread-del {
  flex: 0 0 auto;
  padding: 4px 8px;
  opacity: 0;
  transition: opacity 0.15s;
}

.chat-thread:hover .chat-thread-del,
.chat-thread--active .chat-thread-del { opacity: 1; }

/* ── The conversation ── */
.chat-main {
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* A soft wash of the node's own accent rather than flat white. The chat was three greys deep —
     surface, card and muted text — which reads as a disabled form rather than a conversation, and
     none of the theme's colour reached it. Everything here is a theme token, so it follows the
     accent wherever the theme takes it. */
  background: linear-gradient(180deg, var(--accent-subtle) 0%, var(--bg-card) 220px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

.chat-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--accent-border);
}

.chat-title {
  margin: 0;
  font-size: 1rem;
  font-weight: 700;
  color: var(--accent);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The list is always visible on a desktop, so its toggle would be a button that does nothing. */
.chat-list-toggle { display: none; }

.chat-status {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 6px 16px;
  font-size: 0.75rem;
  color: var(--text-muted);
  border-bottom: 1px solid var(--border-subtle);
  background: transparent;
}

.chat-status-agent { color: var(--accent); }
.chat-status-ownkey { color: var(--accent); text-decoration: none; }
.chat-status-ownkey:hover { text-decoration: underline; }
/* The model sits beside the payer line, not in place of it: which model answered and whose money
   paid are two different questions and a person checking one still needs the other. */
.chat-status-model { color: var(--text-dim); }
.chat-status-elsewhere { color: var(--text-dim); }
.chat-status-reset { margin-left: auto; font-size: 0.75rem; padding: 2px 8px; }

.chat-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.chat-welcome {
  color: var(--text-muted);
  max-width: 46ch;
  margin: auto;
  text-align: center;
}

.chat-welcome h2 {
  font-size: 1.1rem;
  margin: 0 0 6px;
  color: var(--text-primary);
}

.chat-welcome p { margin: 0; line-height: 1.6; font-size: 0.9rem; }
.chat-welcome .chat-welcome-trust { color: var(--text-dim); margin-top: 6px; }

/* One concrete opening each, wrapping on a phone. Outline buttons: they are suggestions, and the
   composer stays the primary way in. */
.chat-starters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  margin-top: 14px;
}
.chat-starter { font-size: 0.82rem; padding: 6px 12px; }

/* ── One turn ── */
.chat-turn {
  display: flex;
  flex-direction: column;
  gap: 3px;
  max-width: 85%;
}

.chat-turn--user { align-self: flex-end; align-items: flex-end; }
.chat-turn--agent { align-self: flex-start; }

.chat-bubble {
  padding: 10px 14px;
  border-radius: var(--radius);
  background: var(--bg-card);
  border: 1px solid var(--border-subtle);
  box-shadow: var(--shadow-sm);
  line-height: 1.6;
  font-size: 0.92rem;
  overflow-wrap: anywhere;
}

.chat-turn--user .chat-bubble {
  background: var(--accent-subtle);
  border: 1px solid var(--accent-border);
}

/* The agent's side gets the accent as a spine rather than a fill: readable at any length, and it
   makes the two speakers tellable apart at a glance instead of by position alone. */
.chat-turn--agent .chat-bubble { border-left: 3px solid var(--accent-border); }
.chat-turn--live .chat-bubble { border-left-color: var(--accent); }

.chat-said { margin: 0; white-space: pre-wrap; }

/* A wide table scrolls inside the bubble instead of crushing its columns until "Versio" wraps
   mid-word. Layout containment is the view's concern (markdown.css owns typography, not where a
   bubble puts its overflow). */
.chat-bubble .md-body table {
  display: block;
  max-width: 100%;
  overflow-x: auto;
}

.chat-thinking {
  margin: 0;
  color: var(--text-muted);
  font-style: italic;
}

.chat-meta {
  display: flex;
  gap: 8px;
  font-size: 0.7rem;
  color: var(--text-muted);
  padding: 0 4px;
}

.chat-model { font-family: var(--font-mono); }

/* What the turn produced. A card is a handover, so the open control is a real link with a real
   address and the picture, when there is one, is the thing itself rather than an icon for it. */
.chat-cards {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 10px;
}
.chat-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
}
.chat-card-img {
  width: 64px;
  height: 48px;
  object-fit: cover;
  border-radius: 4px;
  flex: 0 0 auto;
}
.chat-card--image .chat-card-img { width: 120px; height: 90px; }
.chat-card-body { min-width: 0; flex: 1 1 auto; }
.chat-card-kind {
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}
/* One colour per kind of thing, so a page, an app and a saved record are distinguishable before
   the words are read. Palette tokens only: they flip with the theme. */
.chat-card--page .chat-card-kind { color: var(--accent); }
.chat-card--app .chat-card-kind { color: var(--blue); }
.chat-card--image .chat-card-kind { color: var(--purple); }
.chat-card--file .chat-card-kind { color: var(--teal); }
.chat-card--memory .chat-card-kind { color: var(--mint); }
.chat-card--workspace .chat-card-kind { color: var(--orange); }
.chat-card--page { border-left: 3px solid var(--accent); }
.chat-card--app { border-left: 3px solid var(--blue); }
.chat-card--image { border-left: 3px solid var(--purple); }
.chat-card--file { border-left: 3px solid var(--teal); }
.chat-card--memory { border-left: 3px solid var(--mint); }
.chat-card--workspace { border-left: 3px solid var(--orange); }
.chat-card-title {
  font-size: 0.85rem;
  font-weight: 600;
  overflow-wrap: anywhere;
}
.chat-card-ref { font-size: 0.72rem; color: var(--text-dim); overflow-wrap: anywhere; }
.chat-card-open { flex: 0 0 auto; font-size: 0.78rem; padding: 4px 10px; }

/* ── The work log ── */
.chat-work {
  margin-top: 10px;
  border-top: 1px solid var(--border-subtle);
  padding-top: 8px;
}

.chat-work-head {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  margin-bottom: 4px;
}

.chat-work-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.chat-work-line {
  display: flex;
  gap: 8px;
  align-items: baseline;
  font-size: 0.78rem;
  font-family: var(--font-mono);
}

.chat-work-status {
  flex: 0 0 auto;
  min-width: 68px;
  color: var(--text-muted);
}

.chat-work-line--completed .chat-work-status { color: var(--success); }
.chat-work-line--failed .chat-work-status { color: var(--danger); }

.chat-work-title {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* What the agent is doing right now. The dot moves so a still screen is never the only signal;
   `prefers-reduced-motion` gets the dot without the pulse, because the words and the clock carry
   the meaning on their own. */
.chat-live-status {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  font-size: 0.75rem;
  color: var(--text-muted);
}
.chat-live-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  animation: chat-live-pulse 1.4s ease-in-out infinite;
}
.chat-live-clock { font-family: var(--font-mono); }
@keyframes chat-live-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
@media (prefers-reduced-motion: reduce) {
  .chat-live-dot { animation: none; }
}

/* The way back to the live edge while auto-follow is suspended. Floats over the conversation
   rather than pushing it, so its appearance never moves the text you are reading. */
.chat-jump-latest {
  position: absolute;
  right: 20px;
  bottom: 96px;
  z-index: 4;
  font-size: 0.78rem;
  padding: 4px 10px;
  box-shadow: var(--shadow-sm);
}
.chat-main { position: relative; }

.chat-copy { padding: 0 4px; }
.chat-copy-all { margin-left: auto; font-size: 0.75rem; padding: 2px 8px; }

/* That a machine is on the other end. Quiet, above the conversation, with the rest one press away. */
.chat-ai-notice {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 6px 16px;
}
.chat-ai-notice-line { flex: 1 1 260px; }
/* One line once it has been read: the words stay, the block does not take the top of the page. */
.chat-ai-notice--compact { padding: 2px 16px; }
.chat-ai-notice-short { font-size: 0.72rem; color: var(--text-dim); }
.chat-ai-more { font-size: 0.72rem; padding: 2px 8px; }

/* One suggestion, once, with the way out on the same line as the ask. */
.chat-nudge {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 0 16px 8px;
  padding: 8px 12px;
  border: 1px solid var(--accent-border);
  background: var(--accent-subtle);
  border-radius: var(--radius-sm);
  font-size: 0.8rem;
  line-height: 1.5;
}
.chat-nudge-text { flex: 1 1 260px; }
.chat-nudge-dismiss { flex: 0 0 auto; font-size: 0.75rem; padding: 2px 8px; }

/* Whose agent this is. Quiet, and permanently there. */
.chat-credit {
  padding: 6px 16px 10px;
  text-align: center;
  font-size: 0.72rem;
}
.chat-credit-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--text-dim);
  text-decoration: none;
}
.chat-credit-link:hover { color: var(--text-muted); text-decoration: underline; }
.chat-credit-mark { font-size: 0.9rem; }

/* The fork an agent named, as buttons. The note keeps the box in play: three options are never the
   whole space, and a row of buttons with no way past them is a form. */
.chat-choices {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  align-self: flex-start;
  max-width: 85%;
}
.chat-choice { font-size: 0.82rem; padding: 6px 12px; }
.chat-choices-note { font-size: 0.75rem; color: var(--text-dim); }

/* ── A turn that could not run ── */
.chat-error {
  align-self: stretch;
  border: 1px solid var(--accent-border);
  background: var(--accent-subtle);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.chat-error-msg {
  margin: 0;
  flex: 1 1 240px;
  font-size: 0.85rem;
  line-height: 1.5;
}

/* Pictures attached but not yet sent, and the ones already in the conversation. */
.chat-attachments { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.chat-attachment {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-surface);
  font-size: 0.75rem;
  max-width: 220px;
}
.chat-attachment--error { border-color: var(--danger); color: var(--danger); }
.chat-attachment-thumb { width: 28px; height: 28px; object-fit: cover; border-radius: 3px; }
.chat-attachment-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-attachment-state { color: var(--text-muted); }
.chat-attachment-drop { padding: 0 4px; line-height: 1; }
.chat-file-input { display: none; }
.chat-attach { flex: 0 0 auto; padding: 6px 10px; }

.chat-turn-images { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.chat-turn-file {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: var(--bg-surface);
  font-size: 0.78rem;
  color: inherit;
  text-decoration: none;
}
.chat-turn-file:hover { border-color: var(--accent-border); }
.chat-turn-image {
  max-width: 220px;
  max-height: 180px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-subtle);
}

/* ── The composer ── */
.chat-composer {
  border-top: 1px solid var(--border-subtle);
  padding: 10px 16px;
  background: var(--bg-card);
}

.chat-composer-note {
  margin: 0 0 6px;
  font-size: 0.78rem;
  color: var(--text-muted);
  line-height: 1.5;
}

.chat-composer-row {
  display: flex;
  gap: 8px;
  align-items: flex-end;
}

.chat-input {
  flex: 1 1 auto;
  min-width: 0;
  resize: none;
  max-height: 200px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-input);
  color: inherit;
  font: inherit;
  font-size: 0.92rem;
  line-height: 1.5;
}

.chat-input:focus {
  outline: none;
  border-color: var(--border-focus);
  background: var(--bg-input-focus);
}

.chat-send { flex: 0 0 auto; }

/* The way OUT of the full-screen phone chat. Desktop has the site nav, so it hides there. */
.chat-back { display: none; }
.chat-voice { flex: 0 0 auto; }

/* The read-aloud control sits with the timestamp rather than on the bubble: it is about the turn,
   not part of what was said. */
.chat-listen { font-size: 0.7rem; padding: 0 6px; }

/* ── Phones ──
   One pane at a time. The page takes the whole viewport, the shell's sticky nav is hidden (it lives
   in a higher stacking context, so a z-index here cannot cover it), and the composer sits on the
   keyboard: --chat-avail is the measured visual-viewport height, with 100dvh as the fallback the
   viewport meta's interactive-widget=resizes-content already provides. Same pattern as the inbox,
   which is the surface this one is modelled on. */
@media (max-width: 760px) {
  .chat-view {
    position: fixed;
    inset: 0;
    z-index: 1000;
    grid-template-columns: 1fr;
    gap: 0;
    padding: 0;
    max-width: none;
    height: var(--chat-avail, 100dvh);
    background: var(--bg);
  }

  body:has(.chat-view) { overflow: hidden; }
  body:has(.chat-view) .topnav { display: none; }

  /* The list is a place you go to, not a column that would leave neither pane readable. */
  .chat-threads { display: none; }
  .chat-view--list .chat-threads {
    display: flex;
    padding: 12px;
    background: var(--bg-card);
  }
  .chat-view--list .chat-main { display: none; }

  .chat-list-toggle { display: inline-flex; }
  .chat-threads-close { display: inline-flex; align-self: flex-start; }

  .chat-main {
    border: none;
    border-radius: 0;
    height: 100%;
  }

  .chat-back { display: inline-flex; align-items: center; min-height: 40px; flex: 0 0 auto; }
  .chat-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  .chat-turn { max-width: 92%; }
  .chat-scroll { padding: 16px 12px; gap: 16px; }
  .chat-composer {
    padding: 8px 10px calc(8px + env(safe-area-inset-bottom, 0px));
  }

  /* The composer, two honest rows. One row squeezed the textarea to a slot between three
     buttons — the writing surface was the smallest thing on the writing row. The box takes the
     full width; the controls sit under it, attach and voice on the left, Send grown to a real
     target on the right. */
  .chat-composer-row { flex-wrap: wrap; }
  .chat-input { flex: 1 1 100%; }
  .chat-attach, .chat-voice { flex: 0 0 auto; min-height: 40px; }
  .chat-send { flex: 1 1 auto; margin-left: auto; max-width: 50%; min-height: 40px; }

  /* The status area earns its rows. The agent's GAII is identity chrome a phone screen cannot
     afford — it is on the desktop, in the profile, and in every record; the money line and the
     model stay because one is about their wallet and the other makes answers checkable. */
  .chat-status { padding: 4px 12px; gap: 8px; }
  .chat-status-agent { display: none; }
  /* The full model id is a third of the screen's width; the tooltip keeps the whole string. */
  .chat-status-model { max-width: 40vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .chat-ai-notice { padding: 4px 12px; }
  .chat-head { padding: 10px 12px; }
  .chat-copy-all { font-size: 0.7rem; padding: 2px 6px; }
}
