/* Chat composer (Chat::ComposerComponent): all state visuals derive
   from `data-state` on the form root — set by chat--composer, never
   toggled class-by-class in JS (FE-4).

   States: idle | submitting | locked | cancelling
     idle       — send button (label) visible, stop hidden
     submitting — send button shows its spinner instead of the label
     locked     — send hidden, stop visible (a turn is streaming)
     cancelling — like locked; the stop button is disabled by the
                  controller while the cancel POST settles */

/* Positioning context for the mention popup (components/chat_mention.css)
   — declared here because this file owns the form block. */
.chat-composer-form {
  position: relative;
}

/* Auto-growing input bounds (the contenteditable editor grows
   naturally with its content; CSS owns the bounds — the buttons that
   pin to the bottom edge while it grows live in chat.css'
   .chat-composer block). */
.chat-composer-input {
  /* ~6 lines, then scroll internally. */
  max-height: 10rem;
  line-height: 1.4;
}

/* The contenteditable composer editor (chat--editor): grows naturally
   with content — the .chat-composer-input max-height still caps it,
   but a div needs auto overflow instead of the textarea's autogrow
   toggle. Line breaks are literal (<br>), so wrap like a textarea. */
.chat-composer-editor {
  /* Background rides a custom property so state modifiers only swap
     the variable. Default = var(--tblr-bg-forms), exactly what the
     element's .form-control class would paint (tabler.min.css). */
  --chat-composer-editor-bg: var(--tblr-bg-forms);
  background-color: var(--chat-composer-editor-bg);
  overflow-y: auto;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  min-block-size: calc(1.4em + 0.875rem);
}

/* Canonical empty state from the serializer (chat--editor#sync) —
   `:empty` lies once browsers leave filler <br>s or caret guards
   behind. The placeholder is absolutely positioned OUT of the inline
   flow: an in-flow ::before participates in the contenteditable line
   box and the caret renders after the placeholder text instead of at
   the start of the field. padding: inherit drops it exactly where
   typed text begins. */
.chat-composer-editor {
  position: relative;
}

.chat-composer-editor[data-empty="true"]::before {
  content: attr(data-placeholder);
  position: absolute;
  inset: 0;
  padding: inherit;
  color: var(--gxp-slate-400);
  pointer-events: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chat-composer-editor[aria-readonly="true"] {
  --chat-composer-editor-bg: var(--tblr-bg-surface-secondary);
}

/* Armed drop zone: an in-app drag (drag-payload source) is live
   somewhere on the surface — the input already hints that it accepts
   the payload before the pointer reaches it. Subtle on purpose; the
   hover state below (same specificity, later in the file) takes over
   with the full highlight.

   Both selectors stack three classes on purpose: Tabler's
   `.form-control:focus { outline: 0 }` (0,2,0) must not kill the
   highlight while the composer is focused — the usual state when a
   drag starts. */
.form-control.chat-composer-editor.chat-composer-editor--drop-ready {
  outline: 2px dashed var(--traqx-blue-300);
  outline-offset: -2px;
}

/* Live drop zone: while a droppable payload (mention token or file)
   hovers the editor, chat--drops toggles this class — the input
   announces itself as the valid target. Inset outline so the field
   doesn't grow or shift. */
.form-control.chat-composer-editor.chat-composer-editor--drop-zone {
  --chat-composer-editor-bg: var(--traqx-blue-50);
  outline: 2px dashed var(--traqx-blue-600);
  outline-offset: -2px;
}

.chat-composer .chat-composer-cancel {
  display: none;
}

.chat-composer .chat-composer-submit-spinner {
  display: none;
}

.chat-composer-form[data-state="submitting"] .chat-composer-submit-label {
  display: none;
}

.chat-composer-form[data-state="submitting"] .chat-composer-submit-spinner {
  display: inline-block;
}

.chat-composer-form[data-state="locked"] .chat-composer-submit,
.chat-composer-form[data-state="cancelling"] .chat-composer-submit {
  display: none;
}

.chat-composer-form[data-state="locked"] .chat-composer-cancel,
.chat-composer-form[data-state="cancelling"] .chat-composer-cancel {
  display: inline-block;
}
