
.root {
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Side pads ride the shared clearance (figma Input_Bottom drew L32/R32/B8;
     the sides narrow with the shared width axis); the bottom gradient mask
     is owned by the chat scroller. No top pad: the composer stack's gap owns
     the space above; the status strip still carries its own margin. */
  padding: 0 var(--dsh-composer-side-clearance) 8px;
}

.hero {
  /* No bottom pad in the centered hero, but the side clearance must survive:
     the hero wrapper is full-width on narrow viewports, so this padding is
     the only thing keeping the card off the edges there. */
  padding: 0 var(--dsh-composer-side-clearance);
}

.notice {
  width: 100%;
  max-width: var(--dsh-composer-card-max-width);
  margin-bottom: 6px;
  padding: 4px 8px;
  border-radius: 8px;
  background: var(--dsw-alias-interactive-bg-hover);
  color: var(--dsw-alias-label-secondary);
  font-size: 12px;
  line-height: 18px;
}

.card {
  box-sizing: border-box;
  position: relative; /* overlay anchor positioning context */
  display: flex;
  flex-direction: column;
  /* figma Input 75:8208: 12px between the text area and the button row; 10px
     top pad on the card before .InputText. */
  gap: 12px;
  width: 100%;
  max-width: var(--dsh-composer-card-max-width);
  padding-top: 10px;
  /* Input stroke: black/0.10 light, white/0.06 dark (figma darkmode note says
     the input border is one notch weaker than buttons) — exactly the
     l2-darkmode-thin pair. Fill: the input surface token (elevated in dark). */
  border: 1px solid var(--dsw-alias-border-l2-darkmode-thin);
  border-radius: 22px;
  background: var(--dsw-specific-input-major);
  box-shadow: var(--dsw-shadow-lv2);
  /* The draft text follows the Settings font-size preference (the textarea,
     mirror, and backdrop all inherit from here, so the three layers stay in
     step); the line height keeps the default 10px leading via the shared px
     delta. */
  font-size: var(--dsh-content-font-size, 14px);
  line-height: calc(24px + var(--dsh-content-font-delta, 0px));
  /* Elevated surface in dark, same as the menus: the draft scrollport inside
     scrolls once the composer hits its height cap, so the thumb takes the l2
     pair. Declared on the card because the elevation belongs to the surface,
     and the custom properties inherit down to the box that actually scrolls
     (see ui-theme styles/scrollbar.css for the rebinding contract). */
  --dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2);
  --dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2);
}

/* No-workspace trigger state: dashed l4 stroke marks the card as a pick-a-
   workspace affordance rather than a live composer; hover answers in the
   business blue to invite the click. Native `dashed` has a fixed browser
   pattern, so the stroke is an ::after overlay: theme-token background masked
   by an SVG dash ring (stroke-width 2 centered on the box edge = 1px visible
   inside), which keeps the 22px radius and both themes. */
.cardWorkspaceTrigger {
  border-color: transparent;
  cursor: pointer;
}

.cardWorkspaceTrigger::after {
  content: '';
  position: absolute;
  inset: -1px;
  border-radius: 22px;
  background: var(--dsw-alias-border-l4);
  transition: background-color 100ms ease;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Crect width='100%25' height='100%25' fill='none' rx='22' ry='22' stroke='black' stroke-width='2' stroke-dasharray='4 4'/%3E%3C/svg%3E");
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Crect width='100%25' height='100%25' fill='none' rx='22' ry='22' stroke='black' stroke-width='2' stroke-dasharray='4 4'/%3E%3C/svg%3E");
  pointer-events: none;
}

/* Disabled toolbar controls neither receive nor swallow clicks in the trigger
   state: pointer events fall through to the card's own click handler, making
   the full capsule one pick target. */
.cardWorkspaceTrigger :disabled {
  pointer-events: none;
}

.cardWorkspaceTrigger:hover::after {
  background: var(--dsw-alias-state-business-primary);
}

.accessory {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px 0;
}

/* Floating overlay anchor (menu / popupSelect shell): entries position
   themselves against the card (bottom: 100% + gap); closed entries render null. */
.overlayAnchor {
  position: absolute;
  inset: 0 0 auto;
  height: 0;
}

/* The draft's scrollport, and the ONLY scrolling box in the composer. The
   contenteditable grows with its content inside; the 14-line cap lives here
   because this is the box the cap describes. */
.scroll {
  max-height: var(--dsh-composer-text-max-height);
  overflow-y: auto;
}

/* Auto-grow anchor: the contenteditable is in normal flow and sets the
   draft's height; the placeholder rides it absolutely. */
.grow {
  position: relative;
}

/* Machine pending dot (adjudicating / submitting). */
.pending {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--dsw-alias-state-business-primary);
  animation: input-pending 1s ease-in-out infinite alternate;
}

@keyframes input-pending {
  from { opacity: 0.35; }
  to { opacity: 1; }
}

/* The contenteditable draft surface (grows with its content; .scroll caps
   and scrolls it). figma .InputText 34:10434: pl 16 / pr 12 / pt 4. */
.input {
  box-sizing: border-box;
  padding: 4px 12px 0 16px;
  font-family: var(--dsw-font-family);
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
  word-break: break-word;
  overflow-wrap: anywhere;
  outline: none;
  color: var(--dsw-alias-label-primary);
  /* Business blue, not brand-primary: that token resolves to ink in this sheet. */
  caret-color: var(--dsw-alias-state-business-primary);
}

/* Lexical paragraphs are <p> blocks: strip the UA margins so the surface
   keeps the textarea's line rhythm. */
.input p {
  margin: 0;
}

/* Claim ghost hint as generated content after the last paragraph: the bar
   sets --dsh-composer-hint (a quoted string) while the claim's args are
   blank; without the variable the declaration is invalid and nothing shows. */
.input p:last-child::after {
  content: var(--dsh-composer-hint);
  color: var(--dsw-alias-label-caption);
}

/* figma 34:10434: #ADB2B8 light / #81858C dark — the caption pair exactly. */
.placeholder {
  position: absolute;
  inset: 4px 12px auto 16px;
  color: var(--dsw-alias-label-caption);
  pointer-events: none;
  user-select: none;
}

.inputDisabled {
  color: var(--dsw-alias-label-tertiary);
  cursor: not-allowed;
}

.input[aria-haspopup='menu'] {
  cursor: pointer;
}

/* Hero (centered empty-state) keeps the 2-line floor (figma min-h 52 = ~2 × 24
   line + 4pt); the docked composer collapses to the content height. */
.hero .input {
  min-height: 52px;
}

/* Toolbar: attach + Plan + Read-only on the left; model + send on the right
   (figma Input_Bottom chrome). */
.row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  /* 2px moved from the bottom pad to the top: the whole control row sits 2px
     lower in the card (it read too high against the textarea) while the card
     height and the controls' own centering stay untouched. */
  padding: 2px 8px 6px;
  min-width: 0;
  /* Size container so the chips inside can collapse to icon-only when the
     card runs out of row width (PermissionSelect @container rule). Anonymous
     on purpose: CSS modules hash container-name per module, so a name declared
     here can never match a query in another module's sheet. */
  container-type: inline-size;
}

.tools,
.modes,
.trailing {
  display: flex;
  align-items: center;
  min-width: 0;
}

/* figma 75:8208 drew 16 between + and the mode chips and 4 between Plan /
   Read-only; the chip gap widened to 12 so the pill chips read as separate
   controls. */
.tools {
  gap: 16px;
}

.modes {
  gap: 12px;
}

.trailing {
  flex: none;
  /* Wrap keeps the left mode chips and the right controls apart when the card
     runs out of row width: the trailing group (model + send) moves to its own
     line instead of the left group shrinking until its chip overlaps the
     model trigger (external:107). The auto margin re-anchors it right on the
     wrapped line; on a single line space-between already pins it right. */
  margin-left: auto;
  gap: 12px;
}

/* Attach circle (figma + control): 28px, selector fill, primary glyph. */
.add {
  display: grid;
  place-items: center;
  flex: none;
  width: 28px;
  height: 28px;
  border: none;
  border-radius: 999px;
  background: var(--dsw-specific-selector);
  color: var(--dsw-alias-label-primary);
  cursor: pointer;
}

.add:hover:not(:disabled) {
  background: var(--dsw-alias-interactive-bg-hover-solid);
}

.add:disabled {
  opacity: 0.5;
  cursor: default;
}

/* Plan / Read-only / model — native <select>, chip-like closed chrome
   (figma ToggleButton: 13/20 medium secondary, 12px chevron). */
.select {
  max-width: 220px;
  height: 28px;
  padding: 0 20px 0 8px;
  border: none;
  border-radius: 8px;
  outline: none;
  background-color: transparent;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 4px center;
  background-size: 12px 12px;
  color: var(--dsw-alias-label-secondary);
  font-size: 13px;
  line-height: 20px;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  appearance: none;
}

.select:hover:not(:disabled) {
  background-color: var(--dsw-alias-interactive-bg-hover);
}

.select:disabled {
  opacity: 0.5;
  cursor: default;
}

/* Primary send (figma IconButton 34:10465): 34px circle, #3964FE light /
   #679EFE dark — the info-fill pair (500→400), NOT button-primary (ink);
   white glyph; empty text = 0.4 opacity. */
.primary {
  display: grid;
  place-items: center;
  flex: none;
  width: 34px;
  height: 34px;
  border: none;
  border-radius: 999px;
  background: var(--dsw-alias-button-info-fill);
  /* Static white, not the foreground token: the arrow stays white on the blue
     fill in both themes (design 34:10465). */
  color: #fff;
  cursor: pointer;
  transition: background-color 100ms ease;
  /* Opts out of the row's 2px downward shift (.row top pad): the send circle
     keeps its original seat while the smaller chips sit lower. Transform, not
     margin, so flex centering math is untouched. */
  transform: translateY(-2px);
}

.primary:hover:not(:disabled) {
  background: var(--dsw-alias-button-info-hover);
}

.primary:disabled {
  opacity: 0.4;
  cursor: default;
}

.retry {
  margin-left: 8px;
  padding: 1px 8px;
  border: 1px solid currentColor;
  border-radius: 4px;
  background: transparent;
  color: inherit;
  font-size: 12px;
  cursor: pointer;
}
