﻿/*
    Chat window theme for AIChatComponent (the "Ask Orya" DxWindow).

    Ported from the Orya module's chat styling, deleted in 8b4eff5ae along with the module
    references. The rules were spread across three files -- orya-chat.css, orya-site.css and
    orya-form-ui.css -- and the latter two were forks of the whole app theme. Only the
    chat-scoped rules were brought across: the `.orya-container <generic-xaf-selector>` rules
    in orya-site.css styled the Orya driver app's grids, navigation and loading screens, and
    restoring those would have leaked a second app theme into Tevarai.

    `.orya-container` is kept as the root class deliberately -- the host's darkmode-overwrite.css
    still carries chat rules keyed to it. Renaming here silently drops dark-mode theming.

    Colours resolve against the tenant brand variables generated by CompanyService
    (--site-primary, --primary, --secondary, --lighttext, --midgrey, --site-lighttext), so the
    chat follows whatever palette the company is themed with.
*/

/* ---------- window chrome ---------- */


.ai-chat-header {
    display: flex;
    align-items: center;
    width: 100%;
    padding: 4px 8px;
}

.ai-chat-header-brand {
    display: flex;
    align-items: center;
    margin-right: auto;
}

.chat-header-logo {
    height: 22px;
    width: auto;
}

.fl-r {
    float: right;
}

.chat-btn-header {
    height: 26px;
    width: 26px;
    background: transparent !important;
    border: 0;
    color: currentColor;
}

span.fl-r:has(.chat-btn-header) {
    margin-left: 12px;
}

.dxbl-window > .dxbl-window-dialog > .dxbl-window-header .chat-btn-header.dx-icon-expandform:not(.dxbl-disabled):not(:disabled):hover::before {
    content: "\f170";
    color: currentColor;
    opacity: 1 !important;
    z-index: 1;
    position: relative;
    background-color: transparent;
}

.dxbl-window > .dxbl-window-dialog > .dxbl-window-header .chat-btn-header.dx-icon-close:not(.dxbl-disabled):not(:disabled):hover::before {
    content: "\f00a";
    color: currentColor;
    opacity: 1 !important;
    z-index: 1;
    position: relative;
    background-color: transparent;
}

.dxbl-window > .dxbl-window-dialog:has(.orya-container) .dxbl-window-body {
    padding: 0;
    overflow: hidden;
}

/* ---------- layout ----------

   The original rules pinned the composer with `position: fixed` and reserved room for it with
   `margin-bottom: 120px` on the window body. Those encode the old sidebar's geometry: a fixed
   position resolves against the viewport, not the window, so in a resizable/draggable window
   the composer detaches from its panel. Replaced with a flex column that keeps the composer at
   the bottom of the window whatever size it is dragged to.
*/

.orya-container {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    /* height: 100%; */
    width: 100%;
    min-height: 0;
    overflow: hidden;
    box-sizing: border-box;
}

    /*
        The port carried `margin: 0 auto` from the Orya stylesheet, where `.orya-container` was
        the app's <body> class and this was an ordinary centred block. Once `.orya-container`
        became a flex column, those auto margins changed meaning: auto cross-axis margins on a
        flex item suppress `align-items: stretch`, so the item falls back to shrink-to-fit and
        sizes to its content. That is what made the whole panel — transcript, bubbles and
        composer — collapse to the width of the longest message on a fresh conversation.
        `align-self: stretch` + an explicit width pins it to the panel instead.

        The auto margins are back, but only because `width` is now explicit: auto margins
        collapse a flex item to shrink-to-fit when its cross size is `auto`, whereas with a
        definite width they simply share out the leftover space. That keeps the transcript
        centred when the window is expanded to full screen, where a 1100px column pinned to
        the left edge leaves a dead band down the right-hand side.
    */
/*.orya-container .chat-main-container {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    align-self: stretch;
    width: 100%;
    max-width: 1100px;
    margin: 0 auto;
    padding: 12px 16px 0;
    color: currentColor;
    box-sizing: border-box;
}*/

.orya-container .ai-chat-greeting h1 {
    font-size: 1.6rem;
    font-weight: 600;
    line-height: 1.25;
    margin: 0 0 12px;
}

/* The greeting belongs to the empty state. Once a conversation starts it is just a permanent
   ~90px of dead space above the transcript, so collapse it as soon as a message exists.
   Done in CSS rather than by tracking message count in C# — DxAIChat owns that state, and
   :has() reacts to the messages it renders without the component having to observe them. */
.orya-container .chat-main-container:has(.dxbl-chatui-message) .ai-chat-greeting {
    display: none;
}

.orya-container .ai-chat-provider {
    margin-bottom: 8px;
}

.orya-container .ai-chat-provider-label {
    display: block;
    margin-bottom: 4px;
    font-size: 0.8125rem;
    font-weight: 600;
    opacity: 0.75;
}

.orya-container .ai-chat-provider-combo {
    max-width: 260px;
}

/* The chat surface takes the remaining height; min-height:0 lets it actually shrink inside the
   flex column instead of forcing the window to overflow. */
.orya-container .orya-chat-window {
    flex: 1 1 auto;
    min-height: 0;
}

/*
    The theme's `.dxbl-chatui-root` rule declares CSS custom properties only — no display, no
    width, no height. So the element shrink-wraps its content, and everything below it inherits
    that width: the transcript, the bubbles and the composer all resize to whatever the widest
    message happens to be. Forcing the root to a full-width flex column fixes the whole subtree.

    Both selectors are listed because the CssClass may land on the root element itself rather
    than a wrapper around it — matching on `.chat-main-container` as the ancestor holds either
    way, and the rule is idempotent if both resolve to the same node.
*/
.orya-container .chat-main-container .dxbl-chatui-root,
.orya-container .orya-chat-window {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    width: 100%;
    min-height: 0;
    box-sizing: border-box;
}

/* `.dxbl-chatui` already ships flex/column/height:100% in the theme; it only needs to stop
   inheriting a shrink-wrapped width. */
.orya-container .chat-main-container .dxbl-chatui {
    width: 100%;
    min-height: 0;
}

.orya-container .chat-main-container .dxbl-chatui .dxbl-chatui-messages {
    flex: 1 1 auto;
    min-height: 360px;
    /* overflow-y: auto; */
	height: calc(100% - 110px);
}

.orya-container .chat-main-container .dxbl-chatui .dxbl-chatui-submitarea {
    flex: 0 0 auto;
    width: 100%;
    box-sizing: border-box;
}

.orya-container .ai-chat-empty {
    padding: 8px 0;
    opacity: 0.65;
    font-size: 0.9375rem;
}

.orya-container .chat-header-username {
    font-weight: 700;
    /* CurrentUserName is the login name, which is commonly an email — keep a long one from
       wrapping the greeting onto a third line. */
    overflow-wrap: anywhere;
}

.orya-container .chat-header-gradient {
    background: linear-gradient(to right, var(--site-primary), var(--site-secondary), var(--site-primary), var(--site-secondary));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    color: transparent;
}

/* ---------- message bubbles ---------- */

.orya-container .chat-main-container .dxbl-chatui-root .dxbl-chatui {
    background: transparent;
}

.orya-container .chat-main-container .dxbl-chatui-root .dxbl-chatui .dxbl-chatui-messages {
    background-color: transparent !important;
    border-radius: 20px;
}

.orya-container .chat-main-container .dxbl-chatui-root.dxbl-chatui-emptystate .dxbl-chatui .dxbl-chatui-messages {
    background: transparent;
    color: currentColor;
}

.orya-container .chat-main-container .dxbl-chatui-root .dxbl-chatui .dxbl-chatui-messages .dxbl-chatui-message.dxbl-chatui-message-user {
    background: linear-gradient(to right, rgba(var(--primary), 0.10), rgba(var(--primary), 0.25)) !important;
    color: currentColor;
    border-radius: 10px;
    padding: 20px;
    max-width: 85%;
    /* The port carried a `min-width: 50%` here, which blew a five-character "hello" up into a
       half-panel block. Bubbles hug their content instead; re-add the min-width if the wide
       user bubble was deliberate. */
    width: fit-content;
    align-self: end;
    box-shadow: inset 0 2px 2px 0 rgba(var(--primary), 0.25);
    word-wrap: break-word;
}

.orya-container .chat-main-container .dxbl-chatui-root .dxbl-chatui .dxbl-chatui-messages .dxbl-chatui-message.dxbl-chatui-message-assistant {
    background: linear-gradient(to right, rgba(var(--secondary), 0.30), rgba(var(--secondary), 0.10)) !important;
    color: currentColor;
    border-radius: 10px;
    padding: 20px;
    max-width: 85%;
    /* The theme gives assistant bubbles `min-width: 100%`, which would beat the max-width above
       and stretch every reply to the full transcript. */
    min-width: 0;
    box-shadow: inset 0 2px 2px 0 rgba(var(--secondary), 0.25);
}

.orya-container .chat-main-container .dxbl-chatui-root .dxbl-chatui .dxbl-chatui-messages .dxbl-chatui-message.dxbl-chatui-message-error {
    background: rgba(var(--danger), 0.12) !important;
    color: currentColor;
    border-radius: 10px;
    padding: 20px;
    max-width: 85%;
}

.orya-container .chat-main-container .chat-content > *:first-child {
    margin-top: 0;
}

.orya-container .chat-main-container .chat-content > *:last-child {
    margin-bottom: 0;
}

/* ---------- tables ----------
   Model answers routinely include a Markdown pipe table (route status, etc.). The bubble is a
   fixed ~550px panel, so a wide table must scroll inside its own bubble rather than stretch the
   transcript: `display: block` + `width: max-content` + `max-width: 100%` lets the table take its
   natural width up to the bubble edge, then `overflow-x: auto` gives it its own horizontal
   scrollbar. Colours reuse the same rgba(var(--…)) tokens as the bubble rules above, so they
   follow the theme without a separate dark-mode block. */
.orya-container .chat-main-container .chat-content table {
    display: block;
    width: max-content;
    max-width: 100%;
    overflow-x: auto;
    border-collapse: collapse;
    margin: 8px 0;
    font-size: 0.85rem;
}

.orya-container .chat-main-container .chat-content th,
.orya-container .chat-main-container .chat-content td {
    border: 1px solid rgba(var(--midgrey), 0.35);
    padding: 6px 10px;
    text-align: left;
    white-space: nowrap;
}

.orya-container .chat-main-container .chat-content thead th {
    background: rgba(var(--secondary), 0.25);
    font-weight: 600;
}

.orya-container .chat-main-container .chat-content tbody tr:nth-child(even) td {
    background: rgba(var(--secondary), 0.08);
}

.orya-container .chat-main-container .chat-link {
    text-decoration: none;
    margin-right: 10px;
}

.orya-container .chat-main-container .chat-link:hover {
    text-decoration: underline;
}

/* ---------- composer ---------- */

.orya-container .chat-main-container .dxbl-chatui-root .dxbl-chatui .dxbl-chatui-submitarea {
    background: transparent;
    padding: 10px 0;
}

.orya-container .chat-main-container .dxbl-chatui-root .dxbl-chatui .dxbl-chatui-submitarea .dxbl-chatui-submitarea-container {
    border-radius: 5px;
    background-color: rgba(var(--lighttext), 0.15);
    border-color: rgba(var(--midgrey), 0.25);
    box-shadow: 0 6px 6px 0 rgba(0, 0, 0, 0.1);
    transition: 0.3s;
}

.orya-container .chat-main-container .dxbl-chatui-root .dxbl-chatui .dxbl-chatui-submitarea .dxbl-chatui-submitarea-container:has(textarea:focus) {
    background-color: rgba(var(--lighttext), 0.20);
    box-shadow: inset 0 1px 2px 0 rgba(0, 0, 0, 0.1);
    border-color: rgba(var(--midgrey), 0.95);
    transition: 0.3s;
}

.orya-container .chat-main-container dxbl-memo-editor {
    background: transparent;
    padding: 5px 10px;
    box-shadow: none !important;
}

/*
    The composer opened at roughly three rows tall, leaving a block of dead space above the send
    button for what is usually a one-line prompt. Constrained to start at one row and grow to a
    ceiling, after which it scrolls rather than pushing the transcript off the panel.

    Matched on the `textarea` element rather than a DevExpress class: the element is stable
    across component versions, the internal class names are not.
*/
.orya-container .chat-main-container .dxbl-chatui-submitarea textarea {
    min-height: 1.5rem;
    max-height: 7.5rem;
    resize: none;
}

.orya-container .chat-main-container .dxbl-text-edit.dxbl-memo-edit.dxbl-memo-edit-has-buttons .dxbl-memo-edit-buttons-area .dxbl-btn-group > .dxbl-btn.dxbl-btn-primary {
    color: var(--site-lighttext);
    width: 28px;
    height: 28px;
}

.orya-container .chat-main-container .dxbl-text-edit.dxbl-memo-edit.dxbl-memo-edit-has-buttons .dxbl-memo-edit-buttons-area .dxbl-btn-group > .dxbl-btn,
.orya-container .chat-main-container .dxbl-chatui-root .dxbl-chatui .dxbl-chatui-messages .dxbl-chatui-message .dxbl-chat-message-button {
    background: var(--site-primary) !important;
    background-image: none;
    color: white !important;
    border: 0;
    opacity: 0.6;
    border-radius: 20px !important;
    margin: 4px;
}

.orya-container .chat-main-container .dxbl-text-edit.dxbl-memo-edit.dxbl-memo-edit-has-buttons .dxbl-memo-edit-buttons-area .dxbl-btn-group > .dxbl-btn:hover,
.orya-container .chat-main-container .dxbl-chatui-root .dxbl-chatui .dxbl-chatui-messages .dxbl-chatui-message .dxbl-chat-message-button:hover {
    opacity: 0.9;
}

/* Orya-branded send button. */
.orya-chat-window .dxbl-text-edit-btn {
    transition: 0.5s;
}

.orya-chat-window .dxbl-text-edit-btn .dxbl-image .dxbl-icon-set-default {
    display: none;
}

.orya-chat-window .dxbl-text-edit-btn .dxbl-image {
    background-image: url('/images/Orya-icon-white.png');
    background-size: 16px 16px;
    background-repeat: no-repeat;
    background-position: center;
    /* The port sized this image 40x40 while the sibling rule sizes the button itself 28x28, so
       the image was setting the button area's height and padding the composer out. Matched to
       the button. */
    width: 28px;
    height: 28px;
    transform: rotate(0deg);
    transition: 0.5s;
}

.orya-chat-window .dxbl-text-edit-btn:hover .dxbl-image {
    animation: logo-spin 1s linear infinite;
    transition: 0.5s;
}

/* ---------- prompt suggestions ---------- */

.orya-container .chat-main-container .dxbl-chatui-prompt-suggestions {
    display: block !important;
    width: 100%;
}

.orya-container .chat-main-container .dxbl-chatui-root .dxbl-chatui .dxbl-chatui-messages .dxbl-chatui-prompt-suggestions .dxbl-chatui-prompt-suggestion {
    width: calc(50% - 20px);
    max-width: 100%;
    margin: 10px 10px 0 0;
    display: inline-block !important;
    border-radius: 10px;
    background-color: rgba(var(--lighttext), 0.5);
    border-color: rgba(var(--midgrey), 0.25);
    box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.1);
    transition: 0.3s;
}

.orya-container .chat-main-container .dxbl-chatui-root .dxbl-chatui .dxbl-chatui-messages .dxbl-chatui-prompt-suggestions .dxbl-chatui-prompt-suggestion:hover {
    background-color: rgba(var(--lighttext), 0.75);
    box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.1) !important;
    border-color: rgba(var(--midgrey), 0.75);
    transition: 0.3s;
}

.orya-container .chat-main-container .dxbl-chatui-root .dxbl-chatui .dxbl-chatui-messages .dxbl-chatui-prompt-suggestions .dxbl-chatui-prompt-suggestion .dxbl-chatui-prompt-suggestion-title {
    margin-bottom: 20px;
    color: currentColor;
}

/* ---------- "thinking" indicator ----------

   DxAIChat renders the typing indicator itself — a <DxWaitIndicator> emitted inside the message
   bubble — and exposes no template for it. It cannot be produced from MessageContentTemplate
   either: DxAIChatMessage skips the whole message text slot, and with it that template, while a
   typing message's text is still empty. The stock spinner is restyled into the Orya pill instead.

   `:not(.dxbl-chatui-message-loading-indicator)` leaves the separate ShowLoadingIndicatorAsync
   indicator on the default spinner, and `:only-child` keeps the pill off a bubble that also
   carries the tool-call accordion — that bubble holds real content and stays a normal bubble.

   The label comes from --ai-chat-thinking, set on .orya-container from the RESX resource: the
   stylesheet must not hardcode a user-facing string it cannot localize.

   The pill sits inside an assistant bubble, as it did when it was authored in markup. The bubble
   element itself has to become the pill — it is the only box that can hold both the label and the
   dots — so the message container stands in as the surrounding bubble for the duration. */

.orya-container .chat-main-container .dxbl-chatui-root .dxbl-chatui .dxbl-chatui-messages .dxbl-chatui-message-container:has(> .dxbl-chatui-message-assistant > .dxbl-wait-indicator:not(.dxbl-chatui-message-loading-indicator):only-child) {
    display: block;
    align-self: start;
    width: fit-content;
    max-width: 85%;
    padding: 20px;
    border-radius: 10px;
    background: linear-gradient(to right, rgba(var(--secondary), 0.30), rgba(var(--secondary), 0.10));
    box-shadow: inset 0 2px 2px 0 rgba(var(--secondary), 0.25);
}

.orya-container .chat-main-container .dxbl-chatui-root .dxbl-chatui .dxbl-chatui-messages .dxbl-chatui-message.dxbl-chatui-message-assistant:has(> .dxbl-wait-indicator:not(.dxbl-chatui-message-loading-indicator):only-child) {
    /* flex-direction and wrapping are set explicitly: the theme lays message bubbles out as a
       column, which stacked the label above the dots. */
    display: inline-flex;
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: center;
    gap: 4px;
    width: fit-content;
    min-width: 0;
    padding: 3px 10px;
    border-radius: 20px;
    font-weight: 700;
    white-space: nowrap;
    color: var(--site-lighttext);
    background: linear-gradient(60deg, #f79533, #f37055, #ef4e7b, #a166ab, #5073b8, #1098ad, #07b39b, #6fba82) !important;
    background-size: 400% 400% !important;
    box-shadow: none;
    animation: thinking-bg 3s ease alternate infinite;
}

.orya-container .chat-main-container .dxbl-chatui-root .dxbl-chatui .dxbl-chatui-messages .dxbl-chatui-message.dxbl-chatui-message-assistant:has(> .dxbl-wait-indicator:not(.dxbl-chatui-message-loading-indicator):only-child)::before {
    /* Empty fallback on purpose: if the custom property ever fails to reach the page the dots
       still animate, rather than an untranslated English literal shipping from the stylesheet. */
    content: var(--ai-chat-thinking, "");
}

/* The three bouncing dots come from the indicator's own box: ::before, the emptied spinner <svg>,
   and ::after — the control gives no other element to hang them on. */
.orya-container .dxbl-chatui-message-assistant > .dxbl-wait-indicator:not(.dxbl-chatui-message-loading-indicator):only-child {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    width: 30px !important;
    height: auto;
    animation: none;
}

.orya-container .dxbl-chatui-message-assistant > .dxbl-wait-indicator:not(.dxbl-chatui-message-loading-indicator):only-child::before,
.orya-container .dxbl-chatui-message-assistant > .dxbl-wait-indicator:not(.dxbl-chatui-message-loading-indicator):only-child::after {
    content: "";
}

.orya-container .dxbl-chatui-message-assistant > .dxbl-wait-indicator:not(.dxbl-chatui-message-loading-indicator):only-child::before,
.orya-container .dxbl-chatui-message-assistant > .dxbl-wait-indicator:not(.dxbl-chatui-message-loading-indicator):only-child > svg,
.orya-container .dxbl-chatui-message-assistant > .dxbl-wait-indicator:not(.dxbl-chatui-message-loading-indicator):only-child::after {
    flex: 0 0 auto;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background-color: var(--site-lighttext);
    opacity: 0.4;
    animation: bounceDot 1.2s infinite ease-in-out;
}

/* The spinner artwork is hidden rather than the <svg> itself, which is reused as the middle dot. */
.orya-container .dxbl-chatui-message-assistant > .dxbl-wait-indicator:not(.dxbl-chatui-message-loading-indicator):only-child > svg * {
    display: none;
}

.orya-container .dxbl-chatui-message-assistant > .dxbl-wait-indicator:not(.dxbl-chatui-message-loading-indicator):only-child::before 
{ animation-delay: 0s; }
.orya-container .dxbl-chatui-message-assistant > .dxbl-wait-indicator:not(.dxbl-chatui-message-loading-indicator):only-child > svg 
{ animation-delay: 0.2s; }
.orya-container .dxbl-chatui-message-assistant > .dxbl-wait-indicator:not(.dxbl-chatui-message-loading-indicator):only-child::after 
{ animation-delay: 0.4s; }

/* Keep the "model unavailable" toast above the chat window. */
.ai-chat-toast {
    z-index: 100000 !important;
}

/* ---------- keyframes (referenced above; also deleted with the Orya stylesheets) ---------- */

@keyframes logo-spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

@keyframes thinking-bg {
    0% { background-position: 0% 50%; }
    50% { background-position: 100% 50%; }
    100% { background-position: 0% 50%; }
}

@keyframes bounceDot {
    0% { transform: translateY(0); opacity: 0.4; }
    25% { transform: translateY(-4px); opacity: 1; }
    50% { transform: translateY(0); opacity: 0.4; }
    100% { transform: translateY(0); opacity: 0.4; }
}
