/* -- Message component ----------------------------------------------- */
/* One row of a conversation: an avatar beside a column of header (name,
   time), the message surface (a .bubble, an attachment, anything) and a
   footer (status, actions). Start = the other side, end = you. CSS only. */

@layer components {
  .message {
    --_av: 2rem;
    --_gap: 0.5rem;
    --_foot: 1.75rem;
    display: flex;
    align-items: flex-end;
    gap: var(--_gap);
    width: 100%;
    min-width: 0;

    &[data-align="end"] {
      flex-direction: row-reverse;
    }

    /* -- Sizes: avatar column and the text scale ------------------- */
    &[data-size="sm"] {
      --_av: 1.5rem;
      --_gap: 0.375rem;
    }
    &[data-size="lg"] {
      --_av: 2.5rem;
      --_gap: 0.75rem;
    }
  }

  /* The avatar slot keeps its column even when empty (a placeholder keeps
     consecutive messages aligned) and sits level with the surface's
     bottom edge - lifted above the footer when there is one. */
  .message-avatar {
    display: flex;
    flex: none;
    justify-content: center;
    width: var(--_av);

    & > .avatar {
      width: var(--_av);
      height: var(--_av);
    }
  }
  .message:has(> .message-content > .message-footer) > .message-avatar {
    margin-block-end: calc(var(--_foot) + 0.125rem);
  }
  /* no avatar column at all: data-avatar="none" on the message */
  .message[data-avatar="none"] > .message-avatar {
    display: none;
  }

  .message-content {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.125rem;
    min-width: 0;
    max-width: min(80%, 40rem);

    /* the surface fills up to the column; the column carries the 80% cap */
    & > .bubble {
      max-width: 100%;
    }
    & > .bubble[data-variant="ghost"] {
      width: auto;
    }
  }
  .message[data-align="end"] > .message-content {
    align-items: flex-end;
  }
  /* an assistant's ghost reply runs the full width */
  .message-content:has(> .bubble[data-variant="ghost"]) {
    max-width: 100%;
    flex: 1;
  }
  /* its header lines up with the unframed text */
  .message-content:has(> .bubble[data-variant="ghost"]) > :is(.message-header, .message-footer) {
    padding-inline: 0;
  }

  .message-header {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.375rem;
    padding-inline: 0.25rem;
    font-size: 0.75rem;
    line-height: 1.4;
    color: var(--muted-foreground);
  }
  .message-name {
    font-weight: 600;
    color: var(--foreground);
  }
  .message-time {
    font-variant-numeric: tabular-nums;
    color: var(--muted-foreground);
  }

  .message-footer {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    height: var(--_foot);
    padding-inline: 0.25rem;
    font-size: 0.75rem;
    color: var(--muted-foreground);
    white-space: nowrap;

    & svg {
      width: 0.875rem;
      height: 0.875rem;
      flex-shrink: 0;
    }
    & .btn svg {
      width: 1rem;
      height: 1rem;
    }
    & .btn {
      color: var(--muted-foreground);
    }
    & .btn:hover {
      color: var(--foreground);
    }
  }

  /* data-reveal="hover": the footer's actions appear on hover / focus of
     the message; always shown where there is no hover (touch) */
  @media (hover: hover) {
    .message-footer[data-reveal="hover"] {
      opacity: 0;
      transition: opacity 150ms ease;
    }
    .message:is(:hover, :focus-within) > .message-content > .message-footer[data-reveal="hover"] {
      opacity: 1;
    }
  }

  /* -- Status: delivery ticks in the footer --------------------------- */
  .message-status {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    &[data-status="read"] {
      color: oklch(0.6 0.16 250);
    }
    &[data-status="failed"] {
      color: var(--destructive);
    }
  }

  /* -- Attachment: a file card as the message surface ------------------ */
  .message-attachment {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    box-sizing: border-box;
    width: 16rem;
    max-width: 100%;
    padding: 0.625rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--card);
    color: var(--card-foreground);
    font-size: 0.8125rem;
    text-decoration: none;

    &:is(a) {
      cursor: pointer;
      transition: background-color 150ms ease;
    }
    &:is(a):hover {
      background: var(--accent);
    }
    &:is(a):focus-visible {
      outline: 2px solid var(--ring);
      outline-offset: 2px;
    }
  }
  .message-attachment-icon {
    display: grid;
    flex: none;
    place-items: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: var(--radius-md);
    background: var(--muted);
    color: var(--muted-foreground);
    & svg {
      width: 1.125rem;
      height: 1.125rem;
    }
  }
  .message-attachment-body {
    display: flex;
    flex: 1;
    flex-direction: column;
    min-width: 0;
    line-height: 1.3;
  }
  .message-attachment-name {
    overflow: hidden;
    font-weight: 500;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .message-attachment-meta {
    font-size: 0.75rem;
    color: var(--muted-foreground);
  }

  /* -- Group: consecutive messages of one sender ---------------------- */
  .message-group {
    display: flex;
    flex-direction: column;
    gap: 0.1875rem;

    /* one avatar per group: only the last message shows it (the others
       keep the empty column, so everything lines up) */
    & > .message:not(:last-child) > .message-avatar > * {
      visibility: hidden;
    }
    /* one header per group: the first message's */
    & > .message:not(:first-child) > .message-content > .message-header {
      display: none;
    }
    /* the joined bubble corners tighten, as in a .bubble-group */
    & > .message:not([data-align="end"]) {
      &:not(:last-child) > .message-content > .bubble > .bubble-content {
        border-end-start-radius: var(--_rs);
      }
      &:not(:first-child) > .message-content > .bubble > .bubble-content {
        border-start-start-radius: var(--_rs);
      }
    }
    & > .message[data-align="end"] {
      &:not(:last-child) > .message-content > .bubble > .bubble-content {
        border-end-end-radius: var(--_rs);
      }
      &:not(:first-child) > .message-content > .bubble > .bubble-content {
        border-start-end-radius: var(--_rs);
      }
    }
  }

  /* -- A conversation: rows of messages, groups and markers ------------- */
  .message-list {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    min-width: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  @layer components {
    .message-footer[data-reveal="hover"],
    .message-attachment {
      transition: none;
    }
  }
}

@media (prefers-contrast: more) {
  @layer components {
    .message-header,
    .message-footer,
    .message-time,
    .message-attachment-meta {
      color: var(--foreground);
    }
  }
}

@media (forced-colors: active) {
  @layer components {
    .message-attachment {
      border-color: CanvasText;
    }
    .message-status[data-status] {
      color: CanvasText;
    }
  }
}
