/*
 * THE COMMAND SURFACE, in two shapes on one anatomy. `data-expanded` is the
 * whole switch: absent, the composer is the compact PILL whose geometry
 * an `AgentRun variant="pill"` morphs into; present, it is the full box with its slots above
 * the field and its buttons in a footer.
 *
 * The FOCUSED EDGE is `:has(… __textarea:focus-within)` rather than a
 * `:focus-within` on the shell, and the distinction is the point: the edge says
 * TYPING GOES HERE, so it must not light up when the send button takes focus —
 * that button wears its own ring, and two focus treatments on one box is the
 * shape §2.3 forbids. On a leaf element `:focus-within` is `:focus`, which is
 * what the rule against a bare `:focus` is really about.
 *
 * The MIRROR only lays out; the field paints on top of it. It is absolutely
 * positioned, and a positioned box paints over static in-flow content whatever
 * the source order — so without the field winning the stack the tint is an
 * opaque ground drawn ON TOP of the words. Geometry and font metrics can all
 * agree while that is wrong, which is why the layer is stated here and asserted
 * off this sheet.
 */
@layer theme, base, lotics, components, utilities;
@layer lotics.tokens, lotics.reset, lotics.components;

@layer lotics.components {
  .lotics-composer {
    /* The pill's height, and the fixed single-row field inside it — a tall
       click target that keeps the pill at its own height, where a flex/auto
       height would let the multiline field balloon to its two-row intrinsic
       size. Sizes the component owns, so they are written once. */
    --lotics-composer-pill-height: 52px;
    --lotics-composer-compact-field-height: 44px;
    /* The field's own text inset, and the mirror's — one number, because the
       tint drifts the moment they disagree. */
    --lotics-composer-text-inset: var(--lotics-space-10);

    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: center;
    min-width: 0;
    min-height: var(--lotics-composer-pill-height);
    padding-inline: var(--lotics-space-6);
    border-width: 1.5px;
    border-style: solid;
    border-color: var(--border);
    border-radius: var(--lotics-radius-full);
    background-color: var(--card);
    transition: border-color var(--lotics-duration-fast) var(--lotics-ease-standard);
  }

  /* THE FULL BOX. Square-ish corner, a heavier edge, and the gaps that separate
     the stacked slots from the field and the footer. */
  .lotics-composer[data-expanded] {
    gap: var(--lotics-space-8);
    min-height: auto;
    padding: var(--lotics-space-8);
    border-width: 2px;
    border-radius: var(--lotics-radius-card);
  }

  .lotics-composer:has(.lotics-composer__textarea:focus-within) {
    border-color: var(--ring);
  }

  .lotics-composer__pills {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--lotics-space-4);
    min-width: 0;
  }

  /* The attachment region scrolls sideways rather than wrapping: a second row of
     thumbnails pushes the field off a phone screen. */
  .lotics-composer__files {
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    gap: var(--lotics-space-8);
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
  }

  .lotics-composer__extra {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    min-width: 0;
  }

  /* THE COMPACT ROW: the actions button, the field, the send button. */
  .lotics-composer__input {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--lotics-space-6);
    min-width: 0;
  }

  .lotics-composer[data-expanded] .lotics-composer__input {
    flex-direction: column;
    align-items: stretch;
    justify-content: center;
    padding: var(--lotics-space-4);
  }

  .lotics-composer__lead,
  .lotics-composer__trail {
    display: flex;
    flex-direction: row;
    align-items: center;
    flex-shrink: 0;
  }

  .lotics-composer__field {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    position: relative;
    flex: 1;
    min-width: 0;
    height: var(--lotics-composer-compact-field-height);
  }

  /* The measured content height, floored at ONE line: the measurement arrives
     from a ref callback, so the first render has none and a bare `var()` would
     open the field at zero. */
  .lotics-composer[data-expanded] .lotics-composer__field {
    flex: none;
    height: max(var(--lotics-input-leading), var(--lotics-composer-field-height));
  }

  .lotics-composer__textarea {
    display: block;
    flex: 1;
    width: 100%;
    min-width: 0;
    margin: 0;
    /* ABOVE the mirror — see the head of this file. The rung is the published
       one for in-flow content lifted over a positioned sibling; a local variable
       holding a literal 1 is that ladder restated where nothing can see it. */
    position: relative;
    z-index: var(--lotics-z-row-content);
    padding-inline: var(--lotics-composer-text-inset);
    /* The line sits in the middle of the taller click target. */
    padding-block: calc(
      (var(--lotics-composer-compact-field-height) - var(--lotics-input-leading)) / 2
    );
    border: 0 solid transparent;
    border-radius: 0;
    background-color: transparent;
    color: var(--lotics-ink-default);
    font-family: var(--font-sans);
    font-size: var(--lotics-input-text);
    line-height: var(--lotics-input-leading);
    letter-spacing: var(--lotics-input-tracking);
    font-weight: var(--lotics-weight-regular);
    font-feature-settings: var(--lotics-font-features);
    appearance: none;
    /* The SHELL paints the edge, so the field inside it must not draw a second. */
    outline-style: none;
    /* A drag handle would fight the auto-grow height the component computes. */
    resize: none;
    overflow: hidden;
    cursor: text;
  }

  /* Expanded, the field IS the box: the row around it already spent the inset,
     and the height is the measured content height with no padding in it. */
  .lotics-composer[data-expanded] .lotics-composer__textarea {
    padding: 0;
  }

  /* Past `maxLines` the box stops growing and the text scrolls inside it. */
  .lotics-composer__textarea[data-scroll] {
    overflow-y: auto;
  }

  .lotics-composer__overlay {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    position: absolute;
    inset: 0;
    overflow: hidden;
    padding-inline: var(--lotics-composer-text-inset);
    padding-block: calc(
      (var(--lotics-composer-compact-field-height) - var(--lotics-input-leading)) / 2
    );
    pointer-events: none;
  }

  .lotics-composer[data-expanded] .lotics-composer__overlay {
    padding: 0;
  }

  /* The mirror takes the field's own type rung and nothing else — a tracking of
     its own drifts the tint a fraction of a pixel per character, invisible on a
     short line and off the words by the end of a long one. */
  .lotics-composer__mirror {
    display: block;
    color: transparent;
    white-space: pre-wrap;
    overflow-wrap: break-word;
    font-family: var(--font-sans);
    font-size: var(--lotics-input-text);
    line-height: var(--lotics-input-leading);
    letter-spacing: var(--lotics-input-tracking);
    font-weight: var(--lotics-weight-regular);
    font-feature-settings: var(--lotics-font-features);
    transform: translateY(var(--lotics-composer-mirror-offset));
  }

  /* A GROUND, not coloured text: the words on screen are the field's, drawn on
     top, so the tint has to sit behind them rather than replace them. */
  .lotics-composer__highlight {
    /* Half the control corner — this is a tint behind words, not a box you
       press, so it takes a softer rung than any control on the surface. */
    border-radius: calc(var(--lotics-radius-control) - var(--lotics-space-4));
    background-color: var(--lotics-tone-blue-strong);
  }

  .lotics-composer__placeholder {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: center;
    position: absolute;
    inset: 0;
    padding-inline: var(--lotics-composer-text-inset);
    pointer-events: none;
  }

  /* The hint is DRAWN rather than set on the field, so its ink is painted here
     rather than picked from `Text`'s `color` — that vocabulary is the roles
     prose chooses between, and a prompt is field chrome. Anchored on the root,
     because a bare part class TIES with `.lotics-text`'s own `color` at one
     class each and the ink would then resolve on whichever sheet a bundler
     emitted last — the arithmetic `metric.css` spells out. */
  .lotics-composer .lotics-composer__placeholder-text {
    color: var(--lotics-ink-placeholder);
  }

  .lotics-composer[data-expanded] .lotics-composer__placeholder {
    justify-content: flex-start;
    padding-inline: 0;
    padding-block-start: var(--lotics-space-2);
  }

  .lotics-composer__footer {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: var(--lotics-space-8);
    min-width: 0;
    /* ABOVE the mirror, which is positioned and would otherwise paint over it. */
    z-index: var(--lotics-z-row-content);
  }

  .lotics-composer__footer-left,
  .lotics-composer__footer-right {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--lotics-space-8);
  }
}
