/* One conversation: who it is with, what has been said, and the box to answer in.
 *
 * The thread scrolls and the header and composer do not, so a long conversation
 * never pushes the reply box off the screen — which is the same reason a dialog's
 * footer sits outside its body.
 *
 * No border and no corner of its own: this is a pane of the inbox rather than a
 * card standing on it, and the edges it needs are the ones between the panes.
 * The gallery wraps it in .panel--flush to show it as a card, which is what a
 * panel is for — a component that owned its own elevation could not be made
 * flush, and a screen is the shape the product actually uses. */
.conversation {
  display: flex;
  flex-direction: column;
  min-block-size: 0;
  background: var(--color-canvas);
}

/* --pane-header-height rather than whatever a name and a stay measure, so this
 * rules off at the same line as the header of the list beside it. */
.conversation__header {
  display: flex;
  align-items: center;
  gap: var(--space-half);
  min-block-size: var(--pane-header-height);
  padding: var(--space) var(--pane-gutter);
  border-block-end: var(--border);
}

.conversation__identity { flex: 1; min-inline-size: 0; }

.conversation__who {
  margin: 0;
  font-size: var(--text-medium);
}

.conversation__stay {
  margin: 0;
  font-size: var(--text-small);
  color: var(--color-ink-soft);
}

/* Tight, because the gap here is the gap *within* a turn — one person saying two
 * things is two bubbles that belong together. The air between turns comes from
 * the byline that opens each one. */
.conversation__messages {
  display: flex;
  flex-direction: column;
  gap: var(--space-quarter);
  flex: 1;
  min-block-size: 0;
  overflow-y: auto;
  margin: 0;
  padding: var(--space) var(--pane-gutter);
  list-style: none;
}

/* A message is a bubble on the side its author sits on. `--host` is ours going
 * out, `--guest` is theirs coming in, and `--system` is the channel writing into
 * the thread itself — a reservation confirmed or altered — which is neither
 * side's and reads as a quiet line down the middle. */
.message {
  --message-surface: var(--surface-sunk);
  --message-ink: var(--color-ink);
  /* Long enough to read a paragraph without the eye losing the line, short
   * enough that a one-word answer is still obviously one side of an exchange. */
  --message-max-width: min(80%, 32rem);
  /* One radius at every height, and deliberately not a pill.
     A pill is clamped to half the box, so a two-line bubble gets a radius half
     its height and the text inside it runs at the curve on both ends — and no
     amount of padding fixes that, because the curve grows with the box. There is
     no selector for "more than one line" either: :only-child counts children, not
     lines. So it is a plain radius, and a modest one: a bubble is a box of text
     first, and the sides have to stay straight enough to set a line against. */
  --message-radius: var(--radius);

  display: flex;
  flex-direction: column;
  gap: var(--space-eighth);
  align-items: start;
  max-inline-size: var(--message-max-width);
}

/* Who said it and when, over the first message of a turn — see
 * Message#opens_turn_after? for what a turn is. This is also all the spacing
 * between turns there is: a byline arrives with air over it, and messages inside
 * a turn have none.
 *
 * :has rather than a modifier class, so the spacing follows the byline being
 * there rather than being a second thing to keep in agreement with it. */
.message:has(.message__byline) { margin-block-start: var(--space-and-quarter); }

.message:first-child { margin-block-start: 0; }

.message__byline {
  display: flex;
  align-items: center;
  gap: var(--space-quarter);
  font-size: var(--text-small);
}

.message__author { font-weight: var(--weight-semibold); }

.message__separator { color: var(--color-ink-faint); }

.message__when { color: var(--color-ink-soft); }

.message--host {
  --message-surface: var(--color-accent);
  --message-ink: var(--color-accent-ink);

  align-items: end;
  align-self: end;
}

.message--system {
  --message-surface: transparent;
  --message-ink: var(--color-ink-soft);

  align-items: center;
  align-self: center;
  max-inline-size: 100%;
  font-size: var(--text-small);
}

.message__body {
  padding: var(--space-three-quarters) var(--space-and-quarter);
  border-radius: var(--message-radius);
  background: var(--message-surface);
  color: var(--message-ink);
}

.message--system .message__body { padding-inline: 0; }

.message__text {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.message__translation {
  margin-block-start: var(--space-quarter);
  font-size: var(--text-small);
  color: var(--color-ink-soft);
}

.message__translation summary { cursor: pointer; }

.message__meta {
  display: flex;
  align-items: center;
  gap: var(--space-quarter);
  margin: 0;
  font-size: var(--text-x-small);
  color: var(--color-ink-soft);
}

/* The timestamp is the message's own address. It looks like text until you go
 * near it, because a thread of underlined times reads as a list of links rather
 * than as a conversation. */
.message__link {
  color: inherit;
  text-decoration: none;
}

.message__link:hover,
.message__link:focus-visible {
  text-decoration: underline;
}

/* Somebody followed a link to this one. It fades rather than staying lit: the
 * mark is there to answer "which one did they mean", and once that is answered a
 * permanent highlight is just a message that looks different from its neighbours
 * forever. */
.message--selected .message__body {
  --message-found-duration: calc(var(--duration-slow) * 12);

  outline: var(--border-width-heavy) solid var(--color-accent);
  outline-offset: var(--space-eighth);
  /* Off the duration scale, so `/designs`' slow-motion switch stretches it like
   * every other transition — a highlight that cannot be slowed down is the one
   * thing on the page nobody can inspect. */
  animation: message-found var(--message-found-duration) ease-out forwards;
}

@keyframes message-found {
  0%, 60% { outline-color: var(--color-accent); }
  100% { outline-color: transparent; }
}

@media (prefers-reduced-motion: reduce) {
  /* Settled rather than removed: the message is still the one that was linked
   * to, and it should still say so. */
  .message--selected .message__body { animation: none; }
}

.conversation__composer {
  padding: var(--space) var(--pane-gutter);
  border-block-start: var(--border);
}

/* The box is what reads as the input: the border, the radius and the focus ring
 * are here and the textarea inside is bare, which is the same arrangement as
 * .combobox__field and .input-group — see the focus-within list in forms.css.
 * Before this the textarea was a raw one, so it drew the browser's border, the
 * browser's resize handle and the browser's monospaced face, none of which
 * appear anywhere else in the app.
 *
 * Send sits inside the box, so writing a reply and sending it are one control
 * rather than a field with something parked beside it. */
.conversation__field {
  display: flex;
  align-items: end;
  gap: var(--space-half);
  padding: var(--space-quarter);
  padding-inline-start: var(--space);
  border: var(--border);
  border-radius: var(--radius-pill);
  background: var(--color-canvas);
}

.conversation__input {
  /* Where it stops growing and starts scrolling. A composer that grows without
     limit pushes the thread it is answering off the top of the screen, which is
     the one thing somebody writing a reply is reading. */
  --conversation-input-max-height: 8rem;

  flex: 1;
  min-inline-size: 0;
  /* Centred against the button rather than sitting on its baseline, so a
     one-line reply is one row; once it has grown past the button, the button
     stays at the bottom of the box. */
  align-self: center;
  max-block-size: var(--conversation-input-max-height);
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  line-height: var(--leading-normal);
  resize: none;
  field-sizing: content;
}

/* Why a reply did not go, above what was typed, inside the frame it was typed in. */
.conversation__refusal { margin-block: 0 var(--space-half); }

/* What we know about the guest, beside the conversation rather than inside it —
 * it answers "who is this" while the thread answers "what did they say".
 *
 * A header and a scrolling body, like the two panes to its left, so all three of
 * them rule off at the same line — see --pane-header-height. Only the body
 * scrolls, so who the guest is stays on screen while what we know about them is
 * read past. */
.conversation-about {
  display: flex;
  flex-direction: column;
  min-block-size: 0;
  border-inline-start: var(--border);
}

.conversation-about__identity {
  display: flex;
  align-items: center;
  gap: var(--space-half);
  min-block-size: var(--pane-header-height);
  padding: var(--space) var(--pane-gutter);
  border-block-end: var(--border);
}

.conversation-about__names { min-inline-size: 0; }

.conversation-about__who {
  margin: 0;
  font-size: var(--text-medium);
}

/* An address, and a relay alias is a long one in a narrow column. It wraps rather
   than truncating: an address with an ellipsis in the middle of it is one nobody
   can read out loud or check against a portal, which is the whole use for it. */
.conversation-about__contact {
  display: block;
  margin: 0;
  overflow-wrap: anywhere;
  font-size: var(--text-small);
  color: var(--color-ink-soft);
}

.conversation-about__body {
  flex: 1;
  min-block-size: 0;
  overflow-y: auto;
}

/* Ruled off from each other rather than stacked as cards. The pane is already a
   surface, so a panel in here is a box inside a box — which is what this was, and
   what made a column with four facts in it read as clutter. */
.conversation-about__section {
  display: flex;
  flex-direction: column;
  gap: var(--space-half);
  padding: var(--space) var(--pane-gutter);

  & + & {
    border-block-start: var(--border);
  }
}

/* The heading, and what qualifies the whole section at the far end of it — the
   state of the stay, which is not another row of the list under it. */
.conversation-about__section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-half);
}

.conversation-about__property {
  margin: 0;
  font-weight: var(--weight-semibold);
}

.conversation-about__heading {
  margin: 0;
  font-size: var(--text-small);
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--color-ink-soft);
}

.conversation-about__note {
  margin: 0;
  font-size: var(--text-small);
  color: var(--color-ink-soft);
}
