/* The thread, shared by the Agents view and quick chat: the agent's
   settings beside it, the messages and their cards, Markdown in a body,
   the composer with its attachments, round button, @ picker, and model
   chip, and the working dot. */
@layer views {
  /* The thread, and beside it the agent's settings when they are open. */
  .thread-panel {
    position: relative;
    display: flex;
    flex: 1;
    min-height: 0;
  }

  .thread-main {
    display: flex;
    flex: 1;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
  }

  /* On a desk the agent's settings slide in from the right (agents.js adds
     is-open once the aside is drawn closed, and hides it when the exit
     ends); the thread gives up the width with the same timing, so its
     messages reflow with the pane. The panel clips only while the aside
     moves, so the composer's pickers are never cut off at its edges. */
  @media (min-width: 720px) {
    .thread-panel:has(> .thread-details.panel-sliding) { overflow: hidden; }
    .thread-panel > .thread-details {
      margin-right: -340px;
      opacity: 0;
      transform: translateX(24px);
      transition: margin-right 200ms ease-out, opacity 200ms ease-out, transform 200ms ease-out;
    }
    .thread-panel > .thread-details.is-open {
      margin-right: 0;
      opacity: 1;
      transform: none;
    }
    .thread-panel > .thread-details.panel-closing { pointer-events: none; }
    /* With the pane open the stage's bell and menu float over the pane, not
       the thread, so the header clears only the panel toggle and the pill
       keeps room for the name in a narrow column. */
    .thread-panel:has(> .thread-details.is-open) > .thread-floating > .thread-header {
      padding-left: 56px;
      padding-right: 56px;
    }
  }
  @media (prefers-reduced-motion: reduce) {
    .thread-panel > .thread-details { transition: none; }
  }

  /* The 96px foot lets the last control scroll clear of quick chat's button. */
  .thread-details {
    flex: 0 0 340px;
    min-height: 0;
    padding: var(--controls-h) 20px 96px;
    overflow: auto;
    overscroll-behavior: contain;
    border-left: 1px solid var(--line);
    background: var(--surface-column);
  }

  /* The pane's head: the avatar, the name (a button that renames it in
     place), the runtime it runs on, and the chevron that closes it. */
  .pane-head {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 12px;
  }
  .pane-avatar { display: flex; flex: none; }
  .pane-avatar .avatar { width: 40px; height: 40px; font-size: 15px; }
  .pane-head-text { flex: 1; min-width: 0; }
  .pane-head > .icon-button { flex: none; align-self: flex-start; }

  .details-name {
    margin: 0;
    font-family: var(--serif);
    font-size: 22px;
    font-weight: 400;
    line-height: 1.2;
  }
  .pane-name {
    max-width: 100%;
    padding: 2px 6px;
    margin: 0 -6px;
    border: 0;
    border-radius: 6px;
    background: none;
    color: var(--ink);
    font: inherit;
    text-align: left;
    overflow-wrap: anywhere;
    cursor: text;
  }
  @media (hover: hover) {
    .pane-name:hover { background: var(--hover-tint); }
  }
  .pane-name-input { width: 100%; font-size: 16px; }
  .pane-runtime { margin: 2px 0 0; color: var(--muted); font-size: 13px; }
  .pane-runtime[hidden] { display: none; }
  .pane-refusal { margin: -4px 0 12px; }

  /* The tabs under the head, and their panels. */
  /* The four icon tabs share the sheet's width evenly, down to a 320px phone. */
  .thread-details > .pane-tabs { margin: 0 -20px 16px; padding: 0 8px; --pane-tab-gap: 0; --pane-tab-padding: 8px; }
  .thread-details > #agent-pane-tabs.pane-tabs { margin: 0 0 16px; padding: 0; }
  .pane-panel[hidden] { display: none; }
  .pane-panel > .details-routines:first-child { margin-top: 0; padding-top: 0; border-top: 0; }

  /* The agent's settings as a form (a persona), one field per row. Save is
     off until a field changed; the validator's problems list under it. */
  .details-form {
    display: grid;
    gap: 12px;
  }

  /* Three columns on a desk, the outer two sharing what is left, so the
     pill stays centered whatever the controls beside it. This is quick
     chat's bar; the Agents view's row floats (.thread-floating, below). */
  .thread-header {
    display: grid;
    grid-template-columns: minmax(max-content, 1fr) minmax(0, auto) minmax(max-content, 1fr);
    align-items: center;
    gap: 8px 12px;
    padding: 12px 24px;
    border-bottom: 1px solid var(--line);
  }
  .thread-header > .thread-back { grid-column: 1; }
  .thread-header > .thread-title { grid-column: 2; }

  /* The way back to the list, a phone's only, while the To field shows. */
  .thread-back { display: none; }

  .thread-avatar { display: inline-flex; }
  .thread-avatar[hidden] { display: none; }

  /* The chips (the provider's 16px icon) hang off the pill's right side so
     they do not pull it off center; the title reserves their width and gap
     on both sides, so a long name ends in an ellipsis before the icon can
     reach New chat. */
  .thread-title {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    padding: 0 24px;
  }

  /* The agent's avatar and name on a raised pill, the composer box's
     surface. The border is a ring in the shadow, so the name is the pill's
     full 36px. The name's chevron shows on hover, focus, and while the
     settings are open. */
  .thread-pill {
    position: relative;
    display: inline-flex;
    align-items: stretch;
    min-width: 0;
    max-width: 100%;
    height: 36px;
    border-radius: 999px;
    background: var(--paper);
    box-shadow: 0 0 0 1px var(--line), 0 2px 10px var(--shadow-pop);
    color: var(--ink);
  }
  .thread-pill-name {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    height: 36px;
    padding: 0 14px 0 6px;
    border: 0;
    border-radius: 999px;
    background: none;
    color: inherit;
    font: inherit;
    transition: background-color 120ms ease;
  }
  .thread-pill-name:has(> .thread-avatar[hidden]) { padding-left: 14px; }
  button.thread-pill-name:not(:disabled) { cursor: pointer; }
  @media (hover: hover) {
    button.thread-pill-name:not(:disabled):hover { background: color-mix(in srgb, var(--ink) 4%, var(--paper)); }
  }
  button.thread-pill-name[aria-expanded="true"] { background: color-mix(in srgb, var(--ink) 6%, var(--paper)); }

  .thread-name {
    overflow: hidden;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.2;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .thread-pill-chevron {
    flex: none;
    width: 14px;
    margin: 0 -6px 0 -4px;
    color: var(--muted);
    opacity: 0;
    transition: opacity 120ms ease;
  }
  @media (hover: hover) {
    button.thread-pill-name:not(:disabled):hover .thread-pill-chevron { opacity: 1; }
  }
  button.thread-pill-name:focus-visible .thread-pill-chevron,
  button.thread-pill-name[aria-expanded="true"] .thread-pill-chevron { opacity: 1; }
  button.thread-pill-name:disabled .thread-pill-chevron { display: none; }

  @media (prefers-reduced-motion: reduce) {
    .thread-pill-name,
    .thread-pill-chevron { transition: none; }
  }

  .thread-chips {
    display: inline-flex;
    gap: 4px 8px;
  }
  .thread-chips:empty { display: none; }

  /* The Agents view's thread has no bar: the header is a row floating over
     the top of the messages, which scroll under it, and only its controls
     take the pointer. The row stops short of the scroller's scrollbar
     (thread-view.js measures it), and so does the fade: the column's paper
     to clear over the scroller's top, under the row. The messages start
     below the row; a title line, description, or notice above them starts
     below it too, and then the messages keep their own top and the fade
     only softens their edge. The column is its own stacking context, so the
     settings sheet still covers the row on a phone. */
  .thread-floating {
    --thread-row: 60px;
    --thread-fade: 56px;
    position: relative;
    isolation: isolate;
  }
  .thread-floating > .thread-header {
    position: absolute;
    top: 0;
    left: 0;
    right: var(--thread-scrollbar, 0px);
    z-index: 3;
    border-bottom: 0;
    background: none;
    pointer-events: none;
    /* Clear of the floating controls at both ends, so the pill stays
       centered between them. */
    padding-left: 112px;
    padding-right: 112px;
  }
  .thread-floating .thread-title { pointer-events: none; }
  .thread-floating .thread-back,
  .thread-floating .thread-pill { pointer-events: auto; }
  .thread-floating > .thread-messages {
    padding-top: calc(var(--thread-row) + 12px);
    scroll-padding-top: var(--thread-row);
  }
  .thread-floating > .thread-subtitle,
  .thread-floating > .thread-description,
  .thread-floating > .thread-notice { margin-top: var(--thread-row); }
  .thread-floating > .thread-subtitle:not([hidden]) ~ .thread-description,
  .thread-floating > .thread-subtitle:not([hidden]) ~ .thread-notice,
  .thread-floating > .thread-description:not([hidden]) ~ .thread-notice { margin-top: 0; }
  .thread-floating:has(> .thread-subtitle:not([hidden]), > .thread-description:not([hidden]), > .thread-notice:not([hidden])) {
    --thread-fade: 16px;
  }
  .thread-floating:has(> .thread-subtitle:not([hidden]), > .thread-description:not([hidden]), > .thread-notice:not([hidden])) > .thread-messages {
    padding-top: 16px;
    scroll-padding-top: 0;
  }
  .thread-fade {
    position: relative;
    z-index: 2;
    flex: none;
    height: 0;
    pointer-events: none;
  }
  .thread-fade::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: var(--thread-scrollbar, 0px);
    height: var(--thread-fade);
    background: linear-gradient(to bottom, var(--surface-column) 10%, color-mix(in srgb, var(--surface-column) 0%, transparent));
  }
  /* New chat's To field (thread-view.js to()): the column holds only a
     row at its top naming who the thread is with, a refusal under it, and
     the agents to choose from on a card, in the @ picker's rows. */
  .thread-composing > .thread-messages,
  .thread-composing > .thread-fade,
  .thread-composing .thread-title { display: none; }
  .thread-to {
    display: flex;
    flex: 1;
    flex-direction: column;
    min-height: 0;
    padding: 0 max(24px, calc((100% - 772px) / 2)) 24px;
  }
  /* In the Agents view the To row sits under the floating controls. */
  .thread-floating > .thread-to { margin-top: var(--controls-h); }
  .thread-to-row {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: var(--thread-row, 60px);
    border-bottom: 1px solid var(--line);
  }
  .thread-to-row:focus-within { border-bottom-color: var(--green); }
  .thread-to-label { flex: none; color: var(--muted); }
  .thread-to-input {
    flex: 1;
    min-width: 0;
    min-height: 44px;
    padding: 0;
    border: 0;
    outline: none;
    background: none;
    color: var(--ink);
    font: inherit;
    font-size: var(--field-font);
  }
  .thread-to-refusal {
    margin: 8px 0 0;
    color: var(--red);
    font-size: 13px;
  }
  .thread-to-menu {
    display: flex;
    flex: 0 1 auto;
    flex-direction: column;
    min-height: 0;
    margin-top: 12px;
    overflow: auto;
  }
  .thread-to-list {
    display: flex;
    flex-direction: column;
  }
  .thread-to-none {
    margin: 0;
    padding: 10px;
    color: var(--muted);
  }
  .thread-to-new-icon {
    display: inline-flex;
    flex: none;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 999px;
    background: var(--side);
    color: var(--muted);
  }

  .thread-description {
    margin: 0;
    padding: 16px 24px;
    color: var(--muted);
  }

  /* An archived thread: "This thread is archived." under the pill, and
     Unarchive. */
  .thread-subtitle {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 12px;
    margin: 0;
    padding: 6px 24px 0;
    color: var(--muted);
    font-size: 0.875rem;
  }

  .thread-subtitle[hidden] {
    display: none;
  }

  .thread-notice {
    margin: 0;
    padding: 10px 24px;
    background: var(--red-bg);
    color: var(--red);
    border-bottom: 1px solid var(--line);
  }

  /* The message column and, below, the composer row share one centered
     column (ChatGPT- and Claude-style), capped at 820px and full width
     below that. The thread header stays full width above them. The
     messages scroll in the pane's full width, so the scrollbar sits at
     the pane's right edge; the padding centers the column inside it (820px
     less the 24px gutters, the composer box's width). */
  .thread-messages {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: 12px;
    min-height: 0;
    width: 100%;
    padding: 16px max(24px, (100% - 772px) / 2);
    overflow: auto;
    overscroll-behavior: contain;
  }

  /* Thin, quiet scrollbars on the thread and its input. */
  .thread-messages,
  .composer-box .composer-input {
    scrollbar-width: thin;
    scrollbar-color: var(--rule) transparent;
  }

  .thread-pages {
    display: flex;
    gap: 16px;
  }

  .thread-line {
    margin: 0;
    color: var(--muted);
  }

  .thread-message {
    display: flex;
    flex-direction: column;
    gap: 2px;
    max-width: 44em;
  }
  .thread-message-user {
    align-self: flex-end;
    align-items: flex-end;
  }
  .thread-message-system {
    align-self: center;
    align-items: center;
  }

  .thread-message-text {
    padding: 10px 14px;
    border-radius: 10px;
    font-size: 15px;
    line-height: 1.5;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
  }
  .thread-message-user .thread-message-text {
    background: var(--bubble-user);
    color: var(--bubble-user-ink);
  }
  .thread-message-user .markdown a { color: var(--bubble-user-link); }
  .thread-message-user .markdown code,
  .thread-message-user .markdown pre { background: var(--bubble-user-code); }
  .thread-message-user .markdown pre code { background: none; }
  .thread-message-user .markdown pre { border-color: var(--bubble-user-code); }
  .thread-message-user .markdown blockquote {
    border-left-color: var(--bubble-user-code);
    color: var(--bubble-user-ink);
  }
  .thread-message-assistant .thread-message-text {
    background: var(--bubble-assistant);
    border: 1px solid var(--bubble-assistant-border);
  }
  .thread-message-system .thread-message-text {
    padding: 2px 0;
    color: var(--muted);
    font-size: 13px;
  }

  /* The message a notification opened the thread at: the Feed's mark for
     a post it opened at (.feed-item[data-feed-target]), fading over 1.5 s
     (thread-view.js MARK_MS), and held without the fade under reduced
     motion until it is taken off. */
  .thread-message[data-message-mark] {
    border-radius: 4px;
    background: var(--green-bg);
    box-shadow: 0 0 0 8px var(--green-bg);
    animation: thread-message-mark 1.5s ease-in forwards;
  }
  @keyframes thread-message-mark {
    to { background: transparent; box-shadow: 0 0 0 8px transparent; }
  }
  @media (prefers-reduced-motion: reduce) {
    .thread-message[data-message-mark] { animation: none; }
  }

  /* A settled question: one centered row per question, the answer with a
     check, or why none came in muted text. */
  .thread-question {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: center;
    gap: 2px 8px;
    padding: 2px 0;
    font-size: 13px;
    color: var(--muted);
    overflow-wrap: anywhere;
  }
  .thread-question .request-chip { align-self: center; }
  .thread-question-answer {
    color: var(--ink);
    font-weight: 600;
  }
  .thread-question-check {
    margin-left: 4px;
    color: var(--green);
  }

  /* A proposal: a card across the column while open, with its actions and
     Discuss; once answered, its title opening to the body, the chosen label
     and a check below the title. Its answered line is a centered sentence. */
  .thread-message-proposal {
    align-self: stretch;
    max-width: none;
  }
  .thread-message-proposal .thread-message-meta { text-align: center; }
  .proposal-card {
    padding: 12px 14px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--amber-bg);
  }
  .offer-card { background: var(--bubble-assistant); }
  .offer-card .proposal-title { margin-bottom: 12px; }
  .offer-card .settings-list-line { flex-wrap: nowrap; }
  .offer-card .button { white-space: nowrap; }
  .proposal-card-closed {
    padding: 0;
    border: 0;
    background: none;
  }
  .proposal-title {
    margin: 0 0 6px;
    font-size: 15px;
    font-weight: 600;
    overflow-wrap: anywhere;
  }
  .proposal-body {
    color: var(--ink);
    font-size: 15px;
    line-height: 1.5;
    overflow-wrap: anywhere;
  }
  /* What approving sets up, a checkbox per part, and once answered what
     became of each part, under the folded card. */
  .proposal-parts { margin: 10px 0 0; }
  .proposal-body + .thread-brief { margin-top: 10px; }
  .proposal-part {
    align-items: flex-start;
    min-height: 32px;
    padding: 6px 0;
    font-size: 15px;
    line-height: 1.4;
  }
  .proposal-part input { flex: none; margin-top: 1px; }
  .proposal-part-text { min-width: 0; overflow-wrap: anywhere; }
  .proposal-outcomes {
    display: grid;
    gap: 4px;
    margin: 8px 0 0;
    padding: 0 14px;
    list-style: none;
    font-size: 14px;
    line-height: 1.4;
  }
  .proposal-outcome { overflow-wrap: anywhere; }
  .proposal-outcome-link { color: var(--green); font-weight: 600; }
  .proposal-outcome-state { margin-left: 8px; color: var(--muted); }
  .proposal-outcome-failed { color: var(--red); }
  /* A message card's recipients and subject, above the draft. */
  .proposal-to { margin: 6px 0 0; color: var(--muted); font-size: 14px; overflow-wrap: anywhere; }
  @media (max-width: 719.98px) {
    .proposal-part { min-height: 44px; padding: 10px 0; }
  }
  .proposal-discuss {
    border-color: transparent;
    background: none;
  }
  .proposal-discuss:hover { border-color: var(--line); }
  .proposal-refusal {
    margin: 8px 0 0;
    color: var(--red);
    font-size: 13px;
  }
  .proposal-details > .proposal-summary {
    display: grid;
    grid-template-columns: 8px minmax(0, 1fr);
    gap: 4px 10px;
    align-items: baseline;
  }
  .proposal-summary::before { margin: 0; }
  .proposal-summary-title { min-width: 0; overflow-wrap: anywhere; }
  .proposal-choice {
    grid-column: 2;
    min-width: 0;
    font-weight: 600;
  }
  .proposal-check {
    margin-left: 4px;
    color: var(--green);
  }

  /* A purchase: a card across the column, the merchant and total over its
     state, the items and totals, the receipt once paid, the reason folded,
     and while open Approve (a link to Link's page), Dismiss, and Discuss. */
  .thread-message-purchase {
    align-self: stretch;
    max-width: none;
  }
  .thread-message-purchase .thread-message-meta { text-align: center; }
  .purchase-card {
    display: grid;
    gap: 8px;
    padding: 12px 14px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--paper);
  }
  .purchase-card[data-state="waiting"] { background: var(--amber-bg); }
  .purchase-card-closed { color: var(--muted); text-align: center; border: 0; background: none; }
  .purchase-gone { margin: 0; }
  .purchase-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 4px 12px;
  }
  .purchase-merchant { margin: 0; font-size: 15px; font-weight: 600; overflow-wrap: anywhere; }
  .purchase-total { font-weight: 600; font-variant-numeric: tabular-nums; }
  .purchase-state,
  .purchase-message,
  .purchase-finish,
  .purchase-test { margin: 0; font-size: 14px; overflow-wrap: anywhere; }
  .purchase-state.is-bad { color: var(--red); }
  .purchase-message,
  .purchase-test { color: var(--muted); }
  .purchase-link { color: inherit; text-decoration: underline; }
  .purchase-items { display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; font-size: 14px; }
  .purchase-item,
  .purchase-totals-row,
  .purchase-receipt-row {
    display: flex;
    justify-content: space-between;
    gap: 12px;
  }
  .purchase-item-name { min-width: 0; overflow-wrap: anywhere; }
  .purchase-item-price,
  .purchase-totals dd { font-variant-numeric: tabular-nums; }
  .purchase-totals,
  .purchase-receipt { display: grid; gap: 2px; margin: 0; font-size: 14px; }
  .purchase-totals { padding-top: 6px; border-top: 1px solid var(--line); color: var(--muted); }
  .purchase-totals .is-total { color: var(--ink); font-weight: 600; }
  .purchase-totals dd,
  .purchase-receipt dd { margin: 0; }
  .purchase-receipt dt { color: var(--muted); }
  .purchase-receipt dd { overflow-wrap: anywhere; text-align: right; }
  .purchase-reason-summary { min-height: 32px; }
  .purchase-reason-text { margin: 4px 0 0; font-size: 14px; line-height: 1.5; overflow-wrap: anywhere; }
  .purchase-approve {
    display: inline-flex;
    align-items: center;
    text-decoration: none;
  }
  .purchase-discuss {
    border-color: transparent;
    background: none;
  }
  .purchase-discuss:hover { border-color: var(--line); }

  /* A message's attached files, above its text: images as thumbnails up to
     240px, other files as tiles with their name and type; each opens the
     file in a new tab. */
  .thread-attachments {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: flex-end;
    gap: 6px;
    margin-bottom: 4px;
  }
  .thread-message-assistant .thread-attachments { justify-content: flex-start; }
  .thread-message-system .thread-attachments { justify-content: center; margin-top: 4px; }
  .thread-attachment-image {
    display: block;
    max-width: min(240px, 100%);
    line-height: 0;
    border-radius: 12px;
  }
  .thread-attachment-image img {
    display: block;
    max-width: 100%;
    max-height: 240px;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--bg);
    object-fit: cover;
  }
  .thread-attachment-file {
    display: flex;
    align-items: center;
    gap: 10px;
    max-width: 280px;
    min-height: 52px;
    padding: 8px 14px 8px 10px;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--paper);
    color: var(--ink);
    text-decoration: none;
  }
  .thread-attachment-file:hover { background: var(--bg); }
  .thread-attachment-icon {
    display: flex;
    flex: none;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 8px;
    background: var(--green-bg);
    color: var(--green);
  }
  .thread-attachment-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
  }
  .thread-attachment-name {
    overflow: hidden;
    font-size: 14px;
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .thread-attachment-type {
    color: var(--muted);
    font-size: 12px;
  }

  .thread-message-meta {
    padding: 0 4px;
    color: var(--muted);
    font-size: 12px;
  }

  /* A date line between days in a thread. */
  .thread-day {
    align-self: center;
    margin: 8px 0 0;
    color: var(--muted);
    font-size: 12px;
    letter-spacing: 0.02em;
    text-align: center;
  }

  /* The morning brief's notice: one line that opens to the memo. */
  .thread-message-brief {
    align-self: stretch;
    align-items: stretch;
    max-width: none;
  }
  .thread-message-brief .thread-message-meta { text-align: center; }
  .thread-brief {
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--paper);
  }
  /* The summary is a fold (components.css's .fold-mark): the chevron, in
     the accent, then the card's line. */
  .thread-brief-summary {
    display: block;
    min-height: 44px;
    padding: 11px 14px;
    box-sizing: border-box;
    color: var(--ink);
    font-size: 14px;
    line-height: 22px;
    overflow-wrap: anywhere;
  }
  .thread-brief[open] .thread-brief-summary { border-bottom: 1px solid var(--line); }
  .thread-brief-summary::before { border-color: var(--green); }
  .thread-brief-body {
    padding: 12px 14px 14px;
    color: var(--ink);
    font-size: 15px;
    line-height: 1.5;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
  }

  /* A message another agent sent: the sender's name above the bubble. */
  .thread-message-sender {
    display: inline-flex;
    align-items: center;
    gap: 2px;
  }
  .thread-message-from {
    padding: 0 4px;
    color: var(--muted);
    font-size: 12px;
    font-weight: 600;
    text-decoration: none;
  }
  .thread-message-from:hover,
  .thread-message-from:focus-visible { color: var(--ink); text-decoration: underline; }

  /* A line about a delegation: centered like a date line; the agent's name
     links to its thread. A finished one reuses the brief's disclosure row. */
  .thread-delegation-text a {
    color: var(--green);
    text-decoration: none;
  }
  .thread-delegation-text a:hover,
  .thread-delegation-text a:focus-visible { text-decoration: underline; }
  .thread-delegation-link {
    color: var(--green);
    text-decoration: none;
  }
  .thread-delegation-link:hover,
  .thread-delegation-link:focus-visible { text-decoration: underline; }

  /* An agent named with @ in a sent message. */
  .mention {
    display: inline-block;
    padding: 0 6px;
    border-radius: 999px;
    background: var(--side);
    color: var(--green);
    font-weight: 600;
    line-height: 1.35;
  }

  /* Markdown in a message body (markdown.js). A one-line message is one
     paragraph with no margins, so it reads as plain text did. */
  .markdown > :first-child { margin-top: 0; }
  .markdown :where(p, ul, ol, pre, blockquote, h3, h4, h5, hr) { margin: 0; }
  .markdown > * + *,
  .markdown li > * + *,
  .markdown blockquote > * + * { margin-top: 0.6em; }
  .markdown .md-heading {
    font-size: 1em;
    font-weight: 650;
    line-height: inherit;
  }
  .markdown h3.md-heading { font-size: 1.07em; }
  .markdown * + .md-heading { margin-top: 0.9em; }
  .markdown ul,
  .markdown ol { padding-left: 1.4em; }
  .markdown li + li { margin-top: 0.2em; }
  .markdown li > ul,
  .markdown li > ol { margin-top: 0.2em; }
  .markdown code {
    padding: 0.1em 0.3em;
    border-radius: 4px;
    background: var(--side);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.88em;
  }
  .markdown pre {
    padding: 10px 12px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--side);
    overflow-x: auto;
    white-space: pre;
    overflow-wrap: normal;
  }
  .markdown pre code {
    padding: 0;
    background: none;
    font-size: 13px;
    line-height: 1.45;
  }
  .markdown blockquote {
    padding-left: 12px;
    border-left: 3px solid var(--line);
    color: var(--ink-soft);
  }
  .markdown hr {
    height: 0;
    border: 0;
    border-top: 1px solid var(--line);
  }
  .markdown a { color: var(--green); }

  .thread-request {
    max-height: 60%;
    padding: 12px 24px;
    overflow: auto;
    background: var(--amber-bg);
    border-top: 1px solid var(--line);
  }

  .request-card {
    padding: 12px 0;
  }
  .request-card + .request-card { border-top: 1px solid var(--border-faint); }

  .request-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 8px;
    margin-bottom: 8px;
  }

  .request-chip {
    padding: 1px 8px;
    border-radius: 999px;
    background: var(--paper);
    color: var(--amber);
    font-size: 12px;
    font-weight: 600;
  }

  .request-title {
    margin: 0;
    font-size: 15px;
    font-weight: 600;
    overflow-wrap: anywhere;
  }

  .request-options {
    display: grid;
    gap: 8px;
  }

  .option {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    min-height: 44px;
    padding: 8px 12px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--paper);
    color: var(--ink);
    font: inherit;
    text-align: left;
    cursor: pointer;
  }
  .option:hover { border-color: var(--rule); }
  .option[aria-pressed="true"] {
    border-color: var(--green);
    background: var(--green-bg);
    box-shadow: inset 0 0 0 1px var(--green);
  }
  .option:disabled { color: var(--muted); cursor: default; }

  .option-label { font-weight: 600; }
  .option-description { color: var(--muted); font-size: 13px; }

  .request-other {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 10px;
    margin-top: 8px;
  }
  .request-other-label { font-weight: 600; }

  .request-other-field {
    flex: 1;
    min-width: 160px;
    min-height: var(--field-height);
    padding: 0 var(--field-pad-x);
    border: 1px solid var(--line);
    border-radius: 7px;
    background: var(--paper);
    color: var(--ink);
    font: inherit;
  }

  .request-input {
    max-height: 240px;
    margin: 0 0 8px;
    padding: 10px 12px;
    overflow: auto;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--paper);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12px;
    line-height: 1.45;
    white-space: pre;
  }

  .request-note {
    margin: 0 0 8px;
    color: var(--amber);
    font-size: 13px;
  }

  /* An approval's command, folder, files, or permissions. */
  .request-details {
    display: grid;
    /* A long command or input scrolls inside the card. */
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
    margin: 0 0 8px;
  }
  .request-detail { margin: 0; }
  .request-detail-label {
    display: block;
    color: var(--muted);
    font-size: 12px;
    font-weight: 600;
  }
  .request-detail .request-input { margin: 4px 0 0; }
  .request-detail ul {
    margin: 0;
    padding-left: 1.2em;
    overflow-wrap: anywhere;
  }
  .request-detail-text { overflow-wrap: anywhere; }

  .request-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
    padding-top: 8px;
  }

  .request-missing { color: var(--red); font-size: 13px; }

  /* The thread's own composer: one rounded box in the message column's
     centered width, with no divider above it, holding the input and, under
     it, the bar (the attach slot, the model button or note, and the round
     button). Focus anywhere in the box rings the box. Other composers
     (Goals, Feed instructions) keep the plain .composer look. */
  .composer.thread-composer {
    padding-top: 4px;
    padding-bottom: max(16px, var(--composer-inset-bottom, env(safe-area-inset-bottom)));
    border-top: 0;
  }
  .thread-composer .composer-box,
  .thread-composer .composer-reason,
  .thread-composer .composer-runtime-trouble {
    max-width: 820px;
    margin-inline: auto;
  }
  .thread-composer .composer-reason {
    margin-top: 8px;
    padding: 0 18px;
  }

  .thread-composer .composer-runtime-trouble {
    margin-top: 0;
    margin-bottom: 8px;
    padding: 0 18px;
    color: var(--red);
    font-size: 13px;
  }

  /* The paperclip at the bar's left, a 44px target like the round button. */
  .attach-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none;
    color: var(--muted);
    cursor: pointer;
  }
  .attach-button:hover,
  .attach-button:focus-visible { color: var(--ink); background: var(--bg); }
  .attach-button:disabled { color: var(--faint); background: none; cursor: default; }

  /* Dictate, between the model button and the round button, in the
     paperclip's look. While listening it is Stop, the square icon on the
     tint a pressed or open button takes. The piece still being heard is
     the line under the box, in italics. */
  .mic-button { flex: none; }
  .mic-button[data-mode="dictate"] .mic-button-stop,
  .mic-button[data-mode="listening"] .mic-button-mic { display: none; }
  .mic-button[data-mode="listening"] { color: var(--ink); background: var(--bg); }
  .composer-reason.composer-reason-heard { font-style: italic; }
  /* Sign in after a runtime's sentence: the thread's Retry link, at the
     reason line's size. */
  .composer-reason .composer-sign-in,
  .composer-runtime-trouble .composer-sign-in { min-height: 0; padding: 0 2px; font-size: inherit; }

  /* The attached files above the input: 64px rounded squares, an image as
     its thumbnail and any other file as an icon over its name and type. A
     spinner covers a tile while it uploads, a failed one is ringed in red,
     and the x at the corner removes it: a small dark disc in a 44px target,
     shown on hover or focus with a pointer and always on touch. */
  .attach-tile {
    position: relative;
    flex: none;
    width: 64px;
    height: 64px;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--bg);
  }
  .attach-thumb {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 11px;
    object-fit: cover;
  }
  .attach-file {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    height: 100%;
    padding: 4px 5px;
    color: var(--muted);
    text-align: center;
  }
  .attach-icon { display: inline-flex; }
  .attach-name {
    max-width: 100%;
    overflow: hidden;
    color: var(--ink);
    font-size: 11px;
    line-height: 1.3;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .attach-ext {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.03em;
  }
  .attach-tile[data-status="preparing"] > :not(.attach-spinner):not(.attach-remove),
  .attach-tile[data-status="uploading"] > :not(.attach-spinner):not(.attach-remove) { opacity: 0.45; }
  .attach-spinner {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 22px;
    height: 22px;
    margin: -11px 0 0 -11px;
    border: 2px solid var(--line);
    border-top-color: var(--ink);
    border-radius: 50%;
    animation: attach-spin 0.8s linear infinite;
  }
  @keyframes attach-spin { to { transform: rotate(360deg); } }
  @media (prefers-reduced-motion: reduce) {
    .attach-spinner { animation-duration: 2.4s; }
  }
  .attach-tile[data-status="failed"] {
    border-color: var(--red);
    box-shadow: 0 0 0 1px var(--red);
  }
  .attach-tile[data-status="failed"] > .attach-thumb,
  .attach-tile[data-status="failed"] > .attach-file { opacity: 0.45; }
  .attach-failed {
    position: absolute;
    top: 50%;
    left: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    margin: -11px 0 0 -11px;
    border-radius: 50%;
    background: var(--red);
    color: var(--on-accent);
    font-size: 13px;
    font-weight: 700;
  }
  .attach-remove {
    position: absolute;
    top: -16px;
    right: -16px;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    opacity: 0;
  }
  .attach-tile:hover .attach-remove,
  .attach-remove:focus-visible { opacity: 1; }
  @media (hover: none) {
    .attach-remove { opacity: 1; }
  }
  .attach-remove-disc {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border: 1.5px solid var(--paper);
    border-radius: 50%;
    background: var(--ink);
    color: var(--paper);
  }
  .attach-remove:hover .attach-remove-disc { background: var(--ink-soft); }

  /* The round button: Send (an arrow) while the turn is closed, Stop (a
     square) while it is open, a 36px disc inside a 44px target. The ink
     disc fades when Send has nothing to send. */
  .round-button {
    display: inline-flex;
    flex: none;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 4px;
    border: 0;
    border-radius: 50%;
    background: var(--ink);
    background-clip: content-box;
    color: var(--paper);
    cursor: pointer;
  }
  .round-button:hover { background-color: var(--ink-soft); }
  .round-button:focus-visible { outline-offset: 0; }
  .round-button:disabled {
    background-color: var(--line);
    color: var(--muted);
    cursor: default;
  }
  /* The dark composer is lighter than a hairline, so the faded disc takes
     the rule to stay a disc. */
  :root[data-theme="dark"] .round-button:disabled { background-color: var(--rule); }
  .round-button[data-mode="send"] .round-button-stop,
  .round-button[data-mode="stop"] .round-button-send { display: none; }

  /* The @ picker over the input: the agents whose name starts with what was
     typed, one per row by name. It stays over the input at every
     width, so the text being typed is never covered. */
  .mention-menu {
    position: absolute;
    bottom: calc(100% + 6px);
    left: 0;
    z-index: 3;
    display: flex;
    flex-direction: column;
    width: min(360px, 100%);
    max-height: 264px;
    overflow: auto;
  }
  /* An agent in the @, To, and quick chat menus: a menu entry
     (components.css's .menu-entry) with the avatar before the name. */
  .mention-option {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: var(--menu-row);
    padding: 0 10px;
    border: 0;
    border-radius: var(--radius-entry);
    background: none;
    color: var(--ink);
    font: inherit;
    text-align: left;
    cursor: pointer;
  }
  .mention-option:hover { background: var(--hover-tint); }
  .mention-option[aria-selected="true"] { background: var(--button-tint-hover); }
  .mention-option-name { font-weight: 500; }

  /* In the bar, beside the round button: the model and effort the next
     turn runs on, as a bare button that opens the picker above the box (a
     sheet from the bottom on a phone). */
  .model-button {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    min-height: 44px;
    padding: 0 10px;
    border: 0;
    border-radius: 7px;
    background: none;
    color: var(--muted);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
  }
  .model-button:hover,
  .model-button:focus-visible,
  .model-button[aria-expanded="true"] { color: var(--ink); background: var(--bg); }
  /* The dark composer is raised off the page, so its buttons tint up from
     it rather than down to the page. */
  :root[data-theme="dark"] :is(.attach-button, .model-button):not(:disabled):is(:hover, :focus-visible),
  :root[data-theme="dark"] .mic-button[data-mode="listening"]:not(:disabled),
  :root[data-theme="dark"] .model-button[aria-expanded="true"]:not(:disabled) {
    background: color-mix(in srgb, var(--ink) 8%, var(--composer));
  }
  .model-button:disabled {
    color: var(--muted);
    background: none;
    cursor: default;
  }
  .model-button svg { flex: none; }
  /* Short of room the name ends in an ellipsis. */
  .model-button { max-width: 100%; min-width: 0; }
  .model-button > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  .model-menu {
    position: absolute;
    bottom: calc(100% + 6px);
    right: 0;
    z-index: 3;
    width: min(420px, 100%);
    padding: 12px 10px 10px;
  }
  .model-menu-heading {
    margin: 0 0 4px;
    padding: 0 10px;
    color: var(--muted);
    font-size: 13px;
    font-weight: 500;
  }
  .model-menu-heading + .model-menu-heading,
  .model-list + .model-menu-heading { margin-top: 12px; }
  .model-list {
    display: flex;
    flex-direction: column;
  }
  .model-option {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    min-height: var(--menu-row);
    padding: 0 10px;
    border: 0;
    border-radius: var(--radius-entry);
    background: none;
    color: var(--ink);
    font: inherit;
    text-align: left;
    cursor: pointer;
  }
  .model-option:hover { background: var(--hover-tint); }
  .model-option[aria-selected="true"] {
    background: var(--green-bg);
    font-weight: 600;
  }
  .model-option-default {
    color: var(--muted);
    font-size: 12px;
    font-weight: 400;
  }
  .effort-row {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
  }
  /* Effort's levels are secondary buttons in a row, the chosen one in the
     accent's tint. */
  .effort-option {
    flex: 1 1 0;
    min-height: var(--menu-row);
    padding: 0 8px;
    white-space: nowrap;
    border: 1px solid transparent;
    border-radius: var(--radius-entry);
    background: var(--button-tint);
    color: var(--ink);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
  }
  .effort-option:hover { background: var(--button-tint-hover); }
  .effort-option[aria-pressed="true"] {
    border-color: var(--green);
    background: var(--green-bg);
    font-weight: 600;
  }
  .model-menu-reset {
    display: block;
    min-height: var(--menu-row);
    margin: 6px 0 0;
    padding: 0 10px;
    border: 0;
    background: none;
    color: var(--green);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
  }
  .model-menu-reset:hover,
  .model-menu-reset:focus-visible { color: var(--green-dark); }
  .model-menu-reset:disabled { color: var(--muted); cursor: default; }

  /* The agent is working: a dot after the last message that breathes, as
     ChatGPT's does, and holds still under reduced motion. */
  .thread-working {
    flex: none;
    width: 10px;
    height: 10px;
    margin: 6px 0 6px 6px;
    border-radius: 50%;
    background: var(--ink);
    animation: thread-working 1.2s ease-in-out infinite;
  }
  @keyframes thread-working {
    0%, 100% { transform: scale(0.8); opacity: 0.55; }
    50% { transform: scale(1.15); opacity: 1; }
  }
  @media (prefers-reduced-motion: reduce) {
    .thread-working { animation: none; }
  }

  .thread-failure {
    margin: 0;
    padding: 0 24px 12px;
    color: var(--red);
    font-size: 13px;
  }

  @media (max-width: 719.98px) {
    /* One floating row: the outer columns kept clear for the band's toggle
       (or the way back) and its menu, the pill centered between them and as
       wide as the space between them allows. With the row's 12px and the 8px
       gap, each column ends 64px in, past the band's 56px (a 44px control
       from 12px in), and the name ends in an ellipsis only when the space
       runs out. Nothing wraps. The pill and the way back match the band's
       44px rounds and sit on their line. */
    .thread-floating { --thread-row: 52px; --thread-fade: 60px; }
    .thread-floating .thread-title { padding: 0; }
    .thread-floating > .thread-header {
      grid-template-columns: 44px minmax(0, 1fr) 44px;
      gap: 8px;
      padding-top: 6px;
      padding-bottom: 2px;
      padding-left: 12px;
      padding-right: 12px;
    }
    .thread-composing.thread-floating .thread-back { display: inline-flex; }
    /* The way back sits on a round of the controls' fill, so the messages
       passing under it never show through. */
    .thread-floating .ghost-button {
      width: 44px;
      height: 44px;
      border-radius: 999px;
      background: var(--float-fill);
      box-shadow: 0 0 0 1px var(--line), 0 2px 10px var(--shadow-pop);
    }
    /* Under a pointer it still takes the ghost button's hover tint. */
    @media (hover: hover) {
      .thread-floating .ghost-button:hover:not(:disabled) { background: var(--hover-tint); }
    }
    .thread-floating .thread-pill { height: 44px; background: var(--float-fill); }
    .thread-floating button.thread-pill-name[aria-expanded="true"] { background: color-mix(in srgb, var(--ink) 10%, var(--paper)); }
    .thread-floating .thread-pill-name { gap: 8px; height: 44px; padding: 0 16px 0 10px; }
    .thread-floating .thread-pill-name:has(> .thread-avatar[hidden]) { padding-left: 16px; }
    .thread-floating button.thread-pill-name:not([aria-expanded="true"]):not(:focus-visible) .thread-pill-chevron { display: none; }
    .thread-floating > .thread-to { padding-left: 16px; padding-right: 16px; }

    /* The settings cover the whole thread and stay under the floating
       controls (5). */
    .thread-details {
      position: absolute;
      inset: 0;
      z-index: 1;
      padding: var(--controls-h) 16px 96px;
      border-left: 0;
    }
    .thread-details > .pane-tabs { margin: 0 -16px 16px; padding: 0 4px; --pane-tab-padding: 6px; }
    .thread-details > #agent-pane-tabs.pane-tabs { margin: 0 0 16px; padding: 0; }

    .thread-header,
    .thread-notice,
    .thread-description,
    .thread-subtitle,
    .thread-messages,
    .thread-request,
    .composer,
    .thread-failure {
      padding-left: 16px;
      padding-right: 16px;
    }

    /* The @ picker stays over the input on a phone, so what is typed stays
       in view; only the model picker becomes a sheet from the bottom. */
    .mention-menu { max-height: 200px; }
    .model-menu {
      position: fixed;
      inset: auto 0 var(--nav-bar-h);
      z-index: 7;
      width: auto;
      padding: 16px 10px;
      border-radius: var(--radius-card) var(--radius-card) 0 0;
      box-shadow: 0 -8px 24px var(--shadow-sheet);
    }
  }
}
