/*
Message

One chat message. data-variant (bubble | flat) and data-align (start |
end) are resolved from the sender, so a user message is a bubble at the
end and an assistant message flat text at the start. Grouped follow-ups
keep the avatar column (empty) so their content lines up.

  article.message[data-from][data-variant][data-align][data-grouped]
    .message-avatar          avatar column
    .message-main
      .message-header        .message-author, .message-time
      .message-content       the bubble
        .message-response    rendered markdown (.message-code blocks)
      .message-toolbar > .message-actions, .message-branch-selector
  .message-branch[data-branch][data-branches] > .message-branch-content
  .message-loading           three dots
*/

@layer components {

.message {
  --message-avatar: var(--control-height-sm);

  display:     flex;
  align-items: flex-start;
  gap:         var(--space-3);
  width:       100%;
  min-width:   0;
  color:       var(--ink);
  font-family: var(--font-body);
  font-size:   var(--text-ui);
  line-height: var(--leading-body);
}

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

.message-avatar {
  flex:  none;
  width: var(--message-avatar);
}

.message[data-grouped] .message-avatar {
  visibility: hidden;
}

.message-main {
  display:        flex;
  flex:           1 1 auto;
  flex-direction: column;
  align-items:    flex-start;
  gap:            var(--space-2);
  min-width:      0;
  max-width:      100%;
}

.message[data-align="end"] .message-main {
  align-items: flex-end;
}

/* A bubble message leaves room on the far side, so a short reply does not
   span the whole column. */
.message[data-variant="bubble"] .message-main {
  max-width: 85%;
}

.message-header {
  display:     flex;
  align-items: baseline;
  gap:         var(--space-2);
  min-width:   0;
  font-family: var(--font-ui);
  font-size:   var(--text-caption);
  line-height: var(--leading-snug);
}

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

.message-author {
  overflow:      hidden;
  color:         var(--ink);
  font-weight:   var(--weight-strong);
  white-space:   nowrap;
  text-overflow: ellipsis;
}

.message-time {
  flex:        none;
  color:       var(--ink-dim);
  font-variant-numeric: tabular-nums;
}

/* Content */

.message-content {
  display:        flex;
  flex-direction: column;
  gap:            var(--space-2);
  width:          fit-content;
  min-width:      0;
  max-width:      100%;
  overflow-wrap:  anywhere;
}

.message[data-variant="flat"] .message-content {
  width: 100%;
}

.message[data-variant="bubble"] .message-content {
  padding:       var(--space-2-5) var(--space-4);
  border-radius: var(--radius-surface);
  background:    var(--secondary);
  color:         var(--secondary-ink);
}

.message[data-from="system"] {
  justify-content: center;
}

.message[data-from="system"] .message-main {
  align-items: center;
}

.message[data-from="system"] .message-content {
  color:      var(--ink-dim);
  font-size:  var(--text-caption);
  text-align: center;
}

/* Response (markdown) */

.message-response {
  min-width: 0;
  max-width: 100%;
}

.message-response > :first-child { margin-top: 0; }
.message-response > :last-child  { margin-bottom: 0; }

.message-response :is(p, ul, ol, blockquote, pre, .md-table, .message-code, hr) {
  margin: 0 0 var(--space-3);
}

.message-response :is(h1, h2, h3, h4, h5, h6) {
  margin:      var(--space-4) 0 var(--space-2);
  font-family: var(--font-heading);
  font-weight: var(--weight-heading);
  line-height: var(--leading-heading);
}

.message-response h1 { font-size: var(--text-xl); }
.message-response h2 { font-size: var(--text-lg); }
.message-response h3 { font-size: var(--text-md); }
.message-response :is(h4, h5, h6) { font-size: var(--text-ui); }

.message-response :is(ul, ol) {
  padding-inline-start: var(--space-5);
}

.message-response li + li {
  margin-top: var(--space-1);
}

.message-response li > :is(ul, ol) {
  margin: var(--space-1) 0 0;
}

.message-response li.md-task {
  list-style: none;
  margin-inline-start: calc(-1 * var(--space-5));
}

.message-response li.md-task > input {
  margin: 0 var(--space-1) 0 0;
  vertical-align: middle;
}

.message-response a {
  color:                 var(--link);
  text-decoration:       underline;
  text-underline-offset: var(--link-underline-offset);
}

.message-response :not(pre) > code {
  padding:       0 var(--space-1);
  border-radius: var(--radius-tag);
  background:    var(--bg-muted);
  font-family:   var(--font-mono);
  font-size:     var(--text-ui-sm);
}

.message[data-variant="bubble"] .message-response :not(pre) > code {
  background: color-mix(in oklab, var(--ink) 8%, transparent);
}

.message-response blockquote {
  padding-inline-start: var(--space-3);
  border-inline-start:  var(--space-0-5) solid var(--rule-strong);
  color:                var(--ink-soft);
}

.message-response hr {
  border:     0;
  border-top: var(--surface-border-width) solid var(--rule);
}

.message-response img {
  max-width:     100%;
  height:        auto;
  border-radius: var(--radius-control);
}

.message-response .md-blocked {
  color: var(--ink-dim);
}

/* GFM footnotes: superscript references, a ruled list at the end. */
.message-response sup {
  line-height: 0;
}

.message-response [data-footnote-ref] {
  text-decoration: none;
}

.message-response .md-footnotes {
  padding-top: var(--space-2);
  border-top:  var(--surface-border-width) solid var(--rule);
  color:       var(--ink-soft);
  font-size:   var(--text-caption);
}

.message-response .md-footnotes ol {
  margin: 0;
}

.message-response .md-footnotes p {
  margin: 0 0 var(--space-1);
}

.message-response .md-footnote-back {
  text-decoration: none;
}

.message-response-root {
  display: contents;
}

.message-response .md-table {
  max-width:     100%;
  overflow:      hidden;
  border:        var(--surface-border-width) solid var(--surface-border);
  border-radius: var(--radius-surface);
}

.message-response .md-table-bar {
  justify-content: flex-end;
  padding:         var(--space-0-5) var(--space-1);
  border-bottom:   var(--surface-border-width) solid var(--rule);
  background:      var(--bg-soft);
}

.message-response .md-table-scroll {
  max-width:  100%;
  max-height: var(--message-table-max-height, none);
  overflow:   auto;
}

/* Controls: code copy and download, table menus, image download. */
.message-response .md-controls {
  display:     flex;
  align-items: center;
  gap:         var(--space-0-5);
}

.message-response .md-menu {
  inset:         auto;
  margin:        0;
  min-width:     calc(var(--control-height-sm) * 4);
  padding:       var(--overlay-padding);
  border:        var(--overlay-border-width) solid var(--overlay-border);
  border-radius: var(--radius-overlay);
  background:    var(--overlay-bg);
  color:         var(--overlay-ink);
  box-shadow:    var(--overlay-shadow);
}

.message-response .md-menu:popover-open {
  display:        flex;
  flex-direction: column;
}

.message-response .md-menu-item {
  display:       flex;
  align-items:   center;
  min-height:    var(--item-height);
  padding:       0 var(--item-padding-x);
  border:        0;
  border-radius: var(--radius-item);
  background:    transparent;
  color:         inherit;
  font:          inherit;
  font-family:   var(--font-ui);
  font-size:     var(--text-ui);
  text-align:    start;
  cursor:        pointer;
}

.message-response .md-menu-item:is(:hover, :focus-visible) {
  outline:    none;
  background: var(--item-highlight);
  color:      var(--item-highlight-ink);
}

.message-response .md-image {
  position: relative;
  display:  inline-block;
  max-width: 100%;
}

.message-response .md-image > .md-control {
  position:   absolute;
  inset-block-start: var(--space-1);
  inset-inline-end:  var(--space-1);
  background: var(--overlay-bg);
  box-shadow: var(--overlay-shadow);
  opacity:    0;
  transition: opacity var(--duration-fast) var(--ease-out);
}

.message-response .md-image:is(:hover, :focus-within) > .md-control {
  opacity: 1;
}

/* A touch screen has no hover to reveal it, so it always shows there. */
@media (hover: none) {
  .message-response .md-image > .md-control {
    opacity: 1;
  }
}

.message-response table {
  width:           100%;
  border-collapse: collapse;
  font-size:       var(--text-ui);
}

.message-response :is(th, td) {
  padding:       var(--space-1-5) var(--space-3);
  border-bottom: var(--surface-border-width) solid var(--rule);
  text-align:    start;
}

.message-response tr:last-child td {
  border-bottom: 0;
}

.message-response th {
  background:  var(--bg-soft);
  font-family: var(--font-ui);
  font-weight: var(--weight-strong);
}

/* Code blocks: a header with the language and a copy button, then the code,
   which scrolls inside the block, never the page. */
.message-code {
  max-width:     100%;
  overflow:      hidden;
  border:        var(--surface-border-width) solid var(--surface-border);
  border-radius: var(--radius-surface);
  background:    var(--message-code-background, var(--bg-soft));
}

.message-code-head {
  display:         flex;
  align-items:     center;
  justify-content: space-between;
  gap:             var(--space-2);
  padding:         var(--space-1) var(--space-1) var(--space-1) var(--space-3);
  border-bottom:   var(--surface-border-width) solid var(--rule);
  color:           var(--ink-dim);
  font-family:     var(--font-ui);
  font-size:       var(--text-caption);
}

.md-control,
.message-code-copy {
  display:         inline-flex;
  align-items:     center;
  justify-content: center;
  width:           var(--control-height-sm);
  height:          var(--control-height-sm);
  padding:         0;
  border:          0;
  border-radius:   var(--radius-control);
  background:      transparent;
  color:           var(--ink-soft);
  cursor:          pointer;
}

.md-control:disabled {
  opacity: var(--opacity-disabled);
  cursor:  default;
}

.md-control:not(:disabled):hover,
.message-code-copy:not(:disabled):hover {
  background: var(--bg-muted);
  color:      var(--ink);
}

.md-control:focus-visible,
.message-code-copy:focus-visible {
  outline:    none;
  box-shadow: var(--focus-ring);
}

/* The table bar and a scrolling code block or table sit flush with a
   clipping edge, so their ring is drawn inside. */
.message-response .md-table-bar .md-control:focus-visible,
.message-response :is(.message-code pre, .md-table-scroll):focus-visible {
  outline:    none;
  box-shadow: inset 0 0 0 var(--focus-ring-width) var(--focus);
}

.md-control svg,
.message-code-copy svg {
  width:  var(--icon-size-sm);
  height: var(--icon-size-sm);
}

/* Both icons share one cell; only the current one shows. */
.message-code-swap {
  display: inline-grid;
}

.message-code-swap > span {
  display:     inline-flex;
  grid-area:   1 / 1;
}

.message-code-swap[data-state="off"] > .message-code-swap-on,
.message-code-swap[data-state="on"] > .message-code-swap-off {
  visibility: hidden;
}

.message-code-swap[data-state="on"] {
  color: var(--success);
}

.message-code pre {
  margin:      0;
  border:      0;
  border-radius: 0;
  background:  transparent;
  color:       var(--message-code-text, var(--ink));
  box-shadow:  none;
  padding:     var(--space-3);
  overflow-x:  auto;
  font-family: var(--font-mono);
  font-size:   var(--text-ui-sm);
  line-height: var(--leading-relaxed);
  white-space: pre;
}

.message-code code {
  font-family: inherit;
}

.message-code pre {
  max-height: var(--message-code-max-height, none);
  overflow-y: auto;
}

/* lineNumbers: a gutter column beside the code, one number per line. */
.message-code pre.has-lines {
  display:               grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap:            var(--space-3);
}

.message-code-lines {
  color:       var(--ink-dim);
  text-align:  end;
  user-select: none;
}

/* A fullscreen table fills the screen; its rows scroll inside. */
.message-response .md-table:fullscreen {
  display:        flex;
  flex-direction: column;
  max-width:      none;
  border:         0;
  border-radius:  0;
  background:     var(--bg);
  color:          var(--ink);
}

.message-response .md-table:fullscreen .md-table-scroll {
  flex:       1;
  max-height: none;
  padding:    var(--space-4);
}

/* Syntax colors, the contract's --syntax-* set. A
   code theme (codeColors, or the --message-code-* properties set in CSS)
   replaces any of them. */
.message-code .tok-comment  { color: var(--message-code-comment, var(--syntax-comment)); font-style: italic; }
.message-code .tok-keyword  { color: var(--message-code-keyword, var(--syntax-keyword)); }
.message-code .tok-string   { color: var(--message-code-string, var(--syntax-string)); }
.message-code .tok-number,
.message-code .tok-variable { color: var(--message-code-number, var(--syntax-number)); }
.message-code .tok-function,
.message-code .tok-type,
.message-code .tok-tag      { color: var(--message-code-function, var(--syntax-function)); }
.message-code .tok-property,
.message-code .tok-attr     { color: var(--message-code-property, var(--syntax-property)); }

/* The link safety dialog: the full url, wrapped, never widening the panel. */
.message-link-url {
  margin:        0;
  padding:       var(--space-2) var(--space-3);
  border-radius: var(--radius-control);
  background:    var(--bg-muted);
  font-family:   var(--font-mono);
  font-size:     var(--text-ui-sm);
  overflow-wrap: anywhere;
}

.message-link-copy .message-code-swap > span,
.message-link-open {
  gap: var(--space-1-5);
}

.message-link-copy svg,
.message-link-open svg {
  width:  var(--icon-size-sm);
  height: var(--icon-size-sm);
}

.message-link-copy .message-code-swap[data-state="on"] {
  color: inherit;
}

/* Streaming: a caret after the last block. */
.message-response[data-streaming] > :last-child::after,
.message-response[data-streaming]:empty::after {
  content:        "";
  display:        inline-block;
  width:          var(--space-2);
  height:         1em;
  margin-inline-start: var(--space-0-5);
  vertical-align: text-bottom;
  background:     currentColor;
  animation:      message-caret var(--caret-blink) steps(1) infinite;
}

.message-response[data-streaming] > .message-code:last-child::after,
.message-response[data-streaming] > :is(ul, ol, table, .md-table):last-child::after {
  display: none;
}

.message-response[data-streaming][data-caret="circle"] > :last-child::after,
.message-response[data-streaming][data-caret="circle"]:empty::after {
  width:         0.6em;
  height:        0.6em;
  vertical-align: middle;
  border-radius: var(--radius-full);
}

@keyframes message-caret {
  50% { opacity: 0; }
}

/* Animated streaming (Streamdown animated): new words fade, blur or rise in.
   The slide moves a relatively positioned span, so no line reflows. */
.message-response .md-anim {
  animation: message-fade-in var(--message-animation-duration, var(--duration-enter)) var(--message-animation-easing, var(--ease-enter)) both;
}

.message-response[data-animation="blur"] .md-anim {
  animation-name: message-blur-in;
}

.message-response[data-animation="slide-up"] .md-anim {
  position:       relative;
  animation-name: message-slide-up;
}

@keyframes message-fade-in {
  from { opacity: 0; }
}

@keyframes message-blur-in {
  from { opacity: 0; filter: blur(var(--space-1)); }
}

@keyframes message-slide-up {
  from { opacity: 0; top: var(--space-1); }
}

/* Raw HTML the response allows: keyboard keys and disclosure. */
.message-response kbd {
  padding:       0 var(--space-1);
  border:        var(--surface-border-width) solid var(--rule-strong);
  border-radius: var(--radius-item);
  background:    var(--bg-soft);
  font-family:   var(--font-mono);
  font-size:     var(--text-ui-sm);
}

.message-response details {
  margin: 0 0 var(--space-3);
}

.message-response summary {
  cursor: pointer;
}

/* Actions And Toolbar */

.message-actions {
  display:     flex;
  align-items: center;
  gap:         var(--space-0-5);
}

.message-action[aria-pressed="true"] {
  background: var(--bg-muted);
  color:      var(--ink);
}

.message-toolbar {
  display:         flex;
  align-items:     center;
  justify-content: space-between;
  gap:             var(--space-4);
  width:           100%;
}

/* Branches */

.message-branch {
  display:        grid;
  gap:            var(--space-2);
  width:          100%;
  min-width:      0;
}

.message-branch-content {
  display:   grid;
  min-width: 0;
}

.message-branch-content > [hidden],
.message-branch[data-branch="0"] > .message-branch-content > :not(:nth-child(1)),
.message-branch[data-branch="1"] > .message-branch-content > :not(:nth-child(2)),
.message-branch[data-branch="2"] > .message-branch-content > :not(:nth-child(3)),
.message-branch[data-branch="3"] > .message-branch-content > :not(:nth-child(4)),
.message-branch[data-branch="4"] > .message-branch-content > :not(:nth-child(5)),
.message-branch[data-branch="5"] > .message-branch-content > :not(:nth-child(6)),
.message-branch[data-branch="6"] > .message-branch-content > :not(:nth-child(7)),
.message-branch[data-branch="7"] > .message-branch-content > :not(:nth-child(8)),
.message-branch[data-branch="8"] > .message-branch-content > :not(:nth-child(9)),
.message-branch[data-branch="9"] > .message-branch-content > :not(:nth-child(10)),
.message-branch[data-branch="10"] > .message-branch-content > :not(:nth-child(11)),
.message-branch[data-branch="11"] > .message-branch-content > :not(:nth-child(12)),
.message-branch[data-branch="12"] > .message-branch-content > :not(:nth-child(13)),
.message-branch[data-branch="13"] > .message-branch-content > :not(:nth-child(14)),
.message-branch[data-branch="14"] > .message-branch-content > :not(:nth-child(15)),
.message-branch[data-branch="15"] > .message-branch-content > :not(:nth-child(16)),
.message-branch[data-branch="16"] > .message-branch-content > :not(:nth-child(17)),
.message-branch[data-branch="17"] > .message-branch-content > :not(:nth-child(18)),
.message-branch[data-branch="18"] > .message-branch-content > :not(:nth-child(19)),
.message-branch[data-branch="19"] > .message-branch-content > :not(:nth-child(20)) {
  display: none;
}

.message-branch-selector {
  display:     inline-flex;
  align-items: center;
  gap:         var(--space-0-5);
  color:       var(--ink-soft);
}

.message-branch[data-branches="0"] .message-branch-selector,
.message-branch[data-branches="1"] .message-branch-selector {
  display: none;
}

/* Right to left, Previous sits at the right: its chevron points back to the start. */
.message-branch-button:dir(rtl) > .icon {
  scale: -1 1;
}

/* Wide enough for "10 of 12", so the next button never moves. */
.message-branch-page {
  min-inline-size:      7ch;
  font-family:          var(--font-ui);
  font-size:            var(--text-caption);
  font-variant-numeric: tabular-nums;
  text-align:           center;
}

/* Loading */

.message-loading {
  display:     inline-flex;
  align-items: center;
  gap:         var(--space-1);
  height:      1lh;
  color:       var(--ink-dim);
}

.message-loading-dot {
  width:         var(--space-1-5);
  height:        var(--space-1-5);
  border-radius: var(--radius-full);
  background:    currentColor;
  animation:     message-dot calc(var(--duration-loop) * 2) var(--ease-in-out) infinite;
}

.message-loading-dot:nth-child(2) { animation-delay: calc(var(--duration-loop) * 0.33); }
.message-loading-dot:nth-child(3) { animation-delay: calc(var(--duration-loop) * 0.66); }

@keyframes message-dot {
  0%, 80%, 100% { opacity: 0.3; transform: translateY(0); }
  40%           { opacity: 1;   transform: translateY(calc(-1 * var(--space-0-5))); }
}

@media (prefers-reduced-motion: reduce) {
  .message-loading-dot,
  .message-response[data-streaming] > :last-child::after,
  .message-response .md-anim {
    animation: none;
  }
}

}
