.agent-composer {
  --composer-chip-height: 2rem;
  /* AR34 (doc 65 round 18, operator feedback): control-row height consistency
     — the attach button, engine badge, model picker, and Send previously
     each sourced their own height from unrelated rules (composer-attach-
     button's own 2rem min-height; .model-picker-button's 3px/9px padding;
     .engine-chip's bare 2px/9px padding, no floor at all; the Send button's
     .button padding) and landed at four different measured heights live
     (engine chip 20.3px, model picker 24.8px, Send 34.5px — attach button's
     own rule already landed near-target at 32px). 30px matches this
     codebase's own established compact-icon-control convention (files
     preview toolbar: `.fn-pv-icon-btn` = 6px padding around an 18px glyph =
     30px; `.dock-header .button { min-height:30px }`). This class is added
     by runtime/agent-composer.js (initializeAgentComposer/
     initializeLaunchAttachments) to every composer form — dock reply
     (#dock-instruct-form), standalone/session (#instruct-form, what the
     multi-dock rail's iframe actually renders), and the launch column
     (.agent-launch-column__form) — so scoping here is the one shared fix
     all three composer surfaces inherit, per the operator's own framing. */
  --composer-control-height: 30px;
  --composer-icon-size: 18px;
  /* Dock polish (doc 65): one internal inline padding shared by all four controls in the row
     (attach, engine chip, model chip, Send) so they read as one cluster.
     Previously attach sat at 7.68px, the two chips at 9px, and Send at 14px. */
  --composer-control-pad-inline: 0.625rem;
}

.agent-composer :is(.button, .model-picker-button) {
  font-size: 0.75rem;
}

/* The row itself: attach | engine badge | model picker | … | Send. Two
   deliberate exclusions, both left exactly as they already were:
   .agent-launch-column__submit ("button primary large") is the launch
   column's own bigger CTA, not this reply row's Send; .agent-launch-model-
   pill ("model-picker-button agent-launch-model-pill", dock-visual.css) is
   the launch column's pre-submit engine/model CARD (32px icon mark + two
   text lines) — a different control with a different job, not a chip in
   this row, so :not() keeps height:30px from clipping its own icon. */
.agent-composer .composer-attach-button,
.agent-composer .engine-cluster-badge .engine-chip,
.agent-composer .model-picker-button:not(.agent-launch-model-pill),
.agent-composer #instruct-submit,
.agent-composer #dock-instruct-submit {
  /* height (not min-height) + zeroed block padding, vertically centred by
     the box's own existing inline-flex/align-items:center — a floor alone
     left #instruct-submit/#dock-instruct-submit at 34.5px measured live
     (foundation.css's .button.primary already sets its own 13px font-size/
     8px vertical padding, taller than the 30px floor to begin with; a
     fixed height sidesteps that fight instead of chasing its cascade). */
  height: var(--composer-control-height);
  min-height: var(--composer-control-height);
  padding-block: 0;
  padding-inline: var(--composer-control-pad-inline);
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
}
.agent-composer .composer-attach-button svg,
.agent-composer .engine-cluster-badge svg {
  width: var(--composer-icon-size);
  height: var(--composer-icon-size);
}

.agent-composer .file-reference-input {
  border-radius: 0.55rem;
  transition: background-color 120ms ease, outline-color 120ms ease;
}

.agent-composer .file-reference-input.is-image-dragging {
  background: var(--ui-accent-faint);
  outline: 1px dashed var(--ui-accent);
  outline-offset: 0.3rem;
}

.composer-attachment-tray {
  display: flex;
  min-width: 0;
  gap: 0.4rem;
  margin: 0 0 0.45rem;
  overflow-x: auto;
  scrollbar-width: thin;
}

.composer-attachment-tray[hidden] {
  display: none;
}

.composer-image-chip,
.file-reference-chip {
  display: inline-flex;
  min-width: 0;
  min-height: var(--composer-chip-height);
  flex: 0 0 auto;
  align-items: center;
  gap: 0.4rem;
  border: 1px solid var(--ui-line);
  border-radius: 0.45rem;
  background: var(--ui-raised);
  color: var(--ui-text);
  padding: 0.22rem 0.32rem;
  font: 0.68rem/1.2 ui-monospace, SFMono-Regular, Menlo, monospace;
}

.composer-image-chip {
  max-width: 14rem;
}

.composer-image-chip.is-error {
  border-color: var(--ui-danger-line);
  background: var(--ui-danger-soft);
}

.composer-image-chip.is-pending {
  border-color: var(--ui-accent);
}

.composer-image-thumb {
  width: 2rem;
  height: 2rem;
  flex: 0 0 2rem;
  border-radius: 0.3rem;
  background: var(--ui-input);
  object-fit: cover;
}

.composer-image-thumb.is-file {
  display: grid;
  place-items: center;
  color: var(--ui-muted);
  font-size: 0.55rem;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.composer-image-copy {
  display: grid;
  min-width: 0;
  gap: 0.12rem;
}

.composer-image-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.composer-image-state {
  color: var(--ui-muted);
  font: 0.62rem/1.2 system-ui, sans-serif;
}

.composer-image-chip.is-error .composer-image-state {
  color: var(--ui-danger);
}

.composer-chip-remove {
  display: inline-grid;
  width: 1.5rem;
  height: 1.5rem;
  flex: 0 0 1.5rem;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--ui-muted);
  padding: 0;
  font-size: 0.75rem;
}

.composer-chip-remove:hover,
.composer-chip-remove:focus-visible {
  background: var(--ui-hover);
  color: var(--ui-text);
}

.composer-attachment-actions {
  display: inline-flex;
  min-width: 0;
  align-items: center;
  gap: 0.45rem;
  margin-right: auto;
}

.composer-attach-button {
  display: inline-flex;
  min-height: 2rem;
  align-items: center;
  gap: 0.35rem;
  padding: 0.3rem 0.48rem;
}

.composer-attach-button svg {
  width: 0.9rem;
  height: 0.9rem;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.7;
}

.composer-capability {
  margin: 0.4rem 0 0;
  color: var(--ui-muted);
  font-size: 0.68rem;
}

.composer-capability.is-capable {
  color: var(--ui-success);
}

.composer-capability.is-warning {
  color: var(--ui-warning);
}

.composer-capability a {
  color: inherit;
  font-weight: 650;
}

.composer-capability .button-link {
  border: 0;
  background: transparent;
  color: inherit;
  padding: 0;
  font: 700 0.75rem/1.2 system-ui, sans-serif;
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.file-reference-chip {
  max-width: min(24rem, 80vw);
  border-color: var(--ui-accent);
  background: var(--ui-accent-soft);
  color: var(--ui-text);
}

.file-reference-chip-icon {
  width: 0.88rem;
  height: 0.88rem;
  flex: 0 0 0.88rem;
  fill: none;
  stroke: var(--ui-accent);
  stroke-linejoin: round;
  stroke-width: 1.5;
}

.file-reference-chip-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-reference-option {
  display: grid;
  grid-template-columns: 1rem minmax(0, 1fr) auto;
}

.file-reference-option__copy {
  display: grid;
  min-width: 0;
  gap: 0.1rem;
}

.file-reference-option__name {
  display: flex;
  min-width: 0;
  max-width: none;
  overflow: hidden;
  white-space: nowrap;
}

.file-reference-option__name-start {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-reference-option__name-end {
  flex: 0 0 auto;
}

.file-reference-option__copy small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-reference-option-icon {
  width: 0.9rem;
  height: 0.9rem;
  fill: none;
  stroke: currentColor;
  stroke-linejoin: round;
  stroke-width: 1.5;
}

.file-reference-option time {
  color: var(--ui-muted);
  font-size: 0.75rem;
  white-space: nowrap;
}

.file-reference-summary {
  padding: 0.45rem 0.65rem;
  color: var(--ui-muted);
  font-size: 0.75rem;
  text-align: right;
}

.file-reference-freshness {
  flex: 0 0 auto;
  margin-left: auto;
  padding: 0.1rem 0.35rem;
  border-radius: 0.25rem;
  font-size: 0.65rem;
  font-weight: 650;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  white-space: nowrap;
}

.file-reference-freshness--fresh {
  color: color-mix(in srgb, var(--ui-ok, #2f7d4a) 85%, var(--ui-text));
  background: color-mix(in srgb, var(--ui-ok, #2f7d4a) 16%, transparent);
}

.file-reference-freshness--stale {
  color: color-mix(in srgb, var(--ui-warn, #a15c12) 90%, var(--ui-text));
  background: color-mix(in srgb, var(--ui-warn, #a15c12) 18%, transparent);
}

.transcript-attachments {
  display: flex;
  min-width: 0;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.55rem;
}

/* The transcript chips ARE the composer chips: the tray's chip CONTENT
   is built by the composer's own builder, so the composer-image-chip
   rules above are the single source of the look. The clickable control
   is a transparent shell — the foundation button/anchor chrome (border,
   radius, background, padding) is fully reset so ONLY the shared chip's
   frame is visible; focus semantics ride the control's own
   :focus-visible outline. */
.transcript-attachment {
  appearance: none;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: inherit;
  padding: 0;
  font: inherit;
  cursor: pointer;
  max-width: 100%;
  text-align: left;
  text-decoration: none;
  display: inline-flex;
}
.transcript-attachment:focus-visible {
  outline: 2px solid var(--ui-accent, var(--blue));
  outline-offset: 2px;
  border-radius: 0.5rem;
}

.attachment-preview {
  width: min(46rem, calc(100vw - 2rem));
  max-height: calc(100dvh - 2rem);
  border: 1px solid var(--ui-line);
  border-radius: 0.65rem;
  background: var(--ui-panel);
  color: var(--ui-text);
  padding: 0;
}

.attachment-preview::backdrop {
  background: rgb(4 9 16 / 0.78);
}

.attachment-preview header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  border-bottom: 1px solid var(--ui-line);
  padding: 0.7rem 0.85rem;
}

.attachment-preview img {
  display: block;
  max-width: 100%;
  max-height: calc(100dvh - 8rem);
  margin: auto;
  object-fit: contain;
}

.attachment-preview-empty {
  margin: 0;
  padding: 2rem;
  color: var(--ui-text-soft);
  text-align: center;
}

@media (max-width: 54rem) {
  .composer-attachment-actions {
    max-width: calc(100% - 4rem);
  }

  .composer-attach-button span {
    display: none;
  }

  .composer-attachment-tray {
    flex-wrap: nowrap;
  }

  .file-reference-picker {
    width: 100%;
  }

  .file-reference-option {
    grid-template-columns: 1rem minmax(0, 1fr);
  }

  .file-reference-option small,
  .file-reference-option time {
    grid-column: 2;
  }
}

@media (max-width: 820px) {
  /* T306: leave an explicit iOS/home-indicator safe zone inside every
     conversation composer.  The shell dock rail separately reserves the
     bottom frequency-bar row (T323 — Talk keeps the bar visible). */
  .composer,
  .dock-composer {
    padding-bottom: max(12px, env(safe-area-inset-bottom));
  }

  .composer,
  .dock-composer,
  body.agent-projection-dock .composer {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
  }

  .composer .file-reference-chips,
  .dock-composer .file-reference-chips,
  body.agent-projection-dock .file-reference-chips,
  .composer .composer-attachment-tray,
  .dock-composer .composer-attachment-tray {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    max-width: 100%;
  }

  .composer .actions.composer-actions,
  .dock-composer .dock-composer-row,
  body.agent-projection-dock .actions.composer-actions {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    min-width: 0;
    width: 100%;
  }

  :is(#session-close, #dock-close, .close, .dock-close) {
    min-width: 44px;
    min-height: 44px;
  }

  /* T308/T323: talk-mode composer fills width; textarea grows upward above the
     single controls row; frequency bar stays under the rail (T306 reserve). */
  body.talk-mode .composer,
  body.talk-mode .dock-composer,
  body.agent-projection-dock .composer {
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
  }

  body.talk-mode .composer textarea,
  body.talk-mode .dock-composer textarea,
  body.agent-projection-dock .composer textarea {
    width: 100%;
    max-width: 100%;
    min-height: 3.5rem;
    max-height: min(40vh, 14rem);
    resize: vertical;
    box-sizing: border-box;
  }
}

/* Dock polish (doc 65, operator round): the ≥44px phone tap-target floor for the four
   composer-row controls used to live in the plain `@media (max-width: 820px)`
   block above. A docked agent session renders inside an <iframe>, so that
   media query resolves against the IFRAME's viewport, not the device: a dock
   column measured 480px wide on a 1440px desktop, so the floor fired there and
   pushed attach/model/Send to 44px while the engine chip — never covered by
   that rule — stayed at the intended 30px. That is the measured height chaos
   (44 / 30 / 44 / 44).
   `pointer: coarse` is the correct signal for a tap-target floor: it is true on
   real touch devices (where the 44px minimum must hold, dock included) and
   false on a desktop pointer, so a narrow desktop dock iframe now keeps the
   compact --composer-control-height. */
@media (max-width: 820px) and (pointer: coarse) {
  .composer :is(.composer-attach-button, .model-picker-button, #instruct-submit),
  .dock-composer :is(.composer-attach-button, .model-picker-button, #dock-instruct-submit) {
    min-width: 44px;
    min-height: 44px;
  }
}

/* ── @-mentioned AGENTS — doc 82 §5 (AMENDED 2026-09-07) ────────────────
   `@` is agents, `#` is files; the two pickers share every layout rule so they
   feel identical, and differ only in the glyph and what a row carries.

   "The row is the name": the display name is never truncated. The file row's
   three-column grid (glyph / copy / time) would clamp it, so an agent row is a
   two-column grid whose copy cell is allowed to wrap — a long agent name grows
   the row's height instead of losing its end. */
.agent-reference-icon {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.4;
}

/* The option's icon takes the accent so an agent row is identifiable at a
   glance, and the row keeps no third column to squeeze the name. */
.agent-reference-option {
  grid-template-columns: 1rem minmax(0, 1fr);
  align-items: start;
}

.agent-reference-option .file-reference-option-icon {
  margin-top: 0.15rem;
  color: var(--ui-accent);
}

/* Overrides the shared .file-reference-option__name clamp: no ellipsis, no
   nowrap. This is the rule the "never truncated" contract rests on. */
/* Two classes deep on purpose: the shared picker clamps its title with
   `.file-reference-option strong { max-width:42%; text-overflow:ellipsis;
   white-space:nowrap }` (transitional-workspaces.css), an element selector that
   outranks a lone class. That clamp is exactly what doc 82 §5 retires for agent
   rows, so this rule has to win outright rather than partially — a half-win
   left the name wrapping but still capped at 42% width. */
.agent-reference-option .agent-reference-option__name {
  display: block;
  flex: 1 1 auto;
  max-width: none;
  overflow: visible;
  overflow-wrap: anywhere;
  white-space: normal;
  text-overflow: clip;
  font-size: 12.5px;
}

/* Shown ONLY when two active agents share a display name (doc 82 §5). Dimmed
   and in the machine face, so it reads as the disambiguator it is rather than
   as part of the name. */
.agent-reference-option__id {
  color: var(--ui-muted);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 400;
}

.agent-reference-option__detail {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin-top: 0.15rem;
  min-width: 0;
}

.agent-reference-option__tag {
  flex: 0 0 auto;
  padding: 0.05rem 0.35rem;
  border-radius: 999px;
  background: var(--ui-chip-bg);
  color: var(--ui-text-soft);
  font-size: 0.68rem;
  white-space: nowrap;
}

/* The chip keeps the file chip's shape; only the stroke changes, so a mixed
   row of file and agent chips still reads as one strip of references. */
.agent-reference-chip .file-reference-chip-icon {
  stroke: var(--ui-accent);
}
