/*
 * Component styles for the RAG answer.
 *
 * Loaded by the plugin itself, so it applies on a normal page as well as
 * inside the chat widget — where the panel injects the shell into the host
 * DOM and the embed document's own assets never travel along, which is why
 * the widget block in setup.typoscript includes this file too. Layout of the
 * bare embed document stays in RagEmbed.css.
 */

/* Positioning context for the spinner that sits over the answer. */
.ws-meilisearch-rag-answer-wrap {
    position: relative;
}

/* While tokens are still arriving the answer is readable but visibly
 * unfinished. The reserved strip at the bottom is where the spinner sits: it
 * marks the point the next chunk will appear at and travels down with the
 * text, instead of floating in the middle of what is already written. The
 * strip is also what gives the spinner somewhere to sit during the seconds
 * before the first token lands, when the paragraph is still empty. */
.ws-meilisearch-rag-answer[data-streaming="true"] {
    opacity: .4;
    padding-bottom: 2.25rem;
    min-height: 2.25rem;
    transition: opacity .2s ease-out;
}

.ws-meilisearch-rag-spinner {
    position: absolute;
    /* Pinned to the reserved strip below the text, at the start of the line
     * the next chunk will be written on. */
    left: 0;
    right: 0;
    bottom: 0;
    height: 2.25rem;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    /* Clicks belong to the text underneath, not to the overlay. */
    pointer-events: none;
}

.ws-meilisearch-rag-spinner[hidden] {
    display: none;
}

.ws-meilisearch-rag-spinner::before {
    content: '';
    width: 1.25rem;
    height: 1.25rem;
    border: .15rem solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    opacity: .55;
    animation: ws-meilisearch-rag-spin .8s linear infinite;
}

@keyframes ws-meilisearch-rag-spin {
    to { transform: rotate(360deg); }
}

/* Visitors who asked for less motion get a static ring: the faded answer and
 * the status label already say that something is running. */
@media (prefers-reduced-motion: reduce) {
    .ws-meilisearch-rag-spinner::before {
        animation: none;
    }
    .ws-meilisearch-rag-answer[data-streaming="true"] {
        transition: none;
    }
}

/* Screen-reader label for the spinner. Own implementation rather than
 * Bootstrap's .visually-hidden, which is not available in the bare embed. */
.ws-meilisearch-rag-spinner__label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* The input sits below the transcript, which in the widget means it scrolls
 * away as the conversation grows. Inside the panel — the one place with a
 * bounded scroll container — it stays put at the bottom instead. Scoped to the
 * embed body on purpose: on a full page there is no such container, and a
 * sticky field would hover over whatever follows the plugin.
 *
 * The sticky element is the container around the field AND the "start over"
 * link, not the form alone: with only the form pinned, that link sat below it
 * in the panel's padding, and the white shadow under the form — which exists
 * to cover exactly that padding — painted straight over it. */
.ws-meilisearch-rag-embed .ws-meilisearch-rag-ask {
    position: sticky;
    bottom: 0;
    z-index: 1;
    padding-top: .5rem;
    /* sticky positions the margin box: any bottom margin would leave a
     * transparent strip at the bottom edge of the panel with the transcript
     * scrolling visibly through it. The form therefore carries no Bootstrap
     * mb-* utility (those are !important and cannot be overridden here) and
     * pads instead. */
    padding-bottom: .5rem;
    /* Opaque, so the transcript does not scroll through underneath it. The
     * embed document and the panel body are both white (RagEmbed.css line 20,
     * ChatWidget.css line 58); `inherit` would land on a transparent parent. */
    background: #fff;
    /* The panel body keeps its own bottom padding, and overflow is clipped at
     * the padding box — so the strip below the sticky form would still have
     * the transcript scrolling through it. Extending the background downwards
     * with a shadow covers it without touching the layout. */
    box-shadow: 0 1rem 0 #fff;
}

/* Inline reference: a number in brackets, deliberately unobtrusive. The
 * citation used to be the document title, which on a knowledge base carrying
 * one topic per product and release took 40 to 60 characters and dominated the
 * sentence it belonged to. */
.ws-meilisearch-rag-citation {
    font-size: .85em;
    text-decoration: none;
}

.ws-meilisearch-rag-citation:hover,
.ws-meilisearch-rag-citation:focus-visible {
    text-decoration: underline;
}

/* The legend explaining the numbers. Only the documents the answer actually
 * cited, one line each, small and quiet — it is a reference, not content. */
.ws-meilisearch-rag-citations {
    margin: .75rem 0 0;
    padding-left: 1.35rem;
    font-size: .85em;
    line-height: 1.45;
    opacity: .8;
}

.ws-meilisearch-rag-citations li + li {
    margin-top: .15rem;
}

/* Media sources (RagCitationLabelsEvent::setMedia): an inline reference with a
 * play mark, and a block of cards between the answer and the source list. The
 * answer element is white-space: pre-wrap, so the block resets it. Colours
 * follow the site's primary colour; --wsm-media-accent overrides it. */
.ws-meilisearch-rag-citation--media {
    display: inline-flex;
    align-items: center;
    gap: .2em;
    margin-left: .15em;
    padding: 0 .45em;
    border-radius: 1em;
    background: color-mix(in srgb, var(--wsm-media-accent, var(--bs-primary, #1a5fb4)) 12%, #fff);
    color: var(--wsm-media-accent, var(--bs-primary, #1a5fb4));
    font-weight: 600;
    line-height: 1.5;
    vertical-align: .05em;
}

.ws-meilisearch-rag-citation__play {
    width: 0;
    height: 0;
    border-style: solid;
    border-width: .3em 0 .3em .5em;
    border-color: transparent transparent transparent currentColor;
}

.ws-meilisearch-rag-media {
    container-type: inline-size;
    white-space: normal;
    margin-top: 1.1rem;
    padding-top: 1rem;
    border-top: 1px solid rgba(0, 0, 0, .1);
    display: flex;
    flex-direction: column;
    gap: .65rem;
}

.ws-meilisearch-rag-media p {
    margin: 0;
}

.ws-meilisearch-rag-media__heading {
    font-size: .8em;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--wsm-media-accent, var(--bs-primary, #1a5fb4));
}

.ws-meilisearch-rag-media__more {
    margin-top: .35rem !important;
    font-size: .9em;
}

.ws-meilisearch-rag-media__note {
    font-size: .82em;
    opacity: .8;
}

.ws-meilisearch-rag-media__list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
    gap: .65rem;
}

.ws-meilisearch-rag-media__card {
    display: flex;
    gap: .8rem;
    align-items: stretch;
    padding: .6rem;
    border: 1px solid rgba(0, 0, 0, .14);
    color: inherit;
    text-decoration: none;
    min-width: 0;
}

.ws-meilisearch-rag-media__card:hover,
.ws-meilisearch-rag-media__card:focus-visible {
    border-color: var(--wsm-media-accent, var(--bs-primary, #1a5fb4));
    color: inherit;
}

.ws-meilisearch-rag-media__card--primary {
    gap: 1rem;
    padding: .75rem;
    background: color-mix(in srgb, var(--wsm-media-accent, var(--bs-primary, #1a5fb4)) 5%, #fff);
    border-color: color-mix(in srgb, var(--wsm-media-accent, var(--bs-primary, #1a5fb4)) 30%, #fff);
}

.ws-meilisearch-rag-media__thumb {
    position: relative;
    flex: 0 0 5.5rem;
    height: 3.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    background: var(--wsm-media-accent, var(--bs-primary, #1a5fb4));
}

.ws-meilisearch-rag-media__card--primary .ws-meilisearch-rag-media__thumb {
    flex-basis: 10rem;
    height: 6rem;
}

/* Still of the clip: fills the preview, the play mark and the start badge
 * stay on top (both are positioned and come later in the markup). */
.ws-meilisearch-rag-media__image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.ws-meilisearch-rag-media__thumb:has(.ws-meilisearch-rag-media__image) .ws-meilisearch-rag-media__play {
    background: rgba(255, 255, 255, .9);
    box-shadow: 0 0 .5em rgba(0, 0, 0, .35);
}

.ws-meilisearch-rag-media__play {
    width: 2.2em;
    height: 2.2em;
    border-radius: 50%;
    background: #fff;
    position: relative;
}

.ws-meilisearch-rag-media__play::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    margin: -.4em 0 0 -.22em;
    border-style: solid;
    border-width: .4em 0 .4em .65em;
    border-color: transparent transparent transparent var(--wsm-media-accent, var(--bs-primary, #1a5fb4));
}

.ws-meilisearch-rag-media__card:not(.ws-meilisearch-rag-media__card--primary) .ws-meilisearch-rag-media__play {
    width: 1.6em;
    height: 1.6em;
}

.ws-meilisearch-rag-media__start {
    position: absolute;
    right: .3rem;
    bottom: .3rem;
    padding: 0 .3em;
    background: rgba(0, 0, 0, .75);
    color: #fff;
    font-size: .75em;
    font-weight: 600;
    line-height: 1.5;
}

.ws-meilisearch-rag-media__body {
    display: flex;
    flex-direction: column;
    gap: .15rem;
    min-width: 0;
    font-size: .9em;
}

.ws-meilisearch-rag-media__title {
    font-weight: 600;
    line-height: 1.35;
}

.ws-meilisearch-rag-media__card--primary .ws-meilisearch-rag-media__title {
    font-size: 1.1em;
    font-weight: 700;
}

.ws-meilisearch-rag-media__number {
    display: inline-block;
    margin-right: .4em;
    padding: 0 .4em;
    border-radius: 1em;
    background: color-mix(in srgb, var(--wsm-media-accent, var(--bs-primary, #1a5fb4)) 12%, #fff);
    color: var(--wsm-media-accent, var(--bs-primary, #1a5fb4));
    font-size: .8em;
    font-weight: 600;
    vertical-align: .1em;
}

.ws-meilisearch-rag-media__context,
.ws-meilisearch-rag-media__meta {
    font-size: .9em;
    opacity: .8;
}

.ws-meilisearch-rag-media__cta {
    margin-top: auto;
    padding-top: .25rem;
    font-weight: 600;
    color: var(--wsm-media-accent, var(--bs-primary, #1a5fb4));
}

.ws-meilisearch-rag-media__cta::after {
    content: " \2197";
}

/* The chat panel is narrow on a wide screen too, so the block's own width
 * decides, not the viewport's. */
@container (max-width: 30rem) {
    .ws-meilisearch-rag-media__card--primary {
        flex-direction: column;
    }

    .ws-meilisearch-rag-media__card--primary .ws-meilisearch-rag-media__thumb {
        flex-basis: auto;
        height: 7rem;
    }
}

/* Question field and its button, same height.
 *
 * Bootstrap 5 input groups are flex containers and stretch their children to
 * equal height by themselves. Measured in this project the site theme renders
 * .input-group as `inline-table` instead, so that never happened: the field
 * came out 25px against the button's 35px, because the theme's underline-style
 * input pads 1px where the button pads 6px.
 *
 * Restoring flex inside the plugin's own form fixes it at the cause and keeps
 * working when the theme changes its paddings — an explicit height would have
 * to be chased every time. Scoped to this form, so the theme's own input
 * groups elsewhere are untouched. */
.ws-meilisearch-rag-form .input-group {
    display: flex;
    align-items: stretch;
}

.ws-meilisearch-rag-form .input-group > .form-control {
    /* Take the remaining width; the button keeps its intrinsic size. */
    flex: 1 1 auto;
    width: 1%;
    /* The theme's 25px comes from an explicit height on .form-control, which
     * would win over stretching. */
    height: auto;
}

/* "Was this helpful?" under a finished answer (meilisearch.rag.feedback). */
.ws-meilisearch-rag-feedback {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: .75rem;
    padding-top: .75rem;
    border-top: 1px solid var(--wsm-bg-soft, #f2f4f7);
    font-size: .93em;
}
.ws-meilisearch-rag-feedback__btn {
    width: 44px;
    height: 36px;
    padding: 0;
    border: 1px solid var(--wsm-border, #d7dbe0);
    border-radius: .375rem;
    background: #fff;
    color: var(--wsm-accent, #1a5fb4);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}
.ws-meilisearch-rag-feedback__btn svg {
    width: 18px;
    height: 18px;
}
.ws-meilisearch-rag-feedback__btn:hover {
    border-color: var(--wsm-accent, #1a5fb4);
}
.ws-meilisearch-rag-feedback__btn[aria-pressed="true"] {
    background: var(--wsm-accent, #1a5fb4);
    border-color: var(--wsm-accent, #1a5fb4);
    color: #fff;
}
.ws-meilisearch-rag-feedback__thanks {
    color: var(--wsm-muted, #5b6570);
    font-size: .9em;
}
.ws-meilisearch-rag-feedback__thanks:empty {
    display: none;
}
.ws-meilisearch-rag-feedback__support {
    margin-left: auto;
    font-weight: 600;
}
/* After "not helpful": optional reasons and text, then the support card. */
.ws-meilisearch-rag-feedback-more:empty {
    display: none;
}
.ws-meilisearch-rag-feedback-more {
    margin-top: .75rem;
    font-size: .93em;
}
.ws-meilisearch-rag-feedback-form fieldset {
    border: 0;
    margin: 0;
    padding: 0;
}
.ws-meilisearch-rag-feedback-form__legend {
    font-size: inherit;
    font-weight: 600;
    margin-bottom: .25rem;
}
.ws-meilisearch-rag-feedback-form textarea {
    width: 100%;
}
.ws-meilisearch-rag-feedback-card {
    border-color: var(--wsm-border, #d7dbe0);
}
/* Themes colour links inside the chat; the button text must stay readable. */
.ws-meilisearch-rag-feedback-card .btn,
.ws-meilisearch-rag-feedback-card .btn:hover,
.ws-meilisearch-rag-feedback-card .btn:focus {
    color: #fff;
}

/* The finished answer is block HTML (CitationRenderer::blocks()): paragraphs,
 * lists, callouts. While tokens arrive it is raw text, whose line breaks only
 * show with pre-wrap. */
.ws-meilisearch-rag-answer[data-streaming="true"] {
    white-space: pre-wrap;
}
.ws-meilisearch-rag-answer > p,
.ws-meilisearch-rag-answer > ol,
.ws-meilisearch-rag-answer > ul,
.ws-meilisearch-rag-callout {
    margin: 0 0 .75em;
}
.ws-meilisearch-rag-answer ol,
.ws-meilisearch-rag-answer ul {
    padding-left: 1.4em;
}
.ws-meilisearch-rag-answer li + li {
    margin-top: .35em;
}
.ws-meilisearch-rag-answer li > ul {
    margin: .35em 0 0;
}
.ws-meilisearch-rag-callout {
    padding: .75em 1em;
    background: var(--wsm-bg-soft, #f2f4f7);
    font-size: .94em;
}
.ws-meilisearch-rag-callout > p {
    margin: 0 0 .35em;
}
.ws-meilisearch-rag-callout > :last-child {
    margin-bottom: 0;
}
.ws-meilisearch-rag-media__foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .5rem 1rem;
    margin-top: auto;
}
.ws-meilisearch-rag-media__access {
    display: inline-flex;
    align-items: center;
    gap: .3em;
    font-size: .85em;
    opacity: .85;
}
.ws-meilisearch-rag-media__lock {
    width: 1em;
    height: 1em;
    flex-shrink: 0;
}
