Files
AI-Studio/app/MindWork AI Studio/wwwroot/app.css
T

775 lines
23 KiB
CSS

/*
* This file is meant for global styling only: font faces, custom properties, and the overrides that
* reach into markup we do not render ourselves, such as MudBlazor internals or third-party output.
* Styling that belongs to a single component belongs next to that component in a `.razor.css` file,
* the way `Assistants/VisualBriefing/VisualBriefingAssistant.razor.css` does it.
*
* A number of component-specific blocks below do not follow that rule yet, the log viewer and the code
* editor being the largest. Moving them is not a matter of cutting and pasting: Blazor only adds the
* scope attribute to elements a component writes in its own markup, and it appends that attribute to
* the last part of a selector. Rules that target a MudBlazor component, markup injected through a
* `MarkupString`, rendered Markdown, or nodes created by JavaScript therefore stop matching once they
* are scoped. They have to be rewritten with `::deep`, which in turn needs an ancestor element the
* component itself renders. The log viewer has no such element at all today.
*
* So please do not add component-specific rules here just because a neighbouring one is already here.
* Nothing about a broken selector fails the build; it only looks wrong at runtime.
*/
/* roboto-300 - latin */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: url('fonts/roboto-v30-latin-300.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* roboto-regular - latin */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: url('fonts/roboto-v30-latin-regular.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* roboto-500 - latin */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Roboto';
font-style: normal;
font-weight: 500;
src: url('fonts/roboto-v30-latin-500.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* roboto-700 - latin */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Roboto';
font-style: normal;
font-weight: 700;
src: url('fonts/roboto-v30-latin-700.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* JetBrainsMono-Regular - latin */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 400;
src: url('fonts/JetBrainsMono-Regular.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
.mud-text-list .mud-list-item-icon {
margin-top: 4px;
}
.plugin-icon-container {
width: var(--mud-icon-size-large);
height: var(--mud-icon-size-large);
}
.plugin-icon-container img {
width: 100%;
height: 100%;
object-fit: contain;
}
.provider-icon {
width: 1.5em;
height: 1.5em;
object-fit: contain;
flex: none;
}
.mud-popover-open.InnerScrollingFix {
left: 0 !important;
}
:root {
--confidence-color: #000000;
}
.confidence-icon {
color: var(--confidence-color);
}
.confidence-border > .mud-input-control-input-container > .mud-input > .mud-input-outlined-border {
border-width: 2px;
border-color: var(--confidence-color) !important;
}
/*
* The token count under the chat input. It is a plain grey number until the conversation is near
* the model's context window, and then it says so by colour: there is nothing to do about four
* fifths of a window, and quite a lot to do about a full one.
*/
.token-budget-nearly-full .mud-input-helper-text {
color: var(--mud-palette-warning);
}
.token-budget-exceeded .mud-input-helper-text {
color: var(--mud-palette-error);
}
:root {
--custom-icon-color: #000000;
}
.custom-icon-color > a > svg {
color: var(--custom-icon-color) !important;
}
/*
WebKitGTK, the webview on Linux, leaves the zoom of the page out of the font size of an SVG
element. MudBlazor sizes its icons with 1em of that font size, so they would keep their size while
everything around them grows or shrinks with the interface size. The runtime therefore sets
--svg-icon-zoom to its zoom on Linux, see interface_zoom.rs. The webviews of Windows and macOS zoom
SVG elements like everything else, and the variable stays unset there. The :where keeps this as
weak as MudBlazor's own rule, so that every more specific size still wins.
*/
.mud-icon-root:where(svg) {
width: calc(1em * var(--svg-icon-zoom, 1));
height: calc(1em * var(--svg-icon-zoom, 1));
}
/*
MudBlazor draws the thumb of a slider as a dot of 4px, scaled up five times. Zoomed to an interface
size, the dot covers a fraction of a pixel, which the webview rounds to whole pixels before the
scaling magnifies the error: the thumb turns into an uneven shape. These rules draw the thumb in its
final size instead, with the shadows MudBlazor's scaling gave it. All sliders of the app have the
medium size and the primary color.
*/
.mud-slider.mud-slider-medium .mud-slider-input::-webkit-slider-thumb {
width: 20px;
height: 20px;
margin-top: -8px;
transform: none;
}
.mud-slider.mud-slider-medium.mud-slider-primary .mud-slider-input::-webkit-slider-thumb {
box-shadow: 0 5px 10px -5px rgba(var(--mud-palette-primary-rgb), 0.3);
}
.mud-slider.mud-slider-medium.mud-slider-primary .mud-slider-input::-webkit-slider-thumb:hover {
box-shadow: 0 5px 10px -5px rgba(var(--mud-palette-primary-rgb), 0.3), 0 0 0 5px rgba(var(--mud-palette-primary-rgb), 0.24);
}
.mud-slider.mud-slider-medium.mud-slider-primary .mud-slider-input:focus-visible::-webkit-slider-thumb,
.mud-slider.mud-slider-medium.mud-slider-primary .mud-slider-input:active::-webkit-slider-thumb {
box-shadow: 0 5px 10px -5px rgba(var(--mud-palette-primary-rgb), 0.3), 0 0 0 10px rgba(var(--mud-palette-primary-rgb), 0.24);
}
.improvedDiff .wikEdDiffFragment {
background-color: initial !important;
}
.improvedDiff .wikEdDiffNoChange {
background-color: initial !important;
}
.improvedDiff .wikEdDiffDelete {
text-decoration-line: line-through;
text-decoration-style: double;
text-decoration-color: red;
text-decoration-thickness: 2px;
}
/* Fix for MudBlazor, tooltips inside of navmenu */
.mud-navmenu .mud-tooltip-root {
display: initial !important;
}
/* MudStepperWithoutActions overrides the stepper actions with empty content. MudBlazor still renders
the action bar around them, which would leave an empty padded row below the last step. */
.mud-stepper-without-actions .mud-stepper-actions {
display: none;
}
/* Context div for inner scrolling component */
.inner-scrolling-context {
display: flex;
flex-direction: column;
height: 100vh;
}
/* Fixed MudSplitter inside context div for inner scrolling component */
.inner-scrolling-context > .mud-splitter {
flex-grow: 1;
overflow: hidden;
}
/* Fixed the slider part of MudSplitter inside context div for inner scrolling component */
.inner-scrolling-context > .mud-splitter > .mud-slider > .mud-slider-container {
padding-bottom: 12px;
}
/* Fixed the margin for the Markdown code blocks */
.mud-card-content .mud-markdown-body .hljs.mud-markdown-code-highlight {
margin-bottom:2em;
}
/* The actions of a code block, such as saving it, appear left of its copy button, which is 36px wide plus a margin of 8px */
.mud-markdown-body .code-block-with-actions {
position: relative;
}
.mud-markdown-body .code-block-actions {
position: absolute;
display: none;
top: 0;
right: 44px;
}
/* Both appear while the pointer is on the code block, and the copy button stays while it is on the actions, which are no part of the block */
.mud-markdown-body .code-block-with-actions:hover > .code-block-actions,
.mud-markdown-body .code-block-with-actions:hover .mud-markdown-code-highlight-copybtn {
display: block;
}
.justified-markdown .mud-markdown-body p,
.justified-markdown .mud-markdown-body li,
.justified-markdown .mud-markdown-body blockquote p {
text-align: justify;
hyphens: auto;
}
.justified-markdown .mud-markdown-body pre,
.justified-markdown .mud-markdown-body code,
.justified-markdown .mud-markdown-body h1,
.justified-markdown .mud-markdown-body h2,
.justified-markdown .mud-markdown-body h3,
.justified-markdown .mud-markdown-body h4,
.justified-markdown .mud-markdown-body h5,
.justified-markdown .mud-markdown-body h6,
.justified-markdown .mud-markdown-body table {
text-align: left;
}
.configuration-help-justified .mud-input-helper-text,
.configuration-help-justified .mud-form-helpertext {
text-align: justify;
hyphens: auto;
word-break: auto-phrase;
}
.code-block {
background-color: #2d2d2d;
color: #f8f8f2;
border-radius: 6px !important;
overflow: auto !important;
font-family: Consolas, "Courier New", monospace !important;
text-align: left !important;
}
.code-block pre {
margin: 0 !important;
}
.code-block code {
font-family: inherit !important;
}
.inline-code-block {
background-color: #2d2d2d;
color: #f8f8f2;
border-radius: 6px;
font-family: Consolas, "Courier New", monospace;
text-align: left;
padding: 4px 6px;
margin: 0 2px;
}
.no-elevation {
box-shadow: none !important;
}
.sources-card-header {
top: 0em !important;
left: 2.2em !important;
}
.chat-mathjax-block {
text-align: left;
}
.chat-mathjax-block mjx-container[display="true"] {
text-align: left !important;
margin-left: 0 !important;
margin-right: 0 !important;
}
.chat-mathjax-block mjx-container[display="true"] mjx-math {
margin-left: 0 !important;
margin-right: 0 !important;
}
.log-viewer-shell {
min-width: 0;
}
.log-viewer-select {
min-width: 12rem;
}
.log-viewer-number {
max-width: 9rem;
}
.log-viewer-filter {
min-width: 18rem;
max-width: 32rem;
}
.log-viewer-multiselect {
min-width: 16rem;
max-width: 34rem;
}
.log-viewer-path {
color: var(--mud-palette-text-secondary);
word-break: break-all;
}
.log-viewer-pane {
min-height: 28rem;
border: 1px solid var(--mud-palette-lines-default);
border-radius: 6px;
background-color: var(--mud-palette-background-grey);
}
.log-viewer-lines {
margin: 0;
padding: 0.5rem 0;
font-family: Consolas, "Courier New", monospace;
font-size: 0.875rem;
line-height: 1.45;
}
.log-viewer-line {
display: grid;
grid-template-columns: 5.5rem minmax(0, 1fr);
min-height: 1.25rem;
}
.log-viewer-line:hover {
background-color: var(--mud-palette-action-default-hover);
}
.log-viewer-line-number {
padding-right: 0.75rem;
color: var(--mud-palette-text-secondary);
text-align: right;
user-select: none;
border-right: 1px solid var(--mud-palette-lines-default);
}
.log-viewer-line-text {
padding-left: 0.75rem;
white-space: pre-wrap;
overflow-wrap: anywhere;
}
.log-viewer-line-error {
color: var(--mud-palette-error);
}
.log-viewer-line-warn {
color: var(--mud-palette-warning-darken);
}
.log-viewer-line-info {
color: var(--mud-palette-info);
}
.log-viewer-line-debug,
.log-viewer-line-trace {
color: var(--mud-palette-text-secondary);
}
.log-viewer-highlight {
padding: 0 2px;
border-radius: 2px;
background-color: var(--mud-palette-warning);
color: var(--mud-palette-warning-text);
}
.log-viewer-empty {
display: flex;
min-height: 20rem;
align-items: center;
justify-content: center;
gap: 0.75rem;
color: var(--mud-palette-text-secondary);
}
.code-editor {
display: grid;
grid-template-columns: minmax(2.8rem, auto) minmax(0, 1fr);
min-height: 32rem;
height: auto;
width: 100%;
overflow: hidden;
border: 3px solid var(--mw-code-editor-border, rgba(0,0,0,0.11764705882352941));
border-radius: 4px;
background: var(--mw-code-editor-background, rgba(255,255,255,1));
color: var(--mw-code-editor-foreground, rgba(66,66,66,1));
font-family: "JetBrains Mono", monospace;
font-size: 0.65rem;
line-height: 1.45;
tab-size: 4;
}
.code-editor-line-numbers {
overflow: hidden;
padding: 0.8rem 0.65rem 0.8rem 0.5rem;
border-right: 1px solid var(--mw-code-editor-border, rgba(0,0,0,0.11764705882352941));
color: var(--mw-code-editor-foreground, rgba(66,66,66,1));
opacity: 0.55;
text-align: right;
white-space: pre;
user-select: none;
font: inherit;
font-variant-numeric: tabular-nums;
}
.code-editor-input {
min-width: 0;
height: 100%;
overflow: auto;
padding: 0.8rem;
color: var(--mw-code-editor-foreground, rgba(66,66,66,1));
caret-color: var(--mw-code-editor-foreground, rgba(66,66,66,1));
font: inherit;
line-height: inherit;
tab-size: inherit;
outline: none;
}
.code-editor .lua-comment {
color: var(--mw-code-editor-comment, #6a9955);
font-style: italic;
}
.code-editor .lua-string {
color: var(--mw-code-editor-string, #a31515);
}
.code-editor .lua-number {
color: var(--mw-code-editor-number, #098658);
}
.code-editor .lua-keyword {
color: var(--mw-code-editor-keyword, #0000ff);
font-weight: 600;
}
.code-editor .lua-literal {
color: var(--mw-code-editor-literal, #0000ff);
}
.code-editor .lua-built-in {
color: var(--mw-code-editor-built-in, #795e26);
}
.code-editor .lua-constant {
color: var(--mw-code-editor-constant, #0070c1);
font-weight: 500;
}
.code-editor .lua-function {
color: var(--mw-code-editor-function, #795e26);
}
.code-editor .lua-property {
color: var(--mw-code-editor-property, #001080);
}
.code-editor .lua-variable {
color: var(--mw-code-editor-variable, #267f99);
}
/*
* Group headers of the provider tables in the settings (LLM providers, embedding providers,
* transcription providers). The rule targets the entire group row, so that the expand button
* gets the same compact padding and shading as the header cell itself.
*/
tr:has(> .provider-group-header) {
cursor: pointer;
}
tr:has(> .provider-group-header) > .mud-table-cell {
padding-top: 0.25em;
padding-bottom: 0.25em;
background-color: var(--mud-palette-background-gray);
border-top: 1px solid var(--mud-palette-lines-default);
border-bottom: 1px solid var(--mud-palette-lines-default);
}
tr:has(> .provider-group-header) .mud-icon-button {
padding: 0.15em;
}
.provider-group-header {
font-weight: 600;
}
/*
* Headers of an expansion panel which sits inside another one, such as the failure groups of a
* data source on the embeddings page. Two headers of the same size give no clue about which one
* contains the other. MudBlazor's own Dense is no help here: it takes the padding off the content,
* not off the header, whose height is fixed in the framework. Hence this rule — and it has to name
* the MudBlazor classes to outweigh their specificity.
*/
.mud-expand-panel .mud-expand-panel-header.expansion-panel-header-compact {
min-height: 2rem;
padding-top: 0.25rem;
padding-bottom: 0.25rem;
}
/*
* Rows of the tool selection which the chat and the assistants open from their footer. There will be
* far more tools than the ones we start with, so a row must not waste height: MudBlazor's settings
* button alone puts 12px of padding around a 24px icon, which makes a row 48px tall before the
* switch and the frame are counted at all. Size.Small takes most of that away; the rules below take
* the rest, and the second one has to name the MudBlazor class to outweigh its specificity.
*/
.tool-selection-rows > .tool-selection-row {
padding: 0.15rem 0.25rem;
}
.tool-selection-row .mud-icon-button {
padding: 0.2em;
}
/*
* Rows of the data source lists, in the popover next to the tool selection as well as in the
* settings dialog. A row carries a name and at most one icon, so there is no reason for it to be
* 48px tall: MudBlazor pads the item with 8px on both sides and the text slot with another 4px,
* which is more frame than content. Dense on the list halves the first part, the rule below takes
* the second one away, and it has to name the MudBlazor class to outweigh its specificity.
*/
.data-source-rows .mud-list-item-text {
margin-top: 0;
margin-bottom: 0;
}
/*
* The checkboxes MudBlazor renders into a multi-selection list come out larger than the box of the
* tool selection next to it, and MudList has no parameter for their size. So the three rules below
* state it: the 20px icon and the 4px of padding which Size.Small together with Dense produce over
* there, plus the 4px between the box and the name which the tool row takes from the spacing of its
* stack -- the list puts its checkbox outside the slot that holds our own markup, so no stack of
* ours reaches it. The icon needs a rule of its own because MudBlazor gives it an explicit font
* size, which no inherited one can outrank.
*/
.data-source-rows .mud-checkbox {
margin-inline-end: 0.25rem;
}
.data-source-rows .mud-checkbox .mud-icon-button {
padding: 0.25rem;
}
.data-source-rows .mud-checkbox .mud-icon-root {
font-size: 1.25rem;
}
/*
* The frame around a text switch in its compact form. MudBlazor pads the slot of an outlined field
* with 18.5px above and below, which is the right amount for the line of text such a field usually
* holds -- a switch of 24px is left swimming in the middle of it. Size.Small already took the switch
* down; this brings the frame with it, and it has to name the MudBlazor classes to outweigh their
* specificity. Only the two vertical values of that shorthand are replaced, so the 14px to the left
* and right stay as they are.
*/
.text-switch-dense .mud-input-slot.mud-input-root-outlined {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
}
/* A field for file patterns with its help button on the right, which keeps its width while the field grows. */
.pattern-row {
display: grid;
grid-template-columns: minmax(0, 1fr) 48px;
column-gap: 8px;
align-items: center;
}
/* The field takes the first column, and so does what follows below it, such as the help, which keeps them equally wide. */
.pattern-row-main {
grid-column: 1;
min-width: 0;
}
/*
* Pattern lists wrap and grow with their content, up to a limit beyond which they scroll. MudBlazor
* measures the height only on input, after a render with new text, and when the window changes its
* size. When the field gets narrower otherwise, e.g., in a dialog, more lines wrap than it is high,
* and MudBlazor hides the scrollbar below the limit. Allowing it always keeps every line reachable.
*/
.pattern-text-field textarea.mud-input-slot {
white-space: pre-wrap;
overflow-wrap: anywhere;
overflow-y: auto !important;
}
/*
* Dialogs whose footer carries buttons on the left as well, such as Add and Import next to Close.
* MudBlazor pads the content with 24px to the left and right, but the footer with only 8px, so the
* buttons stood out of the column of the table above them. The footer takes over the 24px. On the
* right, the content also gives up the room of its scrollbar as soon as the table grows long, and
* how wide that is depends on the operating system and its settings, down to nothing for scrollbars
* which only show while scrolling. So no fixed padding fits: the content reserves that room for good,
* and the footer reserves the very same, which scrollbar-gutter only does for an element that clips
* its overflow. The popovers of menus and tooltips live elsewhere, so the footer clips no more than
* the outermost blur of a button shadow. A web view without scrollbar-gutter keeps the old offset on
* the right only. Both rules name the MudBlazor classes to outweigh their specificity.
*/
.mud-dialog .mud-dialog-content.dialog-content-aligned {
scrollbar-gutter: stable;
}
.mud-dialog .mud-dialog-actions.dialog-actions-aligned {
padding: 8px 24px;
overflow: hidden;
scrollbar-gutter: stable;
}
/*
* One source below an answer per row. The title takes the free width and wraps, however long the
* name of the document is, while the buttons stay at the right edge, one column below the other.
* The whole row lights up under the mouse, so a button is clearly part of its row. The Markdown
* styles force every list item to stay one with !important, so the row names their classes to
* outweigh them.
*/
.mud-markdown-body li.source-entry {
display: flex !important;
align-items: center;
gap: 0.5rem;
border-radius: var(--mud-default-borderradius);
}
.source-entry:hover {
background-color: var(--mud-palette-action-default-hover);
}
.source-entry-title {
flex: 1 1 auto;
min-width: 0;
overflow-wrap: anywhere;
}
.source-entry-actions {
display: flex;
flex: none;
}
/*
* A dialog which fits the window instead of scrolling as a whole. Its content is a column which
* gives way when the window is too small, down to the one part which scrolls by itself, e.g., the
* text of a ContentViewer. Every element in between is marked dialog-fit, so that it gives way as
* well rather than holding on to the height of its content.
*/
.mud-dialog .mud-dialog-content.dialog-content-fit {
display: flex;
flex-direction: column;
overflow: hidden;
}
.dialog-fit {
display: flex;
flex-direction: column;
min-height: 0;
}
/*
* A piece of content for the user to check, see ContentViewer: a slim bar saying what it is and
* how to see it, above the content, which scrolls inside its frame. Both the viewer and its frame
* give way like a dialog-fit, so that only the content scrolls.
*/
.content-viewer,
.content-viewer-frame {
display: flex;
flex-direction: column;
min-height: 0;
}
.content-viewer-toolbar {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 0.5rem;
padding: 0.25rem 0.5rem 0.25rem 1rem;
border-bottom: 1px solid var(--mud-palette-lines-default);
}
.content-viewer-toolbar-start {
display: flex;
align-items: center;
gap: 0.25rem;
flex: 1 1 auto;
min-width: 0;
}
.content-viewer-body {
min-height: 0;
overflow-y: auto;
padding: 0.75rem 1rem;
}
.content-viewer-plain {
margin: 0;
font: inherit;
white-space: pre-wrap;
overflow-wrap: anywhere;
}
/*
* The passages the AI received from a file, see SourcePassagesDialog: the numbers of the passages
* at the side, as high as the passage next to them, and the passage, which gives way like a
* dialog-fit.
*/
.source-passages {
display: flex;
gap: 1rem;
min-height: 0;
}
.source-passages-menu {
flex: none;
width: 3.5rem;
overflow-y: auto;
}
.source-passages-menu .mud-list-item-text {
text-align: center;
}
.source-passages-content {
flex: 1 1 auto;
min-width: 0;
}
/* The title of a dialog about one file, see FileDialogTitle. */
.file-dialog-title {
display: flex;
align-items: center;
gap: 0.25rem;
overflow-wrap: anywhere;
}
/* An icon button next to text, whose icon should not outgrow the text around it. */
.mud-icon-button.icon-button-compact .mud-icon-root {
font-size: 1rem;
}
/* The warning of a file which is gone, sized and spaced like the compact buttons it stands in for. */
.mud-icon-root.file-action-warning {
font-size: 1rem;
margin: 5px;
vertical-align: middle;
}