/*!
 * Archive Assistant widget styles — package-owned defaults.
 *
 * Plain CSS, no build step and no host Sass variables: the widget must look right on a host
 * that has no design tokens of ours, no icon font and no utility framework. Everything a
 * host is expected to theme is a custom property on `.c-chat`, so overriding a colour is a
 * one-line declaration rather than a fork of this file:
 *
 *   --aa-accent            launcher and primary button colour
 *   --aa-accent-contrast   text on the accent
 *   --aa-surface           panel background
 *   --aa-surface-muted     bubbles, rails, composer
 *   --aa-surface-raised    cards, citations, thought/sources panels
 *   --aa-border            panel and control borders
 *   --aa-text              body text
 *   --aa-text-muted        secondary text
 *   --aa-user-bubble       the researcher's own message
 *   --aa-focus             focus ring colour
 *   --aa-radius            corner radius
 *   --aa-font              font stack
 *   --aa-font-size         base text size; every size below is a ratio of it
 *   --aa-z                 stacking order of the fixed widget
 *
 * Those defaults are declared on `:where(.c-chat)`, which carries no specificity of its
 * own, so a host rule setting them wins whether the host's bundle loads before or after
 * this file. Everything below is a real `.c-chat*` selector and remains package territory.
 *
 * Reduced motion, forced colours and 200% zoom are handled at the bottom of the file.
 */

/* Package defaults for the themable tokens, and nothing else.

  `:where()` and not `.c-chat`: this stylesheet is linked by the widget's own shell, which
  a host renders wherever the widget sits - usually in the body, so *after* the host's
  bundle in the head. At equal specificity the later rule wins, so a host theme written the
  documented way (one `.c-chat` rule setting `--aa-*`) lost to these defaults purely
  because of link order, and the widget rendered package blue on a red-branded site.
  `:where()` contributes zero specificity, so any host selector that matches the root at
  all - `.c-chat`, `[data-chat-root]`, `:root` - beats these regardless of where it is
  loaded. Nothing else moves: the layout below stays at `.c-chat`, so the widget still
  looks right on a host that themes nothing. */
:where(.c-chat) {
    --aa-accent: #1d4ed8;
    --aa-accent-contrast: #ffffff;
    --aa-surface: #ffffff;
    --aa-surface-muted: #f7f7f8;
    --aa-surface-raised: #ffffff;
    --aa-border: #e3e5e8;
    --aa-text: #202123;
    --aa-text-muted: #6b7280;
    --aa-user-bubble: #f0f1f3;
    --aa-focus: #1d4ed8;
    --aa-radius: 18px;
    --aa-font: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    /* Every text size in the widget is a ratio of this, so a host that finds the widget
       small against its own body text raises one value rather than overriding rules. */
    --aa-font-size: 17px;
    --aa-z: 9999;
}

.c-chat {
    position: fixed;
    bottom: 1.25rem;
    right: 1.25rem;
    z-index: var(--aa-z);
    font-family: var(--aa-font);
    color: var(--aa-text);
    font-size: var(--aa-font-size);
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

.c-chat *,
.c-chat *::before,
.c-chat *::after {
    box-sizing: border-box;
}

.c-chat :focus-visible {
    outline: 2px solid var(--aa-focus);
    outline-offset: 2px;
    border-radius: 4px;
}

.c-chat__sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* Launcher
   ----------------------------------------------------------- */
.c-chat__launcher {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 54px;
    height: 54px;
    padding: 0;
    border: 1px solid color-mix(in srgb, var(--aa-accent) 72%, #000);
    border-radius: 9999px;
    cursor: pointer;
    background: var(--aa-accent);
    color: var(--aa-accent-contrast);
    box-shadow: 0 8px 28px rgba(10, 20, 40, .2);
    transition: transform .16s ease, box-shadow .16s ease;
}

.c-chat__launcher:hover {
    transform: translateY(-1px);
    box-shadow: 0 10px 28px rgba(10, 20, 40, .28);
}

.c-chat__launcher:active {
    transform: translateY(0);
    box-shadow: 0 4px 14px rgba(10, 20, 40, .2);
}

.c-chat__launcher[hidden] {
    display: none;
}

/* Panel
   ----------------------------------------------------------- */
.c-chat__panel {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 560px;
    height: 760px;
    max-height: calc(100vh - 2.5rem);
    max-width: calc(100vw - 2.5rem);
    background: var(--aa-surface);
    color: var(--aa-text);
    border: 1px solid color-mix(in srgb, var(--aa-border) 82%, transparent);
    border-radius: var(--aa-radius);
    box-shadow: 0 24px 70px rgba(10, 20, 40, .18), 0 4px 16px rgba(10, 20, 40, .08);
    overflow: hidden;
    animation: c-chat-panel-in .18s ease-out;
}

@keyframes c-chat-panel-in {
    from { opacity: 0; transform: translateY(8px) scale(.985); }
    to { opacity: 1; transform: none; }
}

.c-chat__panel[hidden] {
    display: none;
}

.c-chat__resize {
    position: absolute;
    top: 1px;
    left: 1px;
    width: 16px;
    height: 16px;
    cursor: nwse-resize;
    background:
        linear-gradient(135deg, var(--aa-border) 0 2px, transparent 2px 100%) no-repeat,
        linear-gradient(135deg, transparent 0 4px, var(--aa-border) 4px 6px, transparent 6px 100%) no-repeat;
    z-index: 2;
}

/* Header
   ----------------------------------------------------------- */
.c-chat__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    min-height: 64px;
    padding: .75rem 1rem .75rem 1.125rem;
    border-bottom: 1px solid color-mix(in srgb, var(--aa-border) 76%, transparent);
    background: color-mix(in srgb, var(--aa-surface) 96%, transparent);
}

.c-chat__title {
    font-size: .9375em;
    font-weight: 650;
    line-height: 1.25;
    letter-spacing: -.01em;
    display: flex;
    align-items: center;
    gap: .5rem;
}

.c-chat__title::before {
    content: "";
    width: 7px;
    height: 7px;
    border-radius: 9999px;
    background: var(--aa-accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--aa-accent) 13%, transparent);
}

.c-chat__scope {
    margin-top: 3px;
    font-size: .75em;
    font-weight: 450;
    color: var(--aa-text-muted);
}

.c-chat__actions {
    display: flex;
    align-items: center;
    gap: .25rem;
}

.c-chat__icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 0;
    border-radius: var(--aa-radius);
    background: transparent;
    color: var(--aa-text-muted);
    cursor: pointer;
    transition: background .14s ease, color .14s ease;
}

.c-chat__icon-btn:hover {
    background: color-mix(in srgb, var(--aa-accent) 8%, transparent);
    color: var(--aa-text);
}

.c-chat__icon-btn[hidden] {
    display: none;
}

/* Transcript
   ----------------------------------------------------------- */
.c-chat__body {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 1.25rem 1.25rem .75rem;
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    background: var(--aa-surface);
    scroll-behavior: smooth;
    scrollbar-gutter: stable;
}

[data-chat-transcript] {
    display: flex;
    flex-direction: column;
    gap: 1.75rem;
}

/* Persisted history is a flat message sequence; live messages are already grouped in a
   turn. Keep question-to-answer spacing compact without collapsing separate turns. */
[data-chat-transcript] > .c-chat__msg--user + .c-chat__msg--assistant {
    margin-top: -1rem;
}

.c-chat__empty {
    color: var(--aa-text-muted);
    font-size: .875em;
    text-align: center;
    padding: 2.5rem 1.5rem;
}

.c-chat__empty[hidden],
.c-chat__earlier[hidden] {
    display: none;
}

.c-chat__earlier {
    text-align: center;
}

.c-chat__earlier-btn {
    border: 1px solid var(--aa-border);
    border-radius: 9999px;
    background: var(--aa-surface-muted);
    color: var(--aa-text-muted);
    font-size: .8125em;
    font-weight: 500;
    padding: .375rem .875rem;
    cursor: pointer;
    transition: background .14s ease, color .14s ease, border-color .14s ease;
}

.c-chat__earlier-btn:hover {
    background: var(--aa-user-bubble);
    color: var(--aa-text);
    border-color: var(--aa-border);
}

.c-chat__turn {
    display: flex;
    flex-direction: column;
    gap: .75rem;
    scroll-margin-block: .75rem;
}

/* Messages
   ----------------------------------------------------------- */
.c-chat__msg--user {
    display: flex;
    justify-content: flex-end;
}

.c-chat__msg--user-bubble {
    max-width: 82%;
    padding: .625rem .875rem;
    border-radius: 18px 18px 4px 18px;
    background: var(--aa-user-bubble);
    color: var(--aa-text);
    font-size: 1em;
    font-weight: 450;
    line-height: 1.5;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    word-break: break-word;
}

.c-chat__msg--assistant {
    display: flex;
    flex-direction: column;
    gap: .625rem;
    min-width: 0;
}

.c-chat__msg--assistant .c-chat__bubble {
    border-radius: 0;
}

/* Assistant answers use the transcript surface rather than a card. This keeps long,
   source-heavy research readable and matches the interaction rhythm of ChatGPT. */
.c-chat__bubble {
    padding: 0 .125rem;
    border-radius: 0;
    background: transparent;
    color: var(--aa-text);
    overflow-wrap: anywhere;
    word-break: break-word;
}

.c-chat__bubble > :first-child {
    margin-top: 0;
}

.c-chat__bubble > :last-child {
    margin-bottom: 0;
}

.c-chat__bubble p {
    margin: 0 0 .8rem;
    line-height: 1.65;
    overflow-wrap: anywhere;
    word-break: break-word;
}

.c-chat__bubble strong {
    font-weight: 650;
}

.c-chat__bubble strong,
.c-chat__bubble em,
.c-chat__bubble span {
    overflow-wrap: anywhere;
    word-break: break-word;
}

.c-chat__bubble h1,
.c-chat__bubble h2,
.c-chat__bubble h3,
.c-chat__bubble h4,
.c-chat__bubble h5,
.c-chat__bubble h6 {
    margin: 1.1rem 0 .45rem;
    font-size: calc(1em + 1px);
    font-weight: 650;
    line-height: 1.45;
    letter-spacing: -.006em;
    color: var(--aa-text);
    overflow-wrap: anywhere;
    word-break: break-word;
}

.c-chat__bubble h1:first-child,
.c-chat__bubble h2:first-child,
.c-chat__bubble h3:first-child {
    margin-top: 0;
}

.c-chat__bubble ul,
.c-chat__bubble ol {
    margin: .25rem 0 .85rem;
    padding-left: 1.45rem;
    list-style-position: outside;
}

.c-chat__bubble li {
    padding-left: .2rem;
    line-height: 1.6;
}

.c-chat__bubble li::before {
    content: none;
}

.c-chat__bubble ul > li::marker {
    color: var(--aa-text-muted);
    font-size: .82em;
}

.c-chat__bubble ol > li::marker {
    color: var(--aa-text-muted);
    font-weight: 550;
    font-variant-numeric: tabular-nums;
}

.c-chat__bubble li + li {
    margin-top: .35rem;
}

.c-chat__bubble li > ul,
.c-chat__bubble li > ol {
    margin: .35rem 0 .1rem;
}

.c-chat__bubble hr {
    margin: 1rem 0;
    border: 0;
    border-top: 1px solid var(--aa-border);
}

.c-chat__bubble pre {
    margin: 0 0 .8rem;
    padding: .75rem;
    overflow-x: auto;
    background: var(--aa-surface-muted);
    border: 1px solid var(--aa-border);
    border-radius: 10px;
    font-size: .8125em;
}

.c-chat__bubble code {
    font-size: .9em;
}

.c-chat__bubble blockquote {
    margin: 0 0 .8rem;
    padding-left: .75rem;
    border-left: 2px solid var(--aa-accent);
    color: var(--aa-text-muted);
}

.c-chat__bubble a {
    color: var(--aa-accent);
}

/* Working timeline
   -----------------------------------------------------------
   The turn's steps and its reasoning in one column, in the order they happened. A step is
   a marker and a readable sentence; the queries or page references it used sit under it,
   and its outcome closes it. Reasoning between steps is prose, because that is what it is.
   The vertical rule is drawn once, by the column, rather than per row - a per-row border
   left gaps at every margin and read as several lists. */
.c-chat__timeline {
    display: flex;
    flex-direction: column;
    gap: .625rem;
    max-height: 16rem;
    overflow-y: auto;
    padding-left: .5rem;
    border-left: 2px solid color-mix(in srgb, var(--aa-accent) 20%, var(--aa-border));
    font-size: .9375em;
    color: var(--aa-text-muted);
}

.c-chat__step {
    display: flex;
    align-items: flex-start;
    gap: .375rem;
    min-width: 0;
}

.c-chat__step-marker {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 13px;
    height: 1.45em;
    color: var(--aa-text-muted);
}

.c-chat__step-marker > svg {
    display: block;
    width: 12px;
    height: 12px;
}

/* A running step's marker breathes; a finished one does not. The tick is the accent
   because "this happened" is the one thing a reader scans the column for. */
.c-chat__step[data-state="running"] .c-chat__step-marker {
    animation: c-chat-trace-pulse 1.4s ease-in-out infinite;
}

.c-chat__step[data-state="done"] .c-chat__step-marker {
    color: var(--aa-accent);
}

.c-chat__step[data-state="warn"] .c-chat__step-marker {
    color: #b45309;
}

.c-chat__step-main {
    display: flex;
    flex-direction: column;
    gap: .1875rem;
    min-width: 0;
}

.c-chat__step-title {
    color: var(--aa-text);
    font-weight: 500;
    line-height: 1.45;
}

.c-chat__step[data-state="warn"] .c-chat__step-title {
    color: #b45309;
}

/* What a step was given, on one line under its title. */
.c-chat__step-detail {
    line-height: 1.45;
    overflow-wrap: anywhere;
}

.c-chat__step-meta {
    line-height: 1.45;
    opacity: .85;
}

/* Reasoning between steps, aligned to the step titles rather than the markers - the marker
   column plus its gap, and nothing more, so the narrative sits in one measure. */
.c-chat__thought {
    padding-left: calc(13px + .375rem);
    line-height: 1.55;
}

.c-chat__thought > :first-child {
    margin-top: 0;
}

.c-chat__thought > :last-child {
    margin-bottom: 0;
}

/* Streaming state
   ----------------------------------------------------------- */
.c-chat__thinking[hidden] {
    display: none;
}

.c-chat__status-label {
    font-size: .8125em;
    color: var(--aa-text-muted);
}

.c-chat__skeleton {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    margin-top: .5rem;
}

.c-chat__skeleton-line {
    height: 10px;
    border-radius: 5px;
    background: linear-gradient(90deg, var(--aa-border) 25%, var(--aa-surface) 50%, var(--aa-border) 75%);
    background-size: 200% 100%;
    animation: c-chat-shimmer 1.5s linear infinite;
}

.c-chat__skeleton-line--short {
    width: 70%;
}

@keyframes c-chat-shimmer {
    from { background-position: 200% 0; }
    to { background-position: -200% 0; }
}

/* The turn's working - what it searched and what it reasoned - as one disclosure above
   the answer. Shut, it is a single line: a pulsing "Working..." while the turn runs, and
   afterwards a plain statement of what the turn did. Open, it shows the searches and the
   reasoning. What it must never do is put a page of notes where the answer should be,
   which is what an expanded panel above the reply did. */
.c-chat__trace {
    font-size: .8125em;
    color: var(--aa-text-muted);
}

.c-chat__trace[hidden] {
    display: none;
}

.c-chat__trace-summary {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    cursor: pointer;
    color: var(--aa-text-muted);
    font-weight: 500;
    line-height: 1.4;
}

/* Only while the turn is actually working. A pulse on a finished trace would report
   progress that is not happening. */
.c-chat__trace[data-running] .c-chat__trace-summary {
    animation: c-chat-trace-pulse 1.6s ease-in-out infinite;
}

@keyframes c-chat-trace-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: .55; }
}

@media (prefers-reduced-motion: reduce) {
    .c-chat__trace[data-running] .c-chat__trace-summary {
        animation: none;
    }
}

.c-chat__trace-summary::marker,
.c-chat__trace-summary::-webkit-details-marker {
    color: var(--aa-text-muted);
}

.c-chat__trace-body {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    margin-top: .5rem;
}

/* Sources and citations
   ----------------------------------------------------------- */
/* `a.c-chat__cite`, not `.c-chat__cite`: the pill is always an anchor, and the generic
   `.c-chat__bubble a` rule above is one selector *more* specific than a bare class, so a
   plain class here lost `color` to it and the pill's own colour declaration was dead. The
   element qualifier makes the two equally specific and this one later, which is what a host
   theming `--aa-text` expects to see on the pill. */
a.c-chat__cite {
    /* `inline-block`, not `inline-flex`: an inline-flex box takes its baseline from its
       first flex item, which here is the icon - a replaced element whose baseline is its
       bottom edge - so the pill's text sat above the prose it belongs to and no nudge
       could align it at every font size. An inline-block's baseline is its own last line
       box, i.e. the page number, so the pill and the sentence share a baseline by
       construction and the icon is offset instead. */
    display: inline-block;
    padding: .0625rem .4375rem;
    margin: 0 2px;
    border: 1px solid color-mix(in srgb, var(--aa-accent) 30%, var(--aa-border));
    border-radius: 9999px;
    background: color-mix(in srgb, var(--aa-accent) 7%, var(--aa-surface));
    color: var(--aa-accent);
    font-size: .8em;
    font-weight: 600;
    line-height: 1.35;
    text-decoration: none;
    /* Measured, not guessed: at `baseline` the pill's box centre sat 1.1px below the
       line's, because the box is taller than the text it wraps. A small em-relative lift
       puts the two centres within 0.2px at any base size, so the pill reads as part of the
       sentence rather than a superscript. */
    vertical-align: .07em;

    box-decoration-break: clone;
    transition: background .14s ease, border-color .14s ease;
}

.c-chat__cite-icon {
    vertical-align: -.15em;
    margin-right: 3px;
}

a.c-chat__cite:hover {
    background: color-mix(in srgb, var(--aa-accent) 15%, var(--aa-surface));
    border-color: color-mix(in srgb, var(--aa-accent) 50%, var(--aa-border));
}

.c-chat__sources {
    margin-top: .5rem;
    font-size: .8125em;
}

.c-chat__sources-summary {
    cursor: pointer;
    color: var(--aa-text-muted);
    font-weight: 500;
    display: inline-flex;
    align-items: center;
    gap: .25rem;
}

.c-chat__sources-summary:hover {
    color: var(--aa-text);
}

.c-chat__sources-list {
    margin: .375rem 0 0;
    padding-left: 1.25rem;
    display: flex;
    flex-direction: column;
    gap: .25rem;
}

.c-chat__sources-link {
    color: var(--aa-accent);
    text-decoration: none;
}

.c-chat__sources-link:hover {
    text-decoration: underline;
}

/* Access notices
   -----------------------------------------------------------
   Something the reader can act on, not a fault: material outside a subscription, a
   trial that has run out, an allowance reached. Amber rather than the red an error
   wears, because a reader who cannot tell the two apart learns to ignore both.

   The colours are literals rather than tokens on purpose: a host themes the widget's
   surfaces, and a warning that inherited an accent would stop reading as a warning on
   a red or amber brand. They are mixed into `--aa-surface` so the banner still belongs
   to the panel it sits in. */
.c-chat__notice {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .25rem .5rem;
    margin: 0 0 .5rem;
    padding: .5rem .75rem;
    border: 1px solid color-mix(in srgb, #d97706 30%, var(--aa-border));
    border-radius: 8px;
    background: color-mix(in srgb, #f59e0b 10%, var(--aa-surface));
    color: color-mix(in srgb, #92400e 85%, var(--aa-text));
    font-size: .8125em;
    line-height: 1.45;
}

.c-chat__notice--info {
    border-color: color-mix(in srgb, #2563eb 25%, var(--aa-border));
    background: color-mix(in srgb, #3b82f6 8%, var(--aa-surface));
    color: color-mix(in srgb, #1e40af 85%, var(--aa-text));
}

/* A blocking notice sits directly above the composer it disables, so it reads as the
   reason the control is dead rather than as a message about the conversation. */
.c-chat__notice--blocking {
    margin: 0 .75rem .5rem;
}

.c-chat__notice-text {
    flex: 1 1 auto;
}

.c-chat__notice-action {
    color: inherit;
    font-weight: 600;
    text-decoration: underline;
    white-space: nowrap;
}

/* The send control keeps its shape while refusing, so the composer does not move when a
   notice appears; only its affordance changes. */
.c-chat__send:disabled {
    opacity: .45;
    cursor: not-allowed;
}

@media (forced-colors: active) {
    .c-chat__notice {
        border: 1px solid CanvasText;
    }
}

/* Errors, stopping, retry
   ----------------------------------------------------------- */
.c-chat__error {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    padding: .625rem .875rem;
    border-radius: 14px 4px 14px 14px;
    background: color-mix(in srgb, #ef4444 7%, var(--aa-surface));
    color: #b91c1c;
    border: 1px solid color-mix(in srgb, #ef4444 25%, var(--aa-border));
    font-size: .8125em;
}

.c-chat__error-actions {
    display: flex;
    gap: .5rem;
}

.c-chat__stopped {
    display: flex;
    align-items: center;
    gap: .5rem;
    font-size: .8125em;
    color: var(--aa-text-muted);
}

.c-chat__retry {
    border: 1px solid var(--aa-border);
    border-radius: 9999px;
    background: var(--aa-surface);
    color: var(--aa-text);
    font-size: .8125em;
    font-weight: 500;
    padding: .25rem .75rem;
    cursor: pointer;
    transition: background .14s ease, border-color .14s ease;
}

.c-chat__retry:hover {
    background: var(--aa-surface-muted);
    border-color: var(--aa-accent);
}

/* Suggestions
   ----------------------------------------------------------- */
.c-chat__suggestions {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .375rem;
    margin-top: .125rem;
}

.c-chat__suggestions[hidden] {
    display: none;
}

.c-chat__suggestion {
    /* Explicit box metrics, because a host's global `button` rule is the one thing that
       reaches inside the widget: an inherited line-height or margin is what makes two
       chips sit on top of one another. */
    display: block;
    width: auto;
    max-width: 100%;
    min-width: 0;
    margin: 0;
    border: 1px solid var(--aa-border);
    border-radius: 9999px;
    background: var(--aa-surface);
    color: var(--aa-text);
    font: inherit;
    font-size: .875em;
    font-weight: 450;
    line-height: 1.4;
    padding: .375rem .875rem;
    cursor: pointer;
    text-align: left;
    white-space: normal;
    transition: background .14s ease, border-color .14s ease, transform .1s ease;
}

.c-chat__suggestion:hover {
    background: var(--aa-surface-muted);
    border-color: color-mix(in srgb, var(--aa-accent) 35%, var(--aa-border));
}

.c-chat__suggestion:active {
    transform: translateY(1px);
}

/* Composer
   ----------------------------------------------------------- */
.c-chat__form {
    padding: .5rem 1rem 1rem;
    border-top: 0;
    background: linear-gradient(180deg, color-mix(in srgb, var(--aa-surface) 0%, transparent), var(--aa-surface) 28%);
}

.c-chat__composer {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    padding: .7rem .75rem .625rem;
    border: 1px solid var(--aa-border);
    border-radius: 22px;
    background: var(--aa-surface-raised);
    box-shadow: 0 8px 24px rgba(10, 20, 40, .08);
    transition: border-color .16s ease, box-shadow .16s ease;
}

.c-chat__composer:focus-within {
    border-color: color-mix(in srgb, var(--aa-accent) 62%, var(--aa-border));
    box-shadow: 0 8px 26px rgba(10, 20, 40, .09), 0 0 0 2px color-mix(in srgb, var(--aa-accent) 10%, transparent);
}

.c-chat__input {
    width: 100%;
    max-height: 140px;
    min-height: 24px;
    height: 24px;
    display: block;
    padding: 0 .25rem;
    border: 0;
    background: transparent;
    color: var(--aa-text);
    font: inherit;
    font-size: 1em;
    line-height: 1.5;
    resize: none;
    overflow-y: auto;
}

.c-chat__input::placeholder {
    color: color-mix(in srgb, var(--aa-text-muted) 80%, transparent);
}

.c-chat__input:focus {
    outline: none;
}

.c-chat__toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    flex-wrap: wrap;
}

.c-chat__toolbar-actions {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin-left: auto;
}

.c-chat__toolbar-actions .c-chat__stop,
.c-chat__toolbar-actions .c-chat__send {
    white-space: nowrap;
}

.c-chat__depth {
    display: inline-flex;
    padding: 2px;
    border: 0;
    border-radius: 9999px;
    overflow: hidden;
    background: var(--aa-surface-muted);
}

.c-chat__depth-pill {
    border: 0;
    border-radius: 9999px;
    background: transparent;
    color: var(--aa-text-muted);
    font-size: .75em;
    font-weight: 500;
    padding: .22rem .55rem;
    cursor: pointer;
    transition: background .14s ease, color .14s ease, box-shadow .14s ease;
}

.c-chat__depth-pill:hover {
    color: var(--aa-text);
}

.c-chat__depth-pill.is-active {
    background: var(--aa-surface-raised);
    color: var(--aa-text);
    box-shadow: 0 1px 3px rgba(10, 20, 40, .12);
}

.c-chat__send {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: 0;
    border-radius: 9999px;
    background: var(--aa-accent);
    color: var(--aa-accent-contrast);
    cursor: pointer;
    transition: filter .14s ease, opacity .14s ease, transform .1s ease;
}

.c-chat__send:hover {
    filter: brightness(1.06);
}

.c-chat__send:active {
    transform: translateY(1px);
}

.c-chat__send:disabled {
    opacity: .38;
    cursor: default;
}

.c-chat__stop {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .375rem;
    min-height: 34px;
    border: 1px solid var(--aa-border);
    border-radius: 9999px;
    background: var(--aa-surface-raised);
    color: var(--aa-text);
    font-size: .8125em;
    font-weight: 500;
    padding: .3rem .7rem;
    cursor: pointer;
    transition: background .14s ease, border-color .14s ease;
}

.c-chat__stop:hover {
    background: var(--aa-surface-muted);
    border-color: #ef4444;
    color: #b91c1c;
}

.c-chat__stop[hidden] {
    display: none;
}

/* Accessibility preferences
   -----------------------------------------------------------
   A researcher who has asked for less motion gets none of ours; a
   forced-colours (high contrast) display gets system colours rather
   than our palette; and at large zoom the panel stops being a fixed
   card and takes the viewport, so nothing is clipped off-screen. */

@media (prefers-reduced-motion: reduce) {
    .c-chat *,
    .c-chat *::before,
    .c-chat *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }

    .c-chat__skeleton-line {
        animation: none;
        background: var(--aa-border);
    }

    .c-chat__panel {
        animation: none;
    }

    .c-chat__launcher,
    .c-chat__send {
        transition: none;
    }
}

@media (forced-colors: active) {
    .c-chat {
        --aa-accent: ButtonText;
        --aa-accent-contrast: ButtonFace;
        --aa-surface: Canvas;
        --aa-surface-muted: Canvas;
        --aa-surface-raised: Canvas;
        --aa-border: CanvasText;
        --aa-text: CanvasText;
        --aa-text-muted: CanvasText;
        --aa-user-bubble: Canvas;
        --aa-focus: Highlight;
    }

    .c-chat__panel,
    .c-chat__msg--user-bubble,
    .c-chat__bubble,
    .c-chat__cite,
    .c-chat__suggestion {
        border: 1px solid CanvasText;
    }

    .c-chat__depth-pill.is-active {
        forced-color-adjust: none;
        background: Highlight;
        color: HighlightText;
    }
}

/* Narrow viewports and heavy zoom: the panel fills the screen instead of
   overflowing it, and the launcher stays reachable.

   `100vh` is the *largest* possible mobile viewport - as if the browser's address
   bar were already collapsed - not what is actually visible. A `position: fixed`
   panel sized to it renders taller than the real visible area, so its own header
   sits behind the browser's UI chrome instead of below it. `dvh` tracks the real,
   currently-visible viewport as that chrome shows and hides; declared after the
   `vh` value so a browser without `dvh` support simply keeps the fallback. */
@media (max-width: 480px), (max-height: 480px) {
    .c-chat {
        bottom: 0;
        right: 0;
    }

    .c-chat__panel {
        width: 100vw;
        height: 100vh;
        height: 100dvh;
        max-width: 100vw;
        max-height: 100vh;
        max-height: 100dvh;
        border-radius: 0;
        animation: none;
    }

    .c-chat__resize {
        display: none;
    }

    .c-chat__launcher {
        margin: 1rem;
    }
}
