/* Chat: the conversation, the work line, citations, and the New Chat page.
 *
 * Carried over from the transcript document in substance (the work line, the
 * citation chips and their popover are the same machinery) and restyled for
 * Mosaik: an avatar column for the assistant, softer bubbles for the person,
 * words that fade in as an answer is written, and the mosaic picture above
 * the greeting of an empty conversation.
 */

:is(#view-chat, #view-agent) .conversation{
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overflow-x: hidden;
  scroll-behavior: var(--scroll-behavior, smooth);
  /* Room for the drawn scrollbar on both sides, so the column stays centred
     over the composer. */
  padding: 0 11px;
  scrollbar-width: none;
}
:is(#view-chat, #view-agent) .conversation::-webkit-scrollbar{ width: 0; height: 0; }
/* In Chat the words run on under the composer, seen faintly through it,
   and are gone by the strip below it, where the usage readouts sit: a still
   mask on the scroller rather than a band of the page's colour, so whatever
   lies behind the room (the Mosaik theme's scene) shows through to the foot.
   Not on the New Chat page (shell.css), where it would lie over the picture. */
#view-chat .conversation{
  --fade: linear-gradient(to bottom, #000 calc(100% - var(--dock-h, 150px) + 6px),
    rgba(0, 0, 0, 0.45) calc(100% - 44px), transparent calc(100% - 28px));
  -webkit-mask-image: var(--fade);
  mask-image: var(--fade);
}
#view-chat > .veil{ display: none; }

:is(#view-chat, #view-agent) .column{
  max-width: calc(var(--reading-width, 820px) + 48px);
  margin: 0 auto;
  padding: 28px 24px calc(var(--dock-h, 150px) + 40px);
  font-family: var(--font-sans, var(--ui));
  font-size: var(--font-size, 15px);
  line-height: var(--line-height, 1.68);
}

/* The foot of the page fades under the composer rather than stopping above it. */
:is(#view-chat, #view-agent) > .veil{
  position: absolute;
  left: 0;
  right: 11px;
  bottom: 0;
  height: calc(var(--dock-h, 150px) + 24px);
  pointer-events: none;
  background: linear-gradient(to bottom, color-mix(in srgb, var(--bg) 0%, transparent) 0%,
    color-mix(in srgb, var(--bg) 82%, transparent) 42%, var(--bg) 72%);
  z-index: 2;
  transition: opacity 520ms var(--ease);
}

:is(#view-chat, #view-agent) > .scrollbar{
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 11px;
  z-index: 4;
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}
:is(#view-chat, #view-agent) > .scrollbar.live{ opacity: 1; }
:is(#view-chat, #view-agent) > .scrollbar .thumb{
  position: absolute;
  top: 0;
  right: 4px;
  width: 3px;
  border-radius: 999px;
  background: var(--scrollbar);
  transition: background var(--dur-fast) var(--ease), width var(--dur-fast) var(--ease), right var(--dur-fast) var(--ease);
}
:is(#view-chat, #view-agent) > .scrollbar:hover .thumb,
:is(#view-chat, #view-agent) > .scrollbar.dragging .thumb{ background: var(--scrollbar-hover); width: 5px; right: 3px; }

:is(#view-chat, #view-agent) > .jump{
  position: absolute;
  left: calc(50% - 5px);
  bottom: calc(var(--dock-h, 150px) + 6px);
  z-index: 7;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  padding: 0;
  color: var(--text2);
  background: var(--raised);
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, 8px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease), color var(--dur-fast) var(--ease);
  box-shadow: 0 6px 18px -6px var(--shadow-cast);
}
:is(#view-chat, #view-agent) > .jump.visible{ opacity: 1; pointer-events: auto; transform: translate(-50%, 0); }
:is(#view-chat, #view-agent) > .jump:hover{ color: var(--text); border-color: var(--accent); }
:is(#view-chat, #view-agent) > .jump svg{ width: 15px; height: 15px; }

/* ---- messages ----------------------------------------------------------- */
#view-chat .msg{ margin: 0 0 var(--message-gap, 28px); animation: rise-in var(--dur-slow) var(--ease-out) both; }
/* Drawn with the conversation rather than arriving: no rise of its own. And a
   message off screen is not laid out or painted until it is scrolled near,
   which is what keeps a conversation of hundreds of messages quick to open,
   scroll and write in. Its last size is remembered once it has been drawn. */
#view-chat .msg.still{ animation: none; }
#view-chat .msg:not(:nth-last-child(-n + 4)){
  content-visibility: auto;
  contain-intrinsic-size: auto 260px;
  overflow-clip-margin: 24px;
}
#view-chat .msg.user{ display: flex; flex-direction: column; align-items: flex-end; }
#view-chat .msg.user .bubble{
  max-width: 78%;
  padding: calc(var(--density-pad, 11px) + 1px) 18px;
  border-radius: 20px;
  /* A soft fill and no edge: its colour always stands off the page
     (styles/scene_theme.py holds it there over a scene). */
  background: var(--user-bubble);
  white-space: pre-wrap;
  overflow-wrap: break-word;
  /* Inter's contextual alternates join => into an arrow: what was typed is
     shown as typed (live, 2026-10-14). */
  font-variant-ligatures: no-contextual;
}
/* Code pasted in a question between ``` fences (chat.js). */
#view-chat .msg.user .bubble .asked-code{ margin: 6px 0; padding: 8px 10px; border-radius: 8px; background: color-mix(in srgb, var(--text) 6%, transparent);
  font: 0.88em/1.5 var(--font-mono); white-space: pre; overflow-x: auto; overflow-y: hidden; }
/* Japanese (chat.js markScript): its own fonts, for its own letters only. */
#view-chat :is(.body, .bubble):lang(ja){ font-family: "Mosaik Japanese", var(--font-sans, var(--ui)); }
/* A very long question, folded to its first lines until "Show all". */
#view-chat .msg.user .bubble.folded{
  max-height: 18em;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, #000 72%, transparent);
  mask-image: linear-gradient(to bottom, #000 72%, transparent);
}
#view-chat .msg.user .fold{
  margin: 4px 6px 0 0;
  padding: 2px 8px;
  border: 0;
  border-radius: 6px;
  background: none;
  font: inherit;
  font-size: var(--ui-meta);
  font-weight: 560;
  color: var(--text2);
  cursor: pointer;
}
#view-chat .msg.user .fold:hover{ color: var(--text); background: var(--surface-hover, var(--surface)); }
#view-chat .msg.user.editing .fold{ display: none; }

/* The assistant's mark sits in a narrow column of its own, level with the
   composer's edge; the answer reads in the column beside it. */
#view-chat .msg.assistant {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr);
  column-gap: 12px;
}
#view-chat .msg.assistant > * { grid-column: 2; }
#view-chat .msg.assistant > .avatar {
  grid-column: 1;
  grid-row: 1 / span 6;
  width: 22px;
  height: 22px;
  margin-top: 2px;
  border-radius: 6px;
  overflow: hidden;
}
#view-chat .msg.assistant > .avatar{ position: relative; }
#view-chat .msg.assistant > .avatar svg{ width: 100%; height: 100%; display: block; }
/* Before the first words the star gathers itself: each ray in turn draws in
   to the heart and springs back, and the heart turns a quarter as each round
   ends. Once words come, its points light in turn (js/moments.js
   App.starAvatar). With that detail off, the mark breathes. */
#view-chat .msg.assistant.working > .avatar .pt{
  animation: star-point 0.96s linear infinite;
  animation-delay: calc((var(--i) - 4) * 0.24s);
}
#view-chat .msg.assistant.working:not(.answering, .free-waiting) > .avatar :is(.pt, .heart){
  transform-box: view-box;
  transform-origin: 60px 60px;
}
#view-chat .msg.assistant.working:not(.answering, .free-waiting) > .avatar .pt{
  animation: star-gather 1.44s var(--ease-out) infinite;
  animation-delay: calc((var(--i) - 4) * 0.36s);
}
#view-chat .msg.assistant.working:not(.answering, .free-waiting) > .avatar .heart{
  animation: heart-turn 1.44s var(--ease-spring) infinite;
}
@keyframes star-gather {
  0% { transform: none; opacity: 1; }
  22% { transform: scale(0.58); opacity: 0.5; }
  52%, 100% { transform: none; opacity: 1; }
}
@keyframes heart-turn {
  0%, 62% { transform: none; }
  100% { transform: rotate(90deg); }
}
/* While nothing is written yet, faint lines are drafted from the left and
   wiped where the answer will be (js/chat.js setWorking). They begin after a
   moment, so an answer that starts at once never shows them. */
#view-chat .msg.assistant > .drafting{ display: none; }
#view-chat .msg.assistant.working:not(.answering, .free-waiting, .words-waiting) > .drafting{
  display: grid;
  gap: 11px;
  max-width: 560px;
  padding: 8px 0 4px;
}
#view-chat .msg.assistant > .drafting > i{
  display: block;
  height: 7px;
  border-radius: 4px;
  background: color-mix(in srgb, var(--text) 8%, transparent);
  transform-origin: left center;
  animation: draft-line 3.2s var(--ease) 0.5s infinite both;
}
#view-chat .msg.assistant > .drafting > i:nth-child(1){ width: 94%; }
#view-chat .msg.assistant > .drafting > i:nth-child(2){ width: 81%; animation-delay: 0.9s; }
#view-chat .msg.assistant > .drafting > i:nth-child(3){ width: 58%; animation-delay: 1.3s; }
@keyframes draft-line {
  0% { opacity: 0; transform: scaleX(0.04); }
  30%, 68% { opacity: 1; transform: none; }
  100% { opacity: 0; transform: none; }
}
html.no-thinking-star #view-chat .msg.assistant.working > .drafting{ display: none; }
html.no-thinking-star #view-chat .msg.assistant.working > .avatar :is(.pt, .heart){ animation: none; }
html.no-thinking-star #view-chat .msg.assistant.working > .avatar svg{ animation: breathe 1.8s ease-in-out infinite; }
/* The answer is done: one glint crosses the star. */
#view-chat .msg.assistant > .avatar.glint::after{
  content: "";
  position: absolute;
  inset: -40%;
  background: linear-gradient(105deg, transparent 38%, color-mix(in srgb, #fff 62%, transparent) 50%, transparent 62%);
  transform: translateX(-100%);
  animation: avatar-glint 640ms var(--ease) both;
  pointer-events: none;
}
@keyframes avatar-glint { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
@keyframes breathe {
  0%, 100% { transform: scale(1); filter: saturate(1); }
  50% { transform: scale(0.86) rotate(-6deg); filter: saturate(1.25) brightness(1.1); }
}
#view-chat .msg.assistant .body{ overflow-wrap: break-word; min-height: 1.2em; }
#view-chat .msg.assistant > .reminder-line{ margin: 1px 0 4px; font-size: 0.86em; color: var(--text3); }

/* A drawing still being written (chat.js holdDrawing): the star loader where it
   will stand, with one quiet word, until it is whole. */
#view-chat .drawing-wait{
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 120px;
  margin: 12px 0;
  color: var(--text3);
  font-size: var(--chrome, 13px);
  font-weight: 500;
}
#view-chat .drawing-wait .star-loader{ width: 18px; height: 18px; }

#view-chat .actions{
  display: flex;
  align-items: center;
  gap: 2px;
  height: 28px;
  margin-top: 4px;
  margin-left: -6px;
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}
#view-chat .msg:hover .actions,
#view-chat .actions:focus-within,
#view-chat .msg.assistant.latest .actions{ opacity: 1; }
#view-chat .msg.user .actions{ justify-content: flex-end; margin-left: 0; margin-right: -6px; }
#view-chat .act{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--text3);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
#view-chat .act:hover{ background: var(--surface-hover); color: var(--text); }
#view-chat .act:active{ transform: scale(0.92); }
#view-chat .act svg{ width: 14px; height: 14px; }
#view-chat .act.done{ color: var(--added); }
/* Any question can be edited (as a new version); only the latest taken back. */
#view-chat .msg.user:not(.latest) .act[data-action="delete"]{ display: none; }
/* ‹ 2 / 3 ›, first in the row, on a message with versions beside it. */
#view-chat .actions .versions{
  display: inline-flex;
  align-items: center;
  gap: 0;
  margin-right: 4px;
  color: var(--text3);
  font-size: var(--meta, 12px);
  font-variant-numeric: tabular-nums;
}
#view-chat .actions .versions .count{ min-width: 30px; text-align: center; user-select: none; }
#view-chat .actions .versions .act{ width: 22px; }
#view-chat .actions .versions .act:disabled{ opacity: 0.35; pointer-events: none; }
#view-chat .msg.versioned .actions{ opacity: 1; }
#view-chat .msg.working .actions{ visibility: hidden; }
/* A piece joining a message already on screen: the row above as an answer
   ends, a note, its figures, a card (js/chat.js joins). It ends where its
   own rules put it, so a row kept faint until hovered stays faint. */
#view-chat .joining{ animation: piece-join 320ms var(--ease-out) both; }
@keyframes piece-join { from { opacity: 0.15; transform: translateY(4px); } }
#view-chat .actions .meta{
  margin-left: 8px;
  padding: 2px 6px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  font: inherit;
  font-size: var(--meta, 12px);
  color: var(--text3);
  cursor: pointer;
  min-width: 0;
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

#view-chat .actions .meta:empty{ display: none; }
#view-chat .actions .meta:hover, #view-chat .actions .meta:focus-visible{ color: var(--text2); background: var(--surface-hover); }

#view-chat .editor{
  width: 100%;
  max-width: 82%;
  margin-left: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-end;
  animation: settle-in var(--dur) var(--ease-out);
}
#view-chat .editor textarea{
  width: 100%;
  min-height: 70px;
  resize: vertical;
  font: inherit;
  color: var(--text);
  background: var(--input-bg);
  border: 1px solid var(--accent);
  border-radius: 16px;
  padding: 12px 16px;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 14%, transparent);
}
#view-chat .editor textarea:focus{ outline: none; }
#view-chat .editor-row{ display: flex; gap: 8px; }

/* ---- the reader's message layout ------------------------------------------ */
/* Settings › Appearance: one class on the root each (core/appearance
   Appearance.classes), so changing one restyles the conversation in place
   and draws no message again. Bubbles, the default, is the rules above. */
#view-chat .column{ --answer-indent: 34px; }
/* Its padding keeps the room under an answer being written (js/chat.js
   setRoom) and is read at once to follow the newest line: never eased, even
   by Reduced motion's short transitions on everything. */
#view-chat .column{ transition: none; }

/* Flat: both sides down the left, like a document. The reader's own words
   line up with the answers' text, marked by a quiet rule and a label rather
   than a bubble. */
html.look-flat #view-chat .msg.user{ align-items: flex-start; padding-left: var(--answer-indent); }
html.look-flat #view-chat .msg.user::before{
  content: "You";
  margin: 0 0 4px 16px;
  font-family: var(--ui);
  font-size: var(--meta, 12px);
  font-weight: 600;
  color: var(--text3);
}
html.look-flat #view-chat .msg.user .bubble{
  max-width: 100%;
  padding: 1px 0 1px 16px;
  border-radius: 0;
  background: none;
  box-shadow: inset 2px 0 0 var(--border-strong);
}
html.look-flat #view-chat .msg.user :is(.files, .mentions){ justify-content: flex-start; max-width: 100%; }
html.look-flat #view-chat .msg.user .actions{ justify-content: flex-start; margin-left: 10px; margin-right: 0; }
html.look-flat #view-chat .msg.user .fold{ margin-left: 10px; }
html.look-flat #view-chat .editor{ max-width: 100%; margin-left: 0; align-items: flex-start; }

/* No picture beside an answer: its text takes the whole column. */
html.look-no-avatars #view-chat .column{ --answer-indent: 0px; }
html.look-no-avatars #view-chat .msg.assistant{ grid-template-columns: 0 minmax(0, 1fr); column-gap: 0; }
html.look-no-avatars #view-chat .msg.assistant > .avatar{ display: none; }

/* The line under an answer (model, time, cost and its buttons). Automatic,
   the default, is the rules above: under the newest answer, and under any
   other on hover. Always keeps its words under every answer, the buttons
   still waiting for the pointer; on hover asks for the pointer even on the
   newest; never leaves the words out. Opacity only, as the default does. */
html.look-meta-always #view-chat .msg.assistant .actions{ opacity: 1; }
html.look-meta-always #view-chat .msg.assistant .actions > :not(.meta){
  transition: opacity var(--dur) var(--ease), background var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
html.look-meta-always #view-chat .msg.assistant:not(.latest, :hover, .failed) .actions:not(:focus-within) > :not(.meta, .versions){ opacity: 0; }
html.look-meta-hover #view-chat .msg.assistant.latest:not(:hover, .failed, .versioned) .actions:not(:focus-within){ opacity: 0; }
html.look-meta-never #view-chat .actions .meta{ display: none; }

#view-chat .error{
  display: flex;
  align-items: flex-start;
  gap: 11px;
  margin: 4px 0 0;
  padding: 12px 13px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--danger);
  border-radius: var(--radius-md);
  background: var(--card);
  animation: settle-in var(--dur) var(--ease-out);
}
#view-chat .error .icon{ color: var(--danger); flex: none; margin-top: 1px; }
#view-chat .error .icon svg{ width: 16px; height: 16px; }
/* min-width: 0 lets the text shrink inside the flex row, and anywhere-wrapping
   breaks what has no spaces to break at: a provider's error often ends in a
   long URL, which otherwise ran straight out of the card. */
#view-chat .error .text{
  flex: 1;
  min-width: 0;
  color: var(--danger);
  font-size: 0.93em;
  overflow-wrap: anywhere;
}
#view-chat .error .text a{ color: inherit; text-decoration: underline; text-underline-offset: 2px; }
#view-chat .error .error-main{ flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
/* What the provider said, for whoever wants it: folded away by default. */
#view-chat .error .error-details{ font-size: var(--meta); color: var(--text3); }
#view-chat .error .error-details summary{ cursor: pointer; width: max-content; user-select: none; }
#view-chat .error .error-details summary:hover{ color: var(--text2); }
#view-chat .error .error-details .said{
  margin-top: 6px; padding: 8px 10px; border-radius: var(--radius-sm);
  background: var(--surface);
  font-family: var(--font-mono); font-size: var(--ui-meta); line-height: 1.5;
  white-space: pre-wrap; overflow-wrap: anywhere; max-height: 180px; overflow: auto; user-select: text;
}
#view-chat .error .error-details .said a{ color: inherit; }
#view-chat .error .btn{ flex: none; }
#view-chat .error .error-actions{ display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; flex: none; max-width: 55%; }
#view-chat .error .error-actions[hidden]{ display: none; }
#view-chat .error a.btn{ text-decoration: none; }
/* Waiting for a free model (chat/free_wait.py): a quiet card, not an error,
   and the reply stands still, as nothing runs at rest (docs/speed.md). */
#view-chat .free-wait{
  display: flex;
  align-items: center;
  gap: 11px;
  margin: 4px 0 0;
  padding: 10px 13px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--card);
  color: var(--text2);
  animation: settle-in var(--dur) var(--ease-out);
}
#view-chat .free-wait[hidden]{ display: none; }
#view-chat .free-wait .icon{ color: var(--text3); flex: none; display: inline-flex; }
#view-chat .free-wait .icon svg{ width: 16px; height: 16px; }
#view-chat .free-wait .free-wait-text{ flex: 1; min-width: 0; }
#view-chat .free-wait .free-wait-actions{ display: flex; gap: 6px; flex: none; }
#view-chat .free-wait .free-wait-actions[hidden]{ display: none; }
#view-chat .msg.free-waiting .work.running .phase{ animation: none; color: var(--text2); background-image: none; }
#view-chat .msg.assistant.free-waiting > .avatar .pt,
#view-chat .msg.assistant.free-waiting > .avatar svg{ animation: none; }
/* A reply that failed with nothing written has nothing to copy; one that
   stopped partway keeps its text, and the ways to copy it. */
#view-chat .msg.failed:not(.partial) .actions [data-action="copy"],
#view-chat .msg.failed:not(.partial) .actions [data-action="more"]{ display: none; }
#view-chat .msg.failed .actions{ opacity: 1; }

/* ---- the work line ------------------------------------------------------ */
#view-chat .work{ margin: 0 0 calc(var(--block-gap, 0.95em) * 0.6); }
#view-chat .work summary{
  display: inline-flex;
  align-items: center;
  gap: 7px;
  list-style: none;
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  color: var(--text2);
  padding: 3px 0;
  user-select: none;
}
#view-chat .work summary::-webkit-details-marker{ display: none; }
#view-chat .work .caret{ width: 12px; height: 12px; flex: none; color: var(--text3); transition: transform var(--dur) var(--ease); order: 3; }
#view-chat .work[open] .caret{ transform: rotate(90deg); }
#view-chat .work .phase-line{ position: relative; display: inline-flex; align-items: center; min-height: 1.35em; }
#view-chat .work .phase{
  display: inline-block;
  white-space: nowrap;
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
  background-image: linear-gradient(100deg, var(--text3) 0%, var(--text3) 40%, var(--shimmer) 50%, var(--text3) 60%, var(--text3) 100%);
  background-size: 300% 100%;
  background-position: 100% 0;
  background-repeat: no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
#view-chat .work .phase.entering{ opacity: 0; transform: translateY(6px); }
#view-chat .work .phase.leaving{ position: absolute; left: 0; top: 0; opacity: 0; transform: translateY(-6px); pointer-events: none; }
#view-chat .work.running .phase{ animation: sweep 1.9s cubic-bezier(0.5, 0, 0.5, 1) infinite; }
#view-chat .work:not(.running) .phase{ color: var(--text3); background-image: none; }
@keyframes sweep { from { background-position: 100% 0; } to { background-position: 0% 0; } }
html.reduced-motion #view-chat .work.running .phase{ animation: none; color: var(--text2); background-image: none; }
/* The step a live group is on (chat.js phaseNode, chat/phases.py), in words
   alone: a short label with the light across it while the reply works, and
   what it is about. */
#view-chat .work .phase.step{
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--text3);
  background-image: none;
}
#view-chat .work.running .phase.step{ animation: none; }
#view-chat .work .phase.step .step-label{
  background-image: linear-gradient(100deg, var(--text2) 0%, var(--text2) 40%, var(--shimmer) 50%, var(--text2) 60%, var(--text2) 100%);
  background-size: 300% 100%;
  background-position: 100% 0;
  background-repeat: no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
#view-chat .work.running .phase.step .step-label{ animation: sweep 1.9s cubic-bezier(0.5, 0, 0.5, 1) infinite; }
#view-chat .work .phase.step .step-detail{
  max-width: 34ch;
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: 400;
}
html.reduced-motion #view-chat .work.running .phase.step .step-label,
#view-chat .msg.free-waiting .work.running .phase.step .step-label{ animation: none; color: var(--text2); background-image: none; }

/* Dots side by side, never stacked over each other's letters. */
#view-chat .work .avatars{ display: inline-flex; align-items: center; gap: 2px; padding-left: 3px; order: 4; }
#view-chat .work .avatars .cite-label{ margin-left: 2px; }
/* Opened, the work line is one small window (js/reasoning.js) that scrolls on
   its own: its steps are set tight, and pages of them never push the answer
   down. */
#view-chat .work .sources li:hover, #view-chat .work .sources li.lit{ background: var(--surface-hover); }
/* A group of steps between the reply's paragraphs (chat.js mountGroups): in
   the place marked for it, or after the words while none follow it yet. It
   keeps the paragraph rhythm of the words around it. */
#view-chat .work-slot{ margin: 0 0 var(--block-gap, 0.95em); }
#view-chat .work-slot:empty{ display: none; }
#view-chat .work-tail{ margin-top: calc(var(--block-gap, 0.95em) * 0.6); }
#view-chat .work.inline{ margin: 0; }
#view-chat .work-slot > .work + .work, #view-chat .work-tail > .work + .work{ margin-top: 2px; }

/* ---- sources and citations ---------------------------------------------- */
#view-chat .dot{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  flex: none;
  border-radius: 50%;
  border: 1px solid var(--bg);
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--text);
  text-transform: uppercase;
  user-select: none;
  overflow: hidden;
}
#view-chat .dot.logo{ background: var(--logo-plate); padding: 1px; }
#view-chat .dot.logo.pale{ background: var(--logo-plate-dark); }
#view-chat .dot.logo img{ width: 100%; height: 100%; object-fit: contain; border-radius: 4px; display: block; }
#view-chat .cite-group{
  display: inline-flex;
  align-items: center;
  gap: 3px;
  vertical-align: baseline;
  margin-left: 4px;
  padding: 1px 7px 1px 3px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: var(--soft);
  cursor: pointer;
  line-height: 1;
  transform: translateY(2px);
  transition: background var(--dur-fast) var(--ease);
}
#view-chat .cite-group:hover, #view-chat .cite-group:focus-visible{ background: var(--soft-hover); outline: none; }
#view-chat .cite-group .dot{ width: 14px; height: 14px; font-size: 7.5px; }
#view-chat .cite-label{ font-size: 11.5px; font-weight: 600; color: var(--text3); letter-spacing: 0.01em; max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#view-chat .cited{ border-radius: 4px; box-decoration-break: clone; -webkit-box-decoration-break: clone; transition: background var(--dur) var(--ease); }
#view-chat .cited.lit{ background: var(--accent-wash); }
#view-chat .cite-keep{ white-space: nowrap; }
/* Where the figures came from (chat/figure_ink.py): a quiet line under the
   answer, and once it is clicked (.inked), each figure in its origin's wash,
   the model's in a dashed underline and a chip whose page lacks one hollow.
   Only colours change, at once; Settings turns it off (look-no-figures). */
#view-chat .figures-line{
  display: block;
  margin: 6px 0 0 -6px;
  padding: 2px 6px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  font: inherit;
  font-size: var(--meta, 12px);
  color: var(--text3);
  text-align: left;
  cursor: pointer;
  font-variant-numeric: tabular-nums;
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
#view-chat .figures-line:hover, #view-chat .figures-line:focus-visible{ color: var(--text2); background: var(--surface-hover); }
#view-chat .figures-key{ display: none; width: 9px; height: 9px; margin-right: 4px; border-radius: 2px; }
#view-chat .msg.inked .figures-key{ display: inline-block; }
#view-chat .figures-key[data-from="source"]{ background: var(--figure-source); }
#view-chat .figures-key[data-from="worked"]{ background: var(--figure-worked); }
#view-chat .figures-key[data-from="yours"]{ background: var(--figure-yours); }
#view-chat .figures-key[data-from="model"]{ height: 0; border-radius: 0; border-bottom: 1.5px dashed var(--text3); }
#view-chat .figures-key[data-from="hollow"]{ border: 1px dashed var(--border-strong); border-radius: 50%; }
#view-chat .fig{ border-radius: 2px; box-decoration-break: clone; -webkit-box-decoration-break: clone; }
#view-chat .msg.inked .fig[data-from="source"]{
  background: color-mix(in srgb, var(--figure-source) 20%, transparent); box-shadow: inset 0 -1.5px 0 var(--figure-source);
}
#view-chat .msg.inked .fig[data-from="worked"]{
  background: color-mix(in srgb, var(--figure-worked) 20%, transparent); box-shadow: inset 0 -1.5px 0 var(--figure-worked);
}
#view-chat .msg.inked .fig[data-from="yours"]{
  background: color-mix(in srgb, var(--figure-yours) 20%, transparent); box-shadow: inset 0 -1.5px 0 var(--figure-yours);
}
#view-chat .msg.inked .fig[data-from="model"]{ text-decoration: underline dashed var(--text3); text-underline-offset: 3px; }
#view-chat .msg.inked .cite-group.hollow{ background: transparent; border-style: dashed; }
#view-chat .msg.inked .cite-group.hollow .dot{ opacity: 0.45; }
html.look-no-figures #view-chat .msg.inked .fig{ background: none; box-shadow: none; text-decoration: none; }
html.look-no-figures #view-chat .msg.inked .cite-group.hollow{ background: var(--surface); border-style: solid; }
html.look-no-figures #view-chat .msg.inked .cite-group.hollow .dot{ opacity: 1; }
html.look-no-figures #view-chat .figures-line{ display: none; }
/* Figures that may have changed since the web was read for them (chat/dated.py): a dotted
   underline in the accent's ink, which marks what Update acts on, and a quiet line saying as
   of when. Nothing moves. */
#view-chat .aged-fig{
  text-decoration: underline dotted var(--accent-ink); text-decoration-thickness: 1.5px;
  text-underline-offset: 3px; text-decoration-skip-ink: none;
}
#view-chat .msg.assistant > .aged-line{
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; margin: 6px 0 0;
  font-size: var(--meta, 12px); color: var(--text3);
}
#view-chat .aged-line .link{
  padding: 0; border: 0; background: none; color: var(--accent-ink); font: inherit; font-weight: 600; cursor: pointer;
}
#view-chat .aged-line .link:hover, #view-chat .aged-line .link:focus-visible{ text-decoration: underline; text-underline-offset: 2px; }
#cite-popover {
  position: fixed;
  z-index: 40;
  display: flex;
  flex-direction: column;
  max-height: 60vh;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--raised);
  box-shadow: 0 12px 34px var(--shadow-cast);
  opacity: 0;
  transform: translateY(3px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
#cite-popover.shown { opacity: 1; transform: none; }
#cite-popover .cards { display: flex; flex-direction: column; gap: 2px; min-height: 0; overflow-y: auto; padding: 5px; }
#cite-popover .card { display: block; padding: 8px 9px; border-radius: 8px; text-decoration: none; color: var(--text); }
#cite-popover .card:hover { background: var(--surface-hover); }
#cite-popover .head { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; }
#cite-popover .host { font-size: 12px; font-weight: 600; color: var(--text2); }
#cite-popover .when { font-size: 12px; color: var(--text3); margin-left: auto; }
#cite-popover .title { font-size: 13px; font-weight: 600; line-height: 1.35; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; }
#cite-popover .snip { margin-top: 3px; font-size: 12px; line-height: 1.45; color: var(--text3); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
#cite-popover .foot { display: flex; align-items: baseline; gap: 8px; margin-top: 6px; font-size: 12px; color: var(--text3); }
#cite-popover .foot .path { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#cite-popover .foot .read { flex: none; margin-left: auto; border: 1px solid var(--border); border-radius: 4px; padding: 0 4px; }
#cite-popover .unheld { margin-top: 6px; padding-top: 6px; border-top: 1px dashed var(--border); font-size: 12px; line-height: 1.45; color: var(--text2); }
html.look-no-figures #cite-popover .unheld { display: none; }

#view-chat .body img,
#view-chat .bubble img{
  display: block;
  max-width: 100%;
  max-height: 22rem;
  width: auto;
  height: auto;
  margin: var(--block-gap, 0.95em) 0;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--card);
  object-fit: contain;
}

/* ---- the New Chat page -------------------------------------------------- */
:is(#view-chat, #view-agent) .welcome{
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  /* Exactly the room the column leaves (its 28px top and dock + 40px bottom
     padding), so an empty conversation never has anything to scroll. */
  min-height: calc(100vh - var(--header-h) - var(--dock-h, 150px) - 70px);
  padding-bottom: 0;
  gap: 0;
}
/* The picture itself lies behind the whole main area (#backdrop, shell.css);
   the greeting sits on it just above the composer, which waits in the middle
   of the window. Nothing here takes up room in the column, so the first
   message starts at the top while the picture comes apart behind it. */
:is(#view-chat, #view-agent) .welcome:is(.scenic, .centred){ min-height: 0; }
:is(#view-chat, #view-agent) .welcome :is(.copy, .words){
  position: absolute;
  left: 50%;
  bottom: calc(50vh + (var(--dock-h, 150px) - 30px) / 2 + 22px);
  translate: -50% 0;
  width: min(var(--composer-w, 820px), calc(100% - 48px));
  display: flex;
  flex-direction: column;
  align-items: center;
  animation: rise-in 520ms var(--ease-out) 120ms both;
}
/* The words are always light, whatever the picture: white letters with a
   close, crisp shadow read over any tile without a glow round them. Where
   the tiles under them are light (chat.js measures them once the picture is
   cut), a soft shade settles behind the words, as deep as that picture
   needs and no deeper; over a dark picture it is not there at all. */
@property --scrim { syntax: "<number>"; inherits: true; initial-value: 0.32; }
:is(#view-chat, #view-agent) .welcome .copy{ isolation: isolate; transition: --scrim 700ms var(--ease); }
:is(#view-chat, #view-agent) .welcome .copy::before{
  content: "";
  position: absolute;
  z-index: -1;
  inset: -56px -12% -40px;
  pointer-events: none;
  background: radial-gradient(closest-side,
    color-mix(in srgb, var(--on-picture-dark) calc(var(--scrim) * 100%), transparent) 0%,
    color-mix(in srgb, var(--on-picture-dark) calc(var(--scrim) * 72%), transparent) 45%,
    color-mix(in srgb, var(--on-picture-dark) calc(var(--scrim) * 28%), transparent) 75%, transparent 100%);
}
:is(#view-chat, #view-agent) .welcome .copy :is(h1, p){ margin-bottom: 0; }
/* A little heavier than elsewhere: strokes that hold up over the grout. */
:is(#view-chat, #view-agent) .welcome .copy h1{ font-weight: 560; }
:is(#view-chat, #view-agent) .welcome .copy :is(h1, p){
  color: var(--on-picture-light);
  text-shadow: 0 1px 1px color-mix(in srgb, var(--on-picture-dark) 60%, transparent),
    0 1px 3px color-mix(in srgb, var(--on-picture-dark) 50%, transparent),
    0 0 1px color-mix(in srgb, var(--on-picture-dark) 65%, transparent);
}
:is(#view-chat, #view-agent) .welcome .copy p{ margin-top: 8px; }
/* What went wrong exactly, folded: over the picture, in the copy's colour. */
:is(#view-chat, #view-agent) .welcome .welcome-details{ margin-top: 8px; max-width: 56ch; font-size: var(--ui-small);
  color: var(--text2); animation: rise-in 520ms var(--ease-out) 160ms both; }
:is(#view-chat, #view-agent) .welcome .copy .welcome-details{ color: var(--on-picture-light);
  text-shadow: 0 1px 2px color-mix(in srgb, var(--on-picture-dark) 60%, transparent); }
/* The line above the greeting (an assistant's name, a temporary chat) is over the
   picture too, so it takes the picture's gold in either theme, not the page's ink. */
:is(#view-chat, #view-agent) .welcome .copy .kicker{ color: var(--tile-gold);
  text-shadow: 0 1px 2px color-mix(in srgb, var(--on-picture-dark) 70%, transparent); }
:is(#view-chat, #view-agent) .welcome .welcome-details summary{ cursor: pointer; user-select: none; opacity: .85; }
:is(#view-chat, #view-agent) .welcome .welcome-details .said{ display: block; margin-top: 4px; font-family: var(--font-mono);
  font-size: var(--ui-meta); white-space: pre-wrap; overflow-wrap: anywhere; user-select: text; }
:is(#view-chat, #view-agent) .welcome .copy .chips{ margin-top: 18px; }
:is(#view-chat, #view-agent) .welcome.leaving :is(.copy, .words){ animation: copy-out 280ms var(--ease) both; }
@keyframes copy-out { to { opacity: 0; transform: translateY(-14px); } }
:is(#view-chat, #view-agent) .welcome h1{
  margin: 0 0 10px;
  font-family: var(--display);
  font-size: clamp(28px, 3.2vw, 40px);
  font-weight: 480;
  letter-spacing: -0.02em;
  line-height: 1.12;
  color: var(--text);
  font-variation-settings: "SOFT" 50, "WONK" 0;
  animation: rise-in 520ms var(--ease-out) 80ms both;
}
:is(#view-chat, #view-agent) .welcome p{
  margin: 0;
  max-width: 56ch;
  color: var(--text2);
  font-size: 15.5px;
  line-height: 1.55;
  animation: rise-in 520ms var(--ease-out) 140ms both;
}
:is(#view-chat, #view-agent) .welcome .chips{
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  max-width: 760px;
  margin-top: 26px;
}
:is(#view-chat, #view-agent) .welcome .chip{
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 34px;
  padding: 0 13px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  color: var(--text);
  font-size: var(--ui-size);
  box-shadow: 0 1px 1px var(--shadow-soft);
  animation: rise-in 480ms var(--ease-out) both;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease),
    transform var(--dur) var(--ease-spring), box-shadow var(--dur) var(--ease);
}
:is(#view-chat, #view-agent) .welcome .chip:hover{
  border-color: var(--border-strong);
  transform: translateY(-2px);
  box-shadow: 0 8px 18px -10px var(--shadow-cast);
}
:is(#view-chat, #view-agent) .welcome .chip:active{ transform: translateY(0) scale(0.98); }
:is(#view-chat, #view-agent) .welcome .chip.primary{ background: var(--primary, var(--accent)); border-color: transparent; color: var(--primary-text, var(--accent-text)); font-weight: 600; }
:is(#view-chat, #view-agent) .welcome .chip.primary:hover{ background: var(--primary-hover, var(--accent-hover)); }
:is(#view-chat, #view-agent) .welcome .chip .tile{ width: 9px; height: 9px; }
:is(#view-chat, #view-agent) .welcome .facts{ display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 16px; }
:is(#view-chat, #view-agent) .welcome .fact{ display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--text2); padding: 4px 10px; border: 1px solid var(--border); border-radius: 999px; }
:is(#view-chat, #view-agent) .welcome .fact .icon{ width: 13px; height: 13px; }
:is(#view-chat, #view-agent) .welcome .abilities{ margin-top: 18px; font-size: 12.5px; color: var(--text3); }
:is(#view-chat, #view-agent) .welcome .abilities b{ font-weight: 500; color: var(--text2); }
:is(#view-chat, #view-agent) .welcome .abilities b + b::before{ content: "  ·  "; color: var(--text3); font-weight: 400; }

/* A welcome without the picture, inside a project. */
:is(#view-chat, #view-agent) .welcome.plain h1{ font-size: clamp(26px, 2.8vw, 34px); }
:is(#view-chat, #view-agent) .welcome.plain .kicker{
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 14px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text3);
}

/* A reply that saved something to memory wears a small mark among its
   buttons (chat.js chat.memories); opening it shows what, under the reply. */
#view-chat .act.mem-mark svg{ width: 13px; height: 13px; }
/* Saved just now: the mark arrives with a small pop and an accent ring that
   fades out, transforms and opacity only, once. */
#view-chat .act.mem-mark{ position: relative; }
#view-chat .act.mem-mark.fresh svg{ animation: mem-arrive 520ms var(--ease-out) both; }
#view-chat .act.mem-mark.fresh::after{
  content: "";
  position: absolute;
  inset: 4px;
  border-radius: 50%;
  border: 1.5px solid var(--accent);
  pointer-events: none;
  animation: mem-ring 900ms var(--ease-out) both;
}
@keyframes mem-arrive{
  0%{ opacity: 0; transform: scale(0.4); }
  60%{ opacity: 1; transform: scale(1.18); }
  100%{ opacity: 1; transform: none; }
}
@keyframes mem-ring{
  from{ opacity: 0.8; transform: scale(0.5); }
  to{ opacity: 0; transform: scale(1.5); }
}
#view-chat .act.mem-mark[aria-expanded="true"]{ color: var(--text2); }
#view-chat .remembered{
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 8px;
  margin-top: 2px;
  font-size: var(--meta, 12px);
  color: var(--text3);
  animation: settle-in var(--dur) var(--ease-out);
}
#view-chat .remembered[hidden]{ display: none; }
#view-chat .remembered .mem-label{ font-weight: 600; color: var(--text2); }
#view-chat .remembered .mem-what{ min-width: 0; }
#view-chat .remembered .mem-fact{ color: var(--text2); }
#view-chat .remembered .link{
  margin-left: 6px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text3);
  font: inherit;
  text-decoration: underline;
  text-decoration-color: var(--border-strong);
  text-underline-offset: 2px;
  cursor: pointer;
}
#view-chat .remembered .link:hover{ color: var(--text); }
#view-chat .remembered .manage{ margin-left: auto; }
/* Changes made to an answer after it was read (chat.js setEdits): a quiet
   count among its buttons, kept in view like the versions, that opens the
   list of them under the answer with Commit edits. */
#view-chat .actions .edits-mark{
  height: 22px;
  margin-left: 6px;
  padding: 0 9px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: transparent;
  color: var(--text2);
  font: inherit;
  font-size: var(--meta, 12px);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease),
    border-color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
#view-chat .actions .edits-mark:hover{ background: var(--surface-hover); border-color: var(--border-strong); color: var(--text); }
#view-chat .actions .edits-mark:active{ background: var(--surface-pressed); transform: scale(0.96); }
#view-chat .actions .edits-mark[aria-expanded="true"]{ background: var(--surface-hover); border-color: var(--border-strong); color: var(--text); }
#view-chat .msg.edited .actions{ opacity: 1; }
#view-chat .edit-list{
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 6px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  font-size: var(--meta, 12px);
  line-height: 1.5;
  color: var(--text2);
}
#view-chat .edit-list[hidden]{ display: none; }
#view-chat .edit-list .edit-row{
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 10px;
  row-gap: 2px;
  overflow-wrap: anywhere;
}
#view-chat .edit-list .edit-row + .edit-row{ padding-top: 8px; border-top: 1px solid var(--border); }
#view-chat .edit-list .edit-label{ color: var(--text3); }
#view-chat .edit-list .was{ color: var(--text2); text-decoration: none; }
#view-chat .edit-list .now{ color: var(--text); text-decoration: none; }
#view-chat .edit-list .edit-foot{ display: flex; justify-content: flex-end; margin-top: 2px; }
/* What goes to the model, on the conversation itself (chat.js
   decorateContext): a message always sent or left out wears a small tag, and
   the end of a summary, or of the message limit, is a quiet ruled line. */
#view-chat .msg .ctx-tag{
  display: inline-flex; align-items: center; gap: 5px;
  margin: 0 0 6px; padding: 2px 8px 2px 6px;
  border: 1px solid var(--border); border-radius: 999px;
  background: none; color: var(--text3);
  font: inherit; font-size: var(--meta, 12px); cursor: pointer;
  transition: color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out);
}
#view-chat .msg .ctx-tag .icon{ width: 12px; height: 12px; }
#view-chat .msg .ctx-tag:hover{ color: var(--text); border-color: var(--border-strong); }
#view-chat .msg.ctx-pin .ctx-tag{ color: var(--accent-ink); border-color: color-mix(in srgb, var(--accent) 40%, transparent); }
#view-chat .msg.ctx-out > .bubble,
#view-chat .msg.ctx-out > .body{ opacity: 0.5; transition: opacity var(--dur) var(--ease-out); }
#view-chat .msg.ctx-out:hover > .bubble,
#view-chat .msg.ctx-out:hover > .body{ opacity: 0.8; }
#view-chat .ctx-line{
  align-self: stretch;
  display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px;
  margin: calc(var(--message-gap, 28px) - 6px) 0 -6px;
  padding: 8px 0 0;
  border-top: 1px dashed var(--border-strong);
  font-size: var(--meta, 12px); color: var(--text3);
  animation: settle-in var(--dur) var(--ease-out);
}
#view-chat .ctx-line .icon{ width: 14px; height: 14px; color: var(--accent); }
#view-chat .ctx-line.dropped .icon{ color: var(--text3); }
#view-chat .ctx-line .ctx-say{ flex: 1 1 auto; min-width: 12em; }
#view-chat .ctx-line .link{
  padding: 0; border: 0; background: none; color: var(--text2); font: inherit; cursor: pointer;
  text-decoration: underline; text-decoration-color: var(--border-strong); text-underline-offset: 2px;
}
#view-chat .ctx-line .link:hover{ color: var(--text); }
/* The files sent with a question, above its bubble. */
#view-chat .msg.user .files{
  display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: flex-end; gap: 8px;
  max-width: 78%; margin-bottom: 8px;
}
#view-chat .file-card{
  display: inline-flex; align-items: center; gap: 10px;
  max-width: 260px; min-height: 48px; padding: 7px 14px 7px 8px;
  border: 1px solid var(--border); border-radius: 12px; background: var(--card);
  color: var(--text); font: inherit; text-align: left; cursor: pointer;
  transition: background var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}
#view-chat .file-card:hover{ background: var(--surface-hover, var(--card)); border-color: var(--border-strong, var(--border)); }
#view-chat .file-card:active{ transform: scale(0.98); }
#view-chat .file-card .kind{
  display: grid; place-items: center; flex: none; width: 32px; height: 32px;
  border-radius: 8px; background: var(--accent-wash); color: var(--accent-ink);
}
#view-chat .file-card .kind .icon{ width: 16px; height: 16px; }
#view-chat .file-card .text{ display: flex; flex-direction: column; min-width: 0; }
#view-chat .file-card .name{ font-size: 13px; font-weight: 550; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#view-chat .file-card .sub{ font-size: 11.5px; color: var(--text3, var(--text2)); }
#view-chat .file-card.picture{ padding: 0; overflow: hidden; min-height: 0; }
#view-chat .file-card.picture img{
  display: block; margin: 0; border: 0; border-radius: 0;
  max-width: 240px; max-height: 180px; width: auto; height: auto; object-fit: cover;
}

/* Files the model hands back: a card in the answer where the file was written,
   the way other AI apps link one: the kind's glyph in a cell of its own with
   a line beside it, the name, and what a click does. The whole card opens it;
   Save waits at its end until the pointer comes over it. */
#view-chat .out-card{
  position: relative; display: flex; flex-direction: column; width: fit-content; max-width: min(100%, 440px); min-width: 280px;
  margin: 10px 0; border: 1px solid var(--border); border-radius: 12px; background: var(--card);
  overflow: hidden; color: var(--text);
  transition: border-color var(--dur) var(--ease-out), background var(--dur) var(--ease-out);
}
/* A file being written: three lines drawn in one after another in its kind's
   cell, and a band of light 40% as wide as the card moved by transform from
   wholly off its left edge to wholly off its right along the card's foot.
   The design card shows the same while its design is written (css/design.css). */
#view-chat .pen-lines { display: flex; flex-direction: column; gap: 3px; width: 18px; color: var(--accent); }
#view-chat .pen-lines i {
  display: block; height: 2px; border-radius: 1px; background: currentColor;
  transform-origin: left center; transform: scaleX(0);
  animation: pen-line 1.8s var(--ease-out) infinite;
}
#view-chat .pen-lines i:nth-child(2) { animation-delay: 0.3s; }
#view-chat .pen-lines i:nth-child(3) { width: 62%; animation-delay: 0.6s; }
@keyframes pen-line {
  0% { transform: scaleX(0); opacity: 1; }
  35%, 78% { transform: scaleX(1); opacity: 1; }
  100% { transform: scaleX(1); opacity: 0; }
}
#view-chat .work-band { position: absolute; left: 0; right: 0; bottom: 0; height: 2px; overflow: hidden; pointer-events: none; }
#view-chat .work-band::before {
  content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 40%;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  transform: translateX(-100%); animation: work-band 1.3s linear infinite;
}
@keyframes work-band { from { transform: translateX(-100%); } to { transform: translateX(250%); } }
html.reduced-motion #view-chat .pen-lines i { animation: none; transform: none; }
html.reduced-motion #view-chat .work-band::before { animation: none; width: 100%; transform: none; opacity: 0.5; }
#view-chat .out-card:hover{ border-color: var(--border-strong, var(--border)); }
#view-chat .out-card.opens:hover{ background: var(--surface-hover, var(--card)); }
/* Stopped partway: an unfinished edge and a quieter glyph, still openable. */
#view-chat .out-card.stopped{ border-style: dashed; }
#view-chat .out-card.stopped .kind{ opacity: 0.55; }
/* Code that does not parse: the line it breaks on, in the warning ink. */
#view-chat .out-card.problem .sub{ color: var(--danger, var(--text2)); white-space: normal; }
#view-chat .out-card.problem .kind{ color: var(--danger, var(--text2)); }
#view-chat .out-card .out-row{ display: flex; align-items: stretch; min-width: 0; min-height: 54px; }
#view-chat .out-card .out-main{
  display: flex; align-items: stretch; flex: 1; min-width: 0;
  margin: 0; padding: 0; border: 0; border-radius: 0; background: none;
  font: inherit; color: inherit; text-align: left;
}
#view-chat .out-card button.out-main{ cursor: pointer; }
#view-chat .out-card button.out-main:focus-visible{ outline: none; box-shadow: inset 0 0 0 2px var(--accent); border-radius: 11px; }
#view-chat .out-card .kind{
  display: grid; place-items: center; flex: none; width: 54px; align-self: stretch;
  border-right: 1px solid var(--border); background: color-mix(in srgb, var(--text) 4%, var(--card)); color: var(--text2);
}
#view-chat .out-card .kind .icon{ width: 18px; height: 18px; }
#view-chat .out-card .text{ display: flex; flex-direction: column; justify-content: center; flex: 1; min-width: 0; padding: 8px 14px; line-height: 1.35; }
#view-chat .out-card .name{ font-size: 13.5px; font-weight: 550; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#view-chat .out-card .sub{ font-size: 12px; color: var(--text3, var(--text2)); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#view-chat .out-card.failed .sub, #view-chat .out-card.broken .sub{ color: var(--danger, var(--text2)); white-space: normal; }
#view-chat .out-card .out-acts{ display: flex; align-items: center; gap: 4px; flex: none; padding: 0 10px 0 0; }
#view-chat .out-card.opens .out-btn.bare{ opacity: 0; transition: opacity var(--dur) var(--ease-out), background var(--dur) var(--ease-out); }
#view-chat .out-card.opens:is(:hover, :focus-within) .out-btn.bare{ opacity: 1; }
#view-chat .out-card .out-btn{
  display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 12px;
  border: 1px solid transparent; border-radius: 999px; background: var(--soft);
  color: var(--text); font: inherit; font-size: 12.5px; font-weight: 550; cursor: pointer;
  transition: background var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out);
}
#view-chat .out-card .out-btn .icon{ width: 14px; height: 14px; }
#view-chat .out-card .out-btn:hover{ background: var(--soft-hover); }
#view-chat .out-card .out-btn.primary{ background: var(--accent-wash); border-color: transparent; color: var(--accent-ink); }
#view-chat .out-card .out-btn.primary:hover{ filter: brightness(0.97); }
#view-chat .out-card .out-btn.bare{ width: 30px; padding: 0; justify-content: center; background: transparent; color: var(--text2); }
#view-chat .out-card .out-btn.bare:hover{ background: var(--soft); }
#view-chat .out-card .out-thumb{
  display: block; padding: 0; margin: 0; border: 0; background: var(--surface-sunken, transparent); cursor: zoom-in;
}
#view-chat .out-card .out-thumb img{
  display: block; margin: 0; border: 0; border-radius: 0;
  max-width: 100%; max-height: 300px; width: auto; height: auto;
}
/* A picture's place is held, faintly, while it loads (chat.js holdPlace). */
#view-chat :is(.file-card.picture, .out-card .out-thumb) img{ background: var(--surface); }
/* A picture is just the picture: its name and buttons rise over its foot on
   hover, or while a button in it has the keyboard's focus. */
#view-chat .out-card.picture{ position: relative; min-width: 0; }
#view-chat .out-card.picture .out-row{
  position: absolute; left: 0; right: 0; bottom: 0; align-items: center; min-height: 0; padding: 30px 0 8px 0;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.66), rgba(0, 0, 0, 0.34) 60%, rgba(0, 0, 0, 0));
  color: #fff; opacity: 0; pointer-events: none; transition: opacity var(--dur) var(--ease-out);
}
#view-chat .out-card.picture:hover .out-row,
#view-chat .out-card.picture:focus-within .out-row{ opacity: 1; pointer-events: auto; }
#view-chat .out-card.picture .text{ padding: 0 10px 0 12px; }
#view-chat .out-card.picture .out-acts{ padding-right: 8px; }
#view-chat .out-card.picture .sub{ color: color-mix(in srgb, #fff 78%, transparent); }
#view-chat .out-card.picture .out-btn{ color: #fff; border-color: color-mix(in srgb, #fff 34%, transparent); background: rgba(0, 0, 0, 0.28); }
#view-chat .out-card.picture .out-btn:hover{ background: rgba(0, 0, 0, 0.46); }
#view-chat .out-card.picture .out-btn.primary{ background: #fff; border-color: transparent; color: #000; }
#view-chat .out-card.picture .out-btn.bare{ border-color: transparent; background: transparent; }

/* A picture and the row over it share a frame (chat.js outputCard); the
   words an answer gives it sit under the frame, a short name and a line. */
#view-chat .out-card .out-frame{ position: relative; display: block; min-width: 0; }
#view-chat .out-card.captioned{ background: transparent; border-color: transparent; overflow: visible; }
#view-chat .out-card.captioned .out-frame{ border-radius: inherit; overflow: hidden; }
#view-chat .out-caption{ display: flex; flex-direction: column; gap: 2px; padding: 7px 2px 0; line-height: 1.35; min-width: 0; }
#view-chat .out-caption .out-title{ font-size: 13.5px; font-weight: 600; color: var(--text); }
#view-chat .out-caption .out-line{ font-size: 12.5px; color: var(--text2); }

/* Pictures one after another in a reply, as a gallery (chat/outputs.py
   swap_tokens), laid out as the answer's <mosaik-pictures> group asks:
   grid      tiles of one shape two or three across, each picture filling its tile;
   tiles     small square tiles four across;
   cards     each picture in a box with its words inside, two across;
   large     each picture as wide as the answer, in its own shape;
   row       tall tiles in a row that scrolls sideways, with arrows at its sides.
   A click opens the viewer (js/picture_viewer.js), where each is seen whole. */
#view-chat .out-gallery {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin: 12px 0;
}
#view-chat .out-gallery[data-count="2"], #view-chat .out-gallery[data-count="4"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
#view-chat .out-gallery[data-layout="tiles"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }
#view-chat .out-gallery[data-layout="tiles"][data-count="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
#view-chat .out-gallery[data-layout="cards"] { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
#view-chat .out-gallery[data-layout="large"] { grid-template-columns: minmax(0, 1fr); gap: 14px; }
#view-chat .out-gallery .out-card { width: auto; min-width: 0; max-width: none; margin: 0; border-radius: 10px; }
#view-chat .out-gallery .out-card:not(.picture) { aspect-ratio: 4 / 3; justify-content: center; }
#view-chat .out-gallery .out-card .out-thumb { width: 100%; aspect-ratio: 4 / 3; }
#view-chat .out-gallery[data-layout="tiles"] .out-card .out-thumb { aspect-ratio: 1; }
#view-chat .out-gallery[data-layout="cards"] .out-card .out-thumb { aspect-ratio: 3 / 2; }
#view-chat .out-gallery .out-card .out-thumb img { width: 100%; height: 100%; max-height: none; object-fit: cover; }
#view-chat .out-gallery .out-card.picture .out-row { padding-top: 22px; }
#view-chat .out-gallery .out-card.picture .sub { display: none; }
#view-chat .out-gallery .out-card .out-thumb:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--accent); }

/* Large: the picture whole, as wide as the answer, never taller than most of the window. */
#view-chat .out-card.picture[data-layout="large"] { width: 100%; max-width: none; margin: 12px 0; border-radius: 12px; }
#view-chat .out-gallery .out-card.picture[data-layout="large"] { margin: 0; }
#view-chat .out-card.picture[data-layout="large"] .out-thumb { width: 100%; aspect-ratio: auto; }
#view-chat .out-card.picture[data-layout="large"] .out-thumb img { width: 100%; height: auto; max-height: 70vh; object-fit: cover; }

/* One picture on its own, with no layout given: centred in the answer. */
#view-chat .body > .out-card.picture:not([data-layout]) { margin: 14px auto; }
#view-chat .body > .out-card.picture:not([data-layout]) .out-thumb img { max-height: 380px; }
#view-chat .body > .out-card.picture:not([data-layout]) .out-caption { align-items: center; text-align: center; }

/* Right or left: the picture beside the words, which flow round it. A
   heading, a table, code or a gallery starts below it, and the reply holds it. */
#view-chat .out-card.picture:is([data-layout="right"], [data-layout="left"]) {
  width: min(42%, 320px); min-width: 0; max-width: none; border-radius: 12px;
}
#view-chat .out-card.picture[data-layout="right"] { float: right; margin: 6px 0 12px 22px; }
#view-chat .out-card.picture[data-layout="left"] { float: left; margin: 6px 22px 12px 0; }
#view-chat .out-card.picture:is([data-layout="right"], [data-layout="left"]) .out-thumb { width: 100%; }
#view-chat .out-card.picture:is([data-layout="right"], [data-layout="left"]) .out-thumb img {
  width: 100%; height: auto; max-height: 420px; object-fit: cover;
}
#view-chat .msg.assistant .body :is(h1, h2, h3, h4, hr, table, pre, .out-gallery, .out-card[data-layout="large"]) { clear: both; }
#view-chat .msg.assistant .body::after { content: ""; display: block; clear: both; }
/* Too narrow to share a line with words: centred above them instead. */
@media (max-width: 760px) {
  #view-chat .out-card.picture:is([data-layout="right"], [data-layout="left"]) {
    float: none; width: auto; max-width: min(100%, 440px); margin: 14px auto;
  }
}

/* Cards: the picture and its words in one box. */
#view-chat .out-gallery[data-layout="cards"] .out-card.picture,
#view-chat .out-gallery[data-layout="cards"] .out-card.picture.captioned {
  border: 1px solid var(--border); background: var(--card); border-radius: 12px; overflow: hidden;
}
#view-chat .out-gallery[data-layout="cards"] .out-card.captioned .out-frame { border-radius: 0; }
#view-chat .out-gallery[data-layout="cards"] .out-caption { padding: 10px 12px 12px; }

/* Row: tall tiles side by side; the row scrolls sideways and snaps to a tile. */
#view-chat .out-gallery[data-layout="row"] { display: block; position: relative; }
#view-chat .out-gallery[data-layout="row"] .out-track {
  display: grid; grid-auto-flow: column; grid-auto-columns: 220px; gap: 10px;
  overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; scrollbar-width: none;
  padding-bottom: 2px;
}
#view-chat .out-gallery[data-layout="row"] .out-track::-webkit-scrollbar { display: none; }
#view-chat .out-gallery[data-layout="row"] .out-card { scroll-snap-align: start; }
#view-chat .out-gallery[data-layout="row"] .out-card .out-thumb { aspect-ratio: 4 / 5; }
#view-chat .out-gallery .out-step {
  position: absolute; top: 121px; z-index: 2; /* the middle of a 220 by 275 tile */
  display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border: 0; border-radius: 50%;
  background: rgba(0, 0, 0, 0.5); color: #fff; cursor: pointer;
  opacity: 0; transition: opacity var(--dur) var(--ease-out), background var(--dur) var(--ease-out);
}
#view-chat .out-gallery .out-step[hidden] { display: none; }
#view-chat .out-gallery .out-step.before { left: 8px; }
#view-chat .out-gallery .out-step.after { right: 8px; }
#view-chat .out-gallery .out-step .icon { width: 18px; height: 18px; }
#view-chat .out-gallery:hover .out-step, #view-chat .out-gallery .out-step:focus-visible { opacity: 1; }
#view-chat .out-gallery .out-step:hover { background: rgba(0, 0, 0, 0.7); }

/* ---- assistants and @ ---------------------------------------------------- */
/* The New Chat page's saved assistants: pick one for the chat about to start. */
#view-chat .welcome .assistant-row{
  display: flex; flex-wrap: wrap; justify-content: center; gap: 8px;
  max-width: 760px; margin-top: 18px;
}
#view-chat .welcome .assistant-chip{
  display: inline-flex; align-items: center; gap: 8px;
  height: 34px; padding: 0 6px 0 5px;
  border: 1px solid var(--border); border-radius: 10px;
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  color: var(--text); font: 500 var(--ui-size)/1 var(--ui); cursor: pointer;
  box-shadow: 0 1px 1px var(--shadow-soft);
  animation: rise-in 480ms var(--ease-out) both;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease),
    transform var(--dur) var(--ease-spring), box-shadow var(--dur) var(--ease);
}
#view-chat .welcome .assistant-chip:hover{ border-color: var(--border-strong); transform: translateY(-2px);
  box-shadow: 0 8px 18px -10px var(--shadow-cast); }
#view-chat .welcome .assistant-chip:active{ transform: translateY(0) scale(0.98); }
#view-chat .welcome .assistant-chip .glyph{
  display: grid; place-items: center; width: 24px; height: 24px; border-radius: 7px; color: #fff;
}
#view-chat .welcome .assistant-chip .glyph .icon{ width: 14px; height: 14px; }
#view-chat .welcome .assistant-chip .more{
  display: grid; place-items: center; width: 22px; height: 22px; border-radius: 6px; color: var(--text3);
  opacity: 0; transition: opacity var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
#view-chat .welcome .assistant-chip .more .icon{ width: 14px; height: 14px; }
#view-chat .welcome .assistant-chip:hover .more,
#view-chat .welcome .assistant-chip:focus-visible .more,
#view-chat .welcome .assistant-chip.on .more{ opacity: 1; }
#view-chat .welcome .assistant-chip .more:hover{ background: var(--surface-hover); color: var(--text); }
#view-chat .welcome .assistant-chip.on{
  border-color: var(--accent); background: var(--accent-wash); color: var(--accent-ink);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
#view-chat .welcome .assistant-chip.add{ padding: 0 12px 0 9px; color: var(--text2); border-style: dashed;
  background: color-mix(in srgb, var(--surface) 78%, transparent); }
#view-chat .welcome .assistant-chip.add .icon{ width: 15px; height: 15px; }

/* What a question mentioned with @, under its bubble. */
#view-chat .msg.user .mentions{
  display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; max-width: 78%; margin-top: 6px;
}
#view-chat .mention-pill{
  display: inline-flex; align-items: center; gap: 5px; padding: 2px 9px 2px 7px;
  border-radius: 999px; font-size: 12px; color: var(--accent-ink); background: var(--accent-wash);
}
#view-chat .mention-pill .icon{ width: 12px; height: 12px; }
#view-chat .mention-pill.model{ color: var(--text2); background: var(--surface); border: 1px solid var(--border); }
#view-chat .mention-pill.chat{ color: var(--chart-3); background: color-mix(in srgb, var(--chart-3) 12%, transparent); }
#view-chat .mention-pill.link{ cursor: pointer; }
#view-chat .mention-pill.link:hover{ text-decoration: underline; text-underline-offset: 2px; }

/* A reply being read aloud. */
#view-chat .reading-bar{
  display: inline-flex; align-items: center; gap: 9px; margin-top: 10px; padding: 5px 12px 5px 10px;
  border: 1px solid var(--border); border-radius: 999px; background: var(--surface);
  font-size: 12.5px; color: var(--text2); width: max-content; animation: rise-in var(--dur-slow) var(--ease-out) both;
}
#view-chat .reading-bar .link{ padding: 0; border: 0; background: none; color: var(--accent-ink); font: inherit; font-weight: 600; cursor: pointer; }
#view-chat .reading-bar .wave{ display: inline-flex; align-items: center; gap: 2px; height: 14px; }
#view-chat .reading-bar .wave i{ display: block; width: 3px; height: 100%; border-radius: 2px; background: var(--accent);
  transform-origin: center; animation: reading-wave 900ms ease-in-out infinite; }
#view-chat .reading-bar .wave i:nth-child(2){ animation-delay: -700ms; }
#view-chat .reading-bar .wave i:nth-child(3){ animation-delay: -400ms; }
#view-chat .reading-bar .wave i:nth-child(4){ animation-delay: -200ms; }
#view-chat .reading-bar.preparing .wave i{ animation-duration: 1600ms; opacity: 0.5; }
@keyframes reading-wave { 0%, 100% { transform: scaleY(0.3); } 50% { transform: scaleY(1); } }

/* A file named in a question ([name]), drawn as it was in the message box. */
#view-chat .msg.user .file-ref{
  display: inline-flex; align-items: center; gap: 5px; padding: 0 7px 0 5px; margin: 0 1px;
  border: 1px solid var(--border-strong); border-radius: 6px; background: var(--card); color: var(--text2);
  vertical-align: baseline; line-height: 1.4; white-space: nowrap;
}
#view-chat .msg.user .file-ref .icon{ width: 13px; height: 13px; align-self: center; }

/* An answer cut off by its length limit: a quiet line under it, with the way
   to finish it (chat.js setCut). */
#view-chat .cut-note,
#view-chat .reminder-offer{
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 4px 0 2px;
  padding: 6px 6px 6px 12px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-md, 10px);
  font-size: var(--meta, 12px);
  color: var(--text2);
  animation: settle-in var(--dur) var(--ease-out);
}
#view-chat .cut-note .cut-text,
#view-chat .reminder-offer .offer-text{ flex: 1; min-width: 0; }
/* A reminder a reply offered (chat.js setOffer): the cut note's quiet line,
   with a bell. Once set, the line is solid: it stands for a real reminder. */
#view-chat .reminder-offer .offer-icon{ display: inline-flex; flex: none; color: var(--text3); }
#view-chat .reminder-offer .offer-icon svg{ width: 15px; height: 15px; }
#view-chat .reminder-offer[data-state="set"]{ border-style: solid; border-color: var(--border); }
#view-chat .reminder-offer[data-state="set"] .offer-icon{ color: var(--accent-ink, var(--accent)); }
/* Continue and Raise limit: a matched pair of words, the first to press
   raised on a soft edge, the second quiet until pointed at. */
#view-chat .cut-note .cut-go,
#view-chat .cut-note .cut-longer,
#view-chat .reminder-offer .offer-go,
#view-chat .reminder-offer .offer-no{ height: 26px; padding: 0 12px; border-radius: 999px; font-weight: 550; }
#view-chat .cut-note .cut-go,
#view-chat .reminder-offer .offer-go{ border-color: var(--border); box-shadow: 0 1px 2px rgba(0, 0, 0, .06); }
#view-chat .cut-note .cut-longer,
#view-chat .reminder-offer .offer-no{ color: var(--text2); }

/* Messages queued while an answer is written (chat/queue.py): under the
   answer, in the order they will go. */
#view-chat .queued-card{
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 10px 0 4px auto;
  width: min(100%, 560px);
  animation: rise-in var(--dur) var(--ease-out);
}
#view-chat .queued-head{
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  font-size: var(--meta, 12px);
  color: var(--text3);
}
#view-chat .queued-head .icon{ width: 13px; height: 13px; }
#view-chat .queued-item{
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px 8px 6px 12px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-lg, 14px);
  background: color-mix(in srgb, var(--user-bubble, var(--surface)) 60%, transparent);
}
#view-chat .queued-text{
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
  white-space: pre-wrap;
  overflow-wrap: break-word;
  color: var(--text2);
}
#view-chat .queued-actions{ display: flex; align-items: center; justify-content: flex-end; gap: 2px; }
#view-chat .queued-actions .btn{ margin-right: auto; }
#view-chat .queued-actions .btn .icon{ width: 14px; height: 14px; }
