Files
textgen/css/main.css

2793 lines
62 KiB
CSS
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
:root {
/* Legacy hue-named tokens (still referenced elsewhere). */
--darker-gray: #1C1C1D;
--dark-gray: #212125;
--light-gray: #2C2E34;
--light-theme-gray: #f0f3fb;
--border-color-dark: rgba(255, 255, 255, 0.10);
--header-width: 112px;
--selected-item-color-dark: #282930;
/* Role-based design tokens (light mode defaults).
Blue-leaning grays. The rail is one step darker than
the sidebar so the two read as distinct elevations. */
--bg-body: #ffffff;
--bg-rail: #e4e8f0;
--bg-sidebar: #f0f3fb;
--bg-input: #f3f4f6;
--bg-elevated: #ffffff;
--bg-hover: #dbeafe;
--bg-active: #c8d8f5;
--text: #1a1a1a;
--text-muted: #6b6b73;
--border: rgba(0, 0, 0, 0.10);
--border-soft: rgba(0, 0, 0, 0.06);
--accent: #4a72ff;
--radius-sm: 6px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-xl: 16px;
--space-1: 4px;
--space-2: 8px;
--space-3: 12px;
--space-4: 16px;
--space-5: 24px;
--motion: 0.15s ease;
--motion-slow: 0.2s ease;
}
.dark {
--bg-body: #212125;
--bg-rail: #161617;
--bg-sidebar: #1a1a1c;
--bg-input: #2c2e34;
--bg-elevated: #1d1d1f;
--bg-hover: #2a2a2c;
--bg-active: #303033;
--text: #ececec;
--text-muted: #a3a3a8;
--border: rgba(255, 255, 255, 0.10);
--border-soft: rgba(255, 255, 255, 0.06);
--accent: #4a72ff;
}
@font-face {
font-family: Inter;
src: url('file/css/Inter/Inter-VariableFont_opsz,wght.ttf') format('truetype');
font-weight: 100 900;
font-style: normal;
}
@font-face {
font-family: Inter;
src: url('file/css/Inter/Inter-Italic-VariableFont_opsz,wght.ttf') format('truetype');
font-weight: 100 900;
font-style: italic;
}
body,
.gradio-container,
gradio-app {
font-family: 'Inter', 'Noto Sans', ui-sans-serif, system-ui, -apple-system,
'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
}
/* Hide spin buttons on number inputs (look bad on Windows) */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type="number"] {
-moz-appearance: textfield;
}
.padded.svelte-12cmxck {
padding: 3px 0;
}
div.svelte-sfqy0y,
div.svelte-iyf88w {
background: transparent;
border: 0;
}
/* "info" messages without a title above */
.block > .svelte-e8n7p6:not(:only-of-type, #chat-mode *) {
margin-bottom: 0;
}
.py-6 {
padding-top: 2.5rem
}
.small-button {
min-width: 0 !important;
max-width: 171px;
height: 39.594px;
align-self: end;
}
.refresh-button {
max-width: none;
min-width: 2.2em !important;
height: 39.594px;
align-self: end;
line-height: 1em;
border-radius: 0.75rem;
flex: none;
}
.gradio-container .stretch:has(> .refresh-button):has([role="listbox"]) {
gap: 8px;
}
.refresh-button-medium {
max-width: 4.4em;
}
.refresh-button-small {
max-width: 2.2em;
}
.settings-button {
width: fit-content !important;
min-width: 0 !important;
max-width: 100% !important;
align-self: flex-start;
}
.button_nowrap {
white-space: nowrap;
}
#slim-column {
flex: none !important;
min-width: 0 !important;
}
.slim-dropdown {
background-color: transparent !important;
border: none !important;
padding: 0 !important;
}
.slim-textbox {
padding: 0 !important;
}
#download-label, #upload-label {
min-height: 0
}
.dark a {
color: white !important;
}
ol li p, ul li p {
display: inline-block;
}
#notebook-parent-tab, #chat-tab, #parameters, #chat-settings, #lora, #training-tab, #model-tab, #session-tab, #character-tab, #image-ai-tab {
border: 0;
}
#notebook-parent-tab, #parameters, #chat-settings, #lora, #training-tab, #model-tab, #session-tab, #character-tab, #image-ai-tab {
padding: 1rem;
}
.gradio-container {
max-width: 100% !important;
padding-top: 0 !important;
}
#extensions {
margin: 5px auto 35px;
max-width: 880px;
padding: 1em;
padding-left: calc(var(--header-width) + 1em);
}
.extension-tab {
border: 0 !important;
}
span.math.inline {
font-size: 27px;
vertical-align: baseline !important;
}
gradio-app > :first-child {
padding: 0 !important;
}
.header_bar {
border-right: none;
margin-bottom: 0;
overflow-x: scroll;
text-wrap: nowrap;
z-index: 90;
position: fixed;
display: flex !important;
flex-direction: column;
height: 100dvh;
width: var(--header-width);
}
.header_bar button {
margin: 0;
padding: 0.75rem;
border-radius: 0 !important;
transition: background-color var(--motion), color var(--motion);
}
.header_bar button:hover {
background-color: var(--bg-hover);
}
.header_bar button.selected {
border: 0;
border-radius: 0;
}
.dark .header_bar {
border: none !important;
box-shadow: none;
background-color: var(--bg-rail);
}
.textbox_default textarea {
height: calc(100dvh - 202px);
}
.textbox_default_output textarea {
height: calc(100dvh - 126px);
}
.textbox textarea {
height: calc(100dvh - 153px)
}
.textbox_logits textarea {
height: calc(100dvh - 213px);
}
.textbox_logits_notebook textarea {
height: calc(100dvh - 229px);
}
.monospace textarea {
font-family: monospace;
}
.textbox_default textarea,
.textbox_default_output textarea,
.textbox_logits textarea,
.textbox_logits_notebook textarea,
.textbox textarea {
font-size: 16px !important;
color: #46464A !important;
}
.dark textarea {
color: #efefef !important;
}
/* Hide the gradio footer */
footer {
display: none !important;
}
button {
font-size: 14px !important;
}
.file-saver {
position: fixed !important;
height: 100%;
z-index: 1000;
background-color: rgb(0 0 0 / 50%) !important;
margin-left: -20px;
margin-right: -20px;
}
.file-saver > :first-child {
position: fixed !important;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); /* center horizontally */
width: 100%;
max-width: 500px;
background-color: var(--input-background-fill);
border: var(--input-border-width) solid var(--input-border-color) !important;
padding: 10px;
}
.file-saver > :first-child > :last-child {
background: var(--block-background-fill);
justify-content: flex-end;
}
.checkboxgroup-table label {
background: none !important;
padding: 0 !important;
border: 0 !important;
}
.checkboxgroup-table div {
display: grid !important;
}
.markdown ul ol {
font-size: 100% !important;
}
.pretty_scrollbar::-webkit-scrollbar,
#image-history-gallery > :nth-child(2)::-webkit-scrollbar {
width: 7px;
height: 7px;
}
.pretty_scrollbar::-webkit-scrollbar-track,
#image-history-gallery > :nth-child(2)::-webkit-scrollbar-track {
background: transparent;
}
.pretty_scrollbar::-webkit-scrollbar-thumb,
.pretty_scrollbar::-webkit-scrollbar-thumb:hover,
#image-history-gallery > :nth-child(2)::-webkit-scrollbar-thumb,
#image-history-gallery > :nth-child(2)::-webkit-scrollbar-thumb:hover {
background: var(--neutral-300);
border-radius: 9999px;
}
.dark .pretty_scrollbar::-webkit-scrollbar-thumb,
.dark .pretty_scrollbar::-webkit-scrollbar-thumb:hover,
.dark #image-history-gallery > :nth-child(2)::-webkit-scrollbar-thumb,
.dark #image-history-gallery > :nth-child(2)::-webkit-scrollbar-thumb:hover {
background: rgb(255 255 255 / 6.25%);
border-radius: 9999px;
}
.pretty_scrollbar::-webkit-resizer,
#image-history-gallery > :nth-child(2)::-webkit-resizer {
background: transparent;
}
.dark .pretty_scrollbar::-webkit-resizer,
.dark #image-history-gallery > :nth-child(2)::-webkit-resizer {
background: transparent;
}
.pretty_scrollbar::-webkit-scrollbar-corner,
#image-history-gallery > :nth-child(2)::-webkit-scrollbar-corner {
background: transparent;
}
audio {
max-width: 100%;
}
/* Copied from https://github.com/AUTOMATIC1111/stable-diffusion-webui */
#default-token-counter, #notebook-token-counter {
position: absolute !important;
z-index: 100;
background: var(--input-background-fill) !important;
min-height: 0 !important;
width: 0;
text-align: left;
direction: rtl;
right: 13px;
}
#default-token-counter {
top: calc(100dvh - 200px) !important;
}
#notebook-token-counter {
top: calc(100dvh - 180px) !important;
}
#default-token-counter span, #notebook-token-counter span {
padding: 1px;
box-shadow: 0 0 0 0.3em rgb(192 192 192 / 15%), inset 0 0 0.6em rgb(192 192 192 / 7.5%);
border: 2px solid rgb(192 192 192 / 40%) !important;
border-radius: 0.4em;
}
.no-background {
background: transparent;
padding: 0 !important;
}
/* ----------------------------------------------
Chat tab
---------------------------------------------- */
.h-\[40dvh\] {
height: 66.67dvh
}
.gradio-container {
margin-left: auto !important;
margin-right: auto !important;
}
.w-screen {
width: unset
}
.pending.svelte-1ed2p3z {
opacity: 1;
}
#chat-tab {
padding: 0;
}
#chat-tab > :nth-child(1) {
display: flex;
flex-direction: row;
gap: 0;
}
#chat-tab button, #notebook-tab button, #default-tab button {
min-width: 0 !important;
}
#chat-tab > :first-child, #extensions {
margin-left: auto;
margin-right: auto;
}
@media screen and (width <= 688px) {
#chat-tab {
padding-left: 0;
padding-right: 0;
}
.chat {
padding-left: 0;
padding-right: 0;
}
}
.chat {
margin-left: auto;
margin-right: auto;
flex: 1;
overflow-y: hidden;
display: flex;
flex-direction: column;
word-break: break-word;
overflow-wrap: anywhere;
border-top: none;
border-radius: 0;
visibility: visible;
}
.chat-parent {
flex: 1;
overflow: auto !important;
border-radius: 0 !important;
margin-bottom: 8px;
}
.chat-parent .prose {
visibility: visible;
}
.chat .message {
margin-left: auto;
margin-right: auto;
text-align: start;
padding-left: 1rem;
padding-right: 1rem;
contain: layout paint;
}
.message,
.user-message,
.assistant-message {
contain: layout paint;
animation: fadeIn 0.2s ease-out;
}
.chat .message .timestamp {
font-size: 0.7em;
display: inline-block;
font-weight: normal;
opacity: 0.7;
margin-left: 5px;
}
.chat > .messages {
display: flex;
flex-direction: column;
min-height: calc(100dvh - 225px);
}
.chat > .messages > :first-child {
padding-top: 20px;
}
.chat > .messages > .message:last-child {
padding-bottom: 2rem;
}
.message-body {
font-size: 16px;
}
.dark .message-body h1,
.dark .message-body h2,
.dark .message-body h3,
.dark .message-body h4,
.dark .message-body h5,
.dark .message-body h6 {
color: #e8e8e8 !important;
}
.message-body blockquote {
border-left-width: 4px;
border-left-color: var(--border-color-primary);
}
.message-body h1,
.message-body h2,
.message-body h3,
.message-body h4,
.message-body h5,
.message-body h6 {
color: #1a1a1a;
}
.message-body h1 {
font-weight: 700;
font-size: 2.25em;
margin-top: 0;
margin-bottom: 0.8888889em;
line-height: 1.1111111;
}
.message-body h2 {
font-weight: 700;
font-size: 1.5em;
margin-top: 2em;
margin-bottom: 1em;
line-height: 1.3333333;
}
.message-body h3 {
font-weight: 600;
font-size: 1.25em;
margin-top: 1.6em;
margin-bottom: 0.6em;
line-height: 1.6;
}
.message-body h4 {
font-weight: 600;
font-size: 1em;
margin-top: 1.5em;
margin-bottom: 0.5em;
line-height: 1.5;
}
.message-body h5 {
font-weight: 600;
font-size: 1em;
margin: 0;
}
.message-body h6 {
font-weight: 600;
font-size: 1em;
margin: 0;
}
.dark .message q {
color: #f5b031;
}
.message q {
color: #3480be;
}
.message-body q::before, .message-body q::after {
content: "";
}
.message-body li {
list-style-position: outside;
margin-top: 0.5em !important;
margin-bottom: 0.5em !important;
}
.message-body ul.long-list > li,
.message-body ol.long-list > li {
margin-top: 1.25em !important;
margin-bottom: 1.25em !important;
}
.message-body a {
font-weight: 500;
}
.chat .message-body ul, .chat .message-body ol {
padding-inline-start: 2em;
}
.message-body li > p {
display: inline !important;
}
.message-body ul {
list-style-type: disc !important;
}
.message-body pre:not(:last-child) {
margin-bottom: 35.625px !important;
}
.message-body pre:last-child {
margin-bottom: 0 !important;
}
#default-tab .prose pre, #notebook-tab .prose pre {
overflow: scroll;
}
.prose ul ul {
margin: 0;
}
.message-body pre > code {
white-space: pre !important;
overflow-x: auto !important;
max-width: calc(100dvw - 39px);
border: 1px solid #666;
border-radius: 5px;
font-size: 82%;
padding: 1px 3px;
background: #f3f4f6 !important;
color: #1f2328;
scrollbar-width: thin;
scrollbar-color: var(--neutral-300) transparent;
}
.dark .message-body pre > code {
background: #0d1117 !important;
color: rgb(201 209 217);
scrollbar-color: rgb(255 255 255 / 6.25%) transparent;
}
.message-body pre > code {
display: block;
padding: 15px;
}
.message-body :not(pre) > code {
white-space: normal !important;
font-weight: bold;
font-size: 0.95em;
font-family: Menlo,"Roboto Mono","Courier New",Courier,monospace,Inter,sans-serif;
padding: .15rem .3rem;
background-color: #ececec;
}
.dark .message-body :not(pre) > code {
background-color: rgb(255 255 255 / 10%);
}
#chat-input {
padding: 0;
background: transparent;
border: none;
}
#chat-input textarea {
background: var(--bg-input);
padding: 0.675rem 2.5rem 0.6rem;
margin-top: 0.15rem;
border: 1px solid var(--border);
border-radius: 1.5rem;
overflow-y: auto !important;
}
#chat-input textarea::-webkit-scrollbar {
width: 7px;
}
#chat-input textarea::-webkit-scrollbar-track {
background: transparent;
}
#chat-input textarea::-webkit-scrollbar-thumb {
background: var(--neutral-300);
border-radius: 9999px;
}
.dark #chat-input textarea::-webkit-scrollbar-thumb {
background: rgb(255 255 255 / 6.25%);
}
#chat-input textarea::placeholder {
white-space: nowrap;
overflow: hidden;
color: #9ca3af !important;
opacity: 1 !important;
}
#chat-input textarea:focus {
box-shadow: none !important;
}
#chat-input > :first-child {
background-color: transparent;
}
#chat-input .progress-text {
display: none;
}
#chat-input .submit-button {
display: none;
}
#chat-input .upload-button {
margin-right: 16px;
margin-bottom: 7px;
background: transparent;
}
@media print {
body {
visibility: hidden;
}
.chat {
visibility: visible;
position: absolute;
left: 0;
top: 0;
max-width: unset;
max-height: unset;
width: 100%;
overflow-y: visible;
}
.message {
break-inside: avoid;
}
.gradio-container {
overflow: visible;
}
.tab-nav {
display: none !important;
}
#chat-tab > :first-child {
max-width: unset;
}
}
#chat-tab .generating {
display: none !important;
}
.hover-element {
position: relative;
padding-top: 4px;
}
#hover-element-button {
display: flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
border-radius: 0.5rem;
cursor: pointer;
color: gray;
}
#hover-element-button:hover {
background-color: var(--background-fill-secondary);
}
#hover-element-button svg {
color: inherit;
}
.dark #hover-element-button:hover {
background-color: var(--selected-item-color-dark);
}
.hover-menu {
display: none;
position: absolute;
bottom: 100%;
left: 0;
background: white;
border: 1px solid rgba(0, 0, 0, 0.1);
box-shadow: 0 4px 16px rgb(0 0 0 / 12%), 0 1px 3px rgb(0 0 0 / 8%);
border-radius: 0.75rem;
z-index: 10000;
min-width: 330px;
flex-direction: column;
padding: 4px;
}
.hover-menu::before {
content: '';
position: absolute;
top: 100%;
left: 0;
width: 100%;
height: 8px;
}
.hover-menu > * {
border: none !important;
box-shadow: none !important;
}
.hover-menu button {
width: 100%;
background: transparent !important;
border: none !important;
border-radius: 0.5rem !important;
justify-content: space-between;
margin: 0 !important;
height: 36px;
font-weight: 500;
box-shadow: none !important;
}
.hover-menu button:hover {
background: #dbeafe !important;
}
.dark .hover-menu button:hover {
background: var(--selected-item-color-dark) !important;
}
#show-controls {
background-color: transparent;
border: none !important;
height: 36px;
border-radius: 0.5rem;
padding-top: 3px;
padding-left: 4px;
display: flex;
font-weight: normal;
}
#show-controls:hover {
background-color: #dbeafe;
}
.dark #show-controls {
background-color: transparent;
}
#show-controls label {
display: flex;
flex-direction: row-reverse;
justify-content: start;
width: 100%;
padding-right: 12px;
gap: 10px;
font-weight: 500;
font-size: 14px;
color: var(--button-secondary-text-color);
}
#show-controls label span {
color: inherit;
}
#show-controls label input {
margin-top: 5px;
}
.transparent-substring {
opacity: 0.333;
}
#chat-tab #chat-buttons {
display: none !important;
}
#gr-hover-container {
min-width: 0 !important;
display: flex;
flex-direction: column-reverse;
padding-right: 20px;
padding-bottom: 3px;
flex-grow: 0 !important;
}
#generate-stop-container {
min-width: 0 !important;
display: flex;
flex-direction: column-reverse;
padding-bottom: 3px;
flex: 0 auto !important;
}
#chat-input-container {
display: flex;
flex-direction: column;
min-width: 0 !important;
}
#chat-input-container > .form {
background: transparent;
border: none;
}
#chat-input-row {
padding: 0.5rem 1rem 1rem;
}
#chat-col {
height: 100dvh;
display: flex;
flex-direction: column;
padding-bottom: 0;
gap: 0;
}
@media screen and (width <= 924px) {
#chat-col {
margin-top: 32px;
height: calc(100dvh - 32px);
}
}
.message-body p, .message-body li {
line-height: 1.75 !important;
}
.message-body p, .message-body ul, .message-body ol {
margin: 1.25em 0 !important;
}
.message-body :is(p, ul, ol):first-child {
margin-top: 0 !important;
}
.message-body :is(p, ul, ol):last-child {
margin-bottom: 0 !important;
}
/* ----------------------------------------------
Past chats menus
---------------------------------------------- */
#rename-row label {
margin-top: 0;
}
#rename-row > :nth-child(2) {
justify-content: center;
}
/* ----------------------------------------------
Create the sidebars
---------------------------------------------- */
#chat-controls,
#past-chats-row {
width: 260px;
max-width: 80vw;
padding: 0.5rem;
height: 100dvh;
flex-shrink: 0;
box-sizing: content-box;
z-index: 10;
}
#past-chats-row:not(.negative-header) {
max-width: calc(85vw - var(--header-width));
}
#chat-controls {
padding: 1rem;
padding-bottom: 0;
overflow-y: scroll;
}
#chat-controls > :nth-child(1) {
padding: 0.5rem;
}
#past-chats-row + * {
width: unset;
flex-grow: 1;
flex-shrink: 1;
}
#search_chat {
padding-right: 0.5rem;
}
#search_chat > :nth-child(2) > :first-child {
display: none;
}
/* ----------------------------------------------
Keep dropdown menus above errored components
---------------------------------------------- */
.options {
z-index: 100 !important;
border: 1px solid var(--input-border-color);
border-radius: 0.5rem;
}
/* ----------------------------------------------
Big profile picture for characters
---------------------------------------------- */
.bigProfilePicture {
position: fixed;
bottom: 0;
left: 0;
width: calc(0.5 * (100vw - min(100vw, 48rem) - (120px - var(--header-width))));
z-index: 10000;
}
.pfp_character {
position: relative;
}
.pfp_character:hover {
cursor: pointer;
}
@media screen and (width <= 1300px) {
.bigProfilePicture {
display: none;
}
}
#past-chats {
max-height: calc(100dvh - 135px);
overflow-y: scroll !important;
border-radius: 0;
scrollbar-width: auto;
}
#past-chats::-webkit-scrollbar {
display: block;
}
#past-chats label {
width: 100%;
background-color: transparent !important;
background: none;
border: 0;
border-radius: 0;
padding-top: 8px;
padding-bottom: 8px;
position: relative;
min-height: 42px !important;
}
#past-chats label::before {
content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8 9h8"></path><path d="M8 13h6"></path><path d="M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12z"></path></svg>');
position: absolute;
top: 12px;
left: 12px;
margin-right: 8px;
}
.dark #past-chats label::before {
content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8 9h8"></path><path d="M8 13h6"></path><path d="M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12z"></path></svg>');
}
#past-chats label span {
margin-left: 29px;
}
#past-chats > :nth-child(2) {
display: none;
}
#past-chats > :nth-child(3) {
gap: 0.25rem;
}
#past-chats input {
display: none;
}
#past-chats label {
padding: 0.75rem;
font-size: 12.5px;
font-weight: 400;
margin-right: 8px;
}
#past-chats .selected,
#past-chats label:hover {
border-radius: 0.5rem;
}
#past-chats label:hover {
cursor: pointer;
}
#past-chats label {
transition: background-color 0.15s ease;
}
#past-chats .selected,
#past-chats label:hover {
background-color: #c8d8f5 !important;
}
#past-chats-buttons,
#delete-chat-row,
#rename-row {
width: 100%;
justify-content: center;
gap: 9px;
padding-right: 0.5rem;
}
#new-chat-wrapper {
display: contents;
}
.new-chat-arrow {
cursor: pointer;
position: relative;
padding: 0;
margin-right: -15px;
height: 39.594px;
display: flex;
align-items: center;
}
.new-chat-menu {
display: none;
position: absolute;
top: 0;
left: 0;
padding-top: 1.2em;
z-index: var(--layer-top);
white-space: nowrap;
}
.new-chat-arrow:hover .new-chat-menu {
display: block;
}
.new-chat-menu-item {
cursor: pointer;
padding: var(--size-2);
background: var(--background-fill-primary);
box-shadow: var(--shadow-drop-lg);
border-radius: var(--container-radius);
color: var(--body-text-color);
font-size: var(--text-md);
font-weight: var(--button-large-text-weight);
}
.new-chat-menu-item:hover {
background: var(--background-fill-secondary);
}
#past-chats-row,
#chat-controls {
width: 260px;
padding: 0.5rem;
padding-right: 0;
height: calc(100dvh - 16px);
flex-shrink: 0;
box-sizing: content-box;
}
.sidebar-hidden {
width: 0 !important;
padding: 0 !important;
overflow: hidden;
}
#past-chats-toggle,
#chat-controls-toggle,
#navigation-toggle {
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
user-select: none;
border-radius: 3px;
z-index: 1000;
position: fixed;
width: 2rem;
height: 2rem;
top: 0;
}
#past-chats-toggle svg,
#chat-controls-toggle svg,
#navigation-toggle svg {
pointer-events: none;
}
@media screen and (width <= 408px) {
#past-chats-toggle.past-chats-open {
top: 28px;
}
#chat-controls-toggle.chat-controls-open {
top: 28px;
right: calc(16px + min(260px, 80vw)) !important;
}
}
#past-chats-toggle.past-chats-open.negative-header {
left: calc(min(260px, 85vw) + 16px);
}
#past-chats-toggle.past-chats-open:not(.negative-header) {
left: calc(112px + min(260px, calc(85vw - var(--header-width))) + 16px);
}
#past-chats-toggle.past-chats-closed:not(.negative-header) {
left: 112px;
}
#past-chats-toggle.past-chats-closed.negative-header {
left: 0;
top: 28px;
}
@media screen and (width <= 924px) {
#past-chats-toggle.past-chats-closed.negative-header {
left: 28px;
top: 0;
}
}
.header_bar ~ * {
margin-left: var(--header-width);
}
/* Positions for chat-controls-toggle */
#chat-controls-toggle.chat-controls-open {
right: calc(min(260px, 80vw) + 23px);
}
#chat-controls-toggle.chat-controls-closed {
right: 7px;
}
@media screen and (width <= 924px) {
#chat-controls.sidebar-shown {
position: fixed;
right: 0;
}
#past-chats-row.sidebar-shown {
position: fixed;
}
}
/* ----------------------------------------------
Dark theme
---------------------------------------------- */
.dark .header_bar {
background-color: var(--bg-rail) !important;
}
.dark .header_bar button.selected {
background: var(--bg-active);
}
.dark #chat-input textarea {
background: var(--bg-input);
color: var(--text) !important;
border-color: var(--border);
}
.dark #chat-input textarea::placeholder {
color: var(--text-muted) !important;
opacity: 1 !important;
}
.dark .hover-menu {
background: var(--darker-gray);
border-color: transparent;
box-shadow: 0 4px 16px rgb(0 0 0 / 40%);
}
.dark .hover-menu button {
background-color: transparent !important;
}
.dark #chat-controls,
.dark #past-chats-row {
border: 0 !important;
box-shadow: none;
}
.dark gradio-app .gradio-container.gradio-container-4-37-2 .contain #past-chats label:hover {
background-color: var(--bg-hover) !important;
}
.dark gradio-app .gradio-container.gradio-container-4-37-2 .contain #past-chats .selected {
background-color: var(--bg-active) !important;
}
.dark #past-chats-toggle,
.dark #chat-controls-toggle,
.dark #navigation-toggle {
color: white;
}
.dark svg {
color: white;
}
@media screen and (width <= 408px) {
.dark #past-chats-toggle.past-chats-open {
background: var(--darker-gray);
}
.dark #chat-controls-toggle.chat-controls-open {
background: var(--darker-gray);
}
}
/* ----------------------------------------------
Light theme
---------------------------------------------- */
.header_bar {
background-color: var(--bg-rail) !important;
}
.header_bar button.selected {
background: var(--bg-active);
}
#chat-controls,
#past-chats-row {
background-color: var(--bg-sidebar);
}
#past-chats-toggle,
#chat-controls-toggle,
#navigation-toggle {
color: gray !important;
}
.mobile-top-bar {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 32px;
z-index: 2;
opacity: 0;
pointer-events: none;
}
@media screen and (width <= 924px) {
.mobile-top-bar {
opacity: 1;
pointer-events: auto;
}
.dark .mobile-top-bar {
background-color: var(--darker-gray);
}
.mobile-top-bar {
background-color: var(--light-theme-gray);
}
}
@media screen and (width <= 408px) {
#past-chats-toggle.past-chats-open {
background: var(--light-theme-gray);
}
#chat-controls-toggle.chat-controls-open {
background: var(--light-theme-gray);
}
}
/* ----------------------------------------------
Copy button for chat messages
---------------------------------------------- */
.message .text,
.message .text-you,
.message .text-bot,
.user-message .text,
.assistant-message .text {
position: relative;
}
.message, .user-message, .assistant-message {
position: relative;
}
/* New container for the buttons */
.message-actions {
position: absolute;
bottom: -23px;
left: 0;
display: flex;
gap: 5px;
opacity: 0;
transition: opacity 0.2s;
}
.footer-button {
padding: 0;
margin: 0;
border: none;
border-radius: 3px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.message:hover .message-actions,
.user-message:hover .message-actions,
.assistant-message:hover .message-actions {
opacity: 1;
}
/* Disable message actions and version navigation hover effects during generation */
._generating :is(.message, .user-message, .assistant-message):hover :is(.message-actions, .version-navigation) {
opacity: 0 !important;
pointer-events: none;
}
/* Disable message actions and version navigation hover effects during scrolling */
.scrolling :is(.message, .user-message, .assistant-message):hover :is(.message-actions, .version-navigation) {
opacity: 0 !important;
pointer-events: none;
}
.footer-button svg {
stroke: rgb(140 140 148);
}
.footer-button:hover svg {
stroke: rgb(107 114 128);
}
.dark .footer-button svg {
stroke: rgb(156 163 175);
}
.dark .footer-button:hover svg {
stroke: rgb(209 213 219);
}
.block:has(> .label-wrap) {
padding: 10px 12px !important;
border: 1px solid var(--border-color-primary);
}
.dark .block:has(> .label-wrap) {
border: 1px solid var(--border-color-dark);
}
.welcome-greeting {
text-align: center;
margin-top: 40vh;
font-size: 24px;
opacity: 0.7;
padding-left: 1rem;
padding-right: 1rem;
}
/* Thinking blocks styling */
.thinking-block {
margin-bottom: 12px;
border-radius: 8px;
border: 1px solid rgb(0 0 0 / 10%);
background-color: var(--light-theme-gray);
overflow: hidden;
}
.thinking-content:focus, .thinking-header:focus {
outline: 0 !important;
}
.dark .thinking-block {
background-color: transparent;
border: 1px solid var(--input-border-color);
}
.thinking-header {
display: flex;
align-items: center;
padding: 10px 16px;
cursor: pointer;
user-select: none;
font-size: 14px;
line-height: var(--line-sm);
color: rgb(0 0 0 / 70%);
transition: background-color 0.2s;
}
.thinking-header:hover {
background-color: rgb(0 0 0 / 3%);
}
.thinking-header::-webkit-details-marker {
display: none;
}
.thinking-icon {
margin-right: 8px;
color: rgb(0 0 0 / 50%);
/* Prevents the SVG from shrinking
* when tool call arguments are long */
flex-shrink: 0;
}
.thinking-title {
font-weight: 500;
}
.tool-call-spinner {
display: inline-block;
width: 12px;
height: 12px;
margin-left: 8px;
border: 2px solid rgb(0 0 0 / 15%);
border-top-color: rgb(0 0 0 / 55%);
border-radius: 50%;
animation: tool-call-spin 0.8s linear infinite;
flex-shrink: 0;
}
@keyframes tool-call-spin {
to { transform: rotate(360deg); }
}
.dark .tool-call-spinner {
border-color: rgb(255 255 255 / 15%);
border-top-color: rgb(255 255 255 / 65%);
}
.web-search-results {
display: flex;
flex-direction: column;
gap: var(--space-2);
}
.web-search-result {
padding: var(--space-3) var(--space-4);
background: var(--border-soft);
border-radius: var(--radius-sm);
}
.web-search-title {
display: block;
font-weight: 500;
margin-bottom: var(--space-1);
text-decoration: none;
}
.web-search-title:hover {
text-decoration: underline;
}
.web-search-snippet {
font-size: 0.9em;
color: var(--text-muted);
line-height: 1.4;
}
.thinking-content {
padding: 12px 16px;
border-top: 1px solid rgb(0 0 0 / 7%);
color: rgb(0 0 0 / 70%);
font-size: 14px;
line-height: 1.5;
overflow-wrap: break-word;
max-height: 250px;
overflow-y: scroll;
}
.chat .message-body .thinking-content p,
.chat .message-body .thinking-content li {
font-size: 15px !important;
}
/* Animation for opening thinking blocks */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.thinking-block[open] .thinking-content {
animation: fadeIn 0.3s ease-out;
}
/* Additional style for in-progress thinking */
.thinking-block[data-streaming="true"] .thinking-title {
animation: pulse 1.5s infinite;
}
@keyframes pulse {
0% { opacity: 0.6; }
50% { opacity: 1; }
100% { opacity: 0.6; }
}
.tool-approval-buttons {
display: flex;
gap: 8px;
max-height: none;
overflow-y: visible;
}
.tool-approval-btn {
padding: 6px 12px;
border: 1px solid var(--border-color-primary);
border-radius: 0.75rem;
background: var(--button-secondary-background-fill);
color: var(--button-secondary-text-color);
cursor: pointer;
font-size: 12px;
margin-bottom: 0 !important;
}
.tool-approval-btn:hover {
background: var(--button-secondary-background-fill-hover);
}
strong {
font-weight: bold;
}
.min.svelte-1ybaih5 {
min-height: 0;
}
#vram-info .value {
color: #008d00;
}
.dark #vram-info .value {
color: #07ff07;
}
.message-attachments {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 8px;
padding-bottom: 6px;
}
.attachment-box {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 8px;
background: rgb(0 0 0 / 5%);
border-radius: 6px;
border: 1px solid rgb(0 0 0 / 10%);
min-width: 80px;
max-width: 120px;
}
.attachment-icon {
margin-bottom: 4px;
color: #555;
}
.attachment-name {
font-size: 0.8em;
text-align: center;
word-break: break-word;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.dark .attachment-box {
background: rgb(255 255 255 / 5%);
border: 1px solid rgb(255 255 255 / 10%);
}
.dark .attachment-icon {
color: #ccc;
}
/* Message Editing Styles */
.editing-textarea {
width: 100%;
min-height: 200px;
max-height: 65vh;
padding: 10px;
border-radius: 0.5rem;
border: 1px solid var(--border-color-primary);
background-color: var(--light-theme-gray);
font-family: inherit;
font-size: inherit;
resize: vertical;
}
.dark .editing-textarea {
border: 1px solid var(--border-color-dark);
background-color: var(--darker-gray);
}
.editing-textarea:focus {
outline: none;
border-color: var(--selected-item-color-dark);
}
.edit-controls-container {
margin-top: 0;
display: flex;
gap: 8px;
padding-bottom: 8px;
}
.edit-control-button {
padding: 6px 12px;
border: 1px solid var(--border-color-primary);
border-radius: 0.75rem;
cursor: pointer;
background: var(--button-secondary-background-fill);
color: var(--button-secondary-text-color);
font-size: 12px;
margin: 0;
}
/* --- Simple Version Navigation --- */
.version-navigation {
position: absolute;
bottom: -23px;
right: 0;
display: flex;
align-items: center;
gap: 5px;
opacity: 0;
transition: opacity 0.2s;
}
.message:hover .version-navigation,
.user-message:hover .version-navigation,
.assistant-message:hover .version-navigation {
opacity: 1;
}
.version-nav-button {
padding: 2px 6px;
font-size: 12px;
min-width: auto;
}
.version-nav-button[disabled] {
opacity: 0.3;
cursor: not-allowed;
}
.version-position {
font-size: 11px;
color: currentcolor;
font-family: monospace;
min-width: 35px;
text-align: center;
opacity: 0.8;
user-select: none;
}
.token-display {
font-family: monospace;
font-size: 13px;
color: var(--body-text-color-subdued);
margin-top: 4px;
}
.image-attachment {
flex-direction: column;
max-width: 314px;
}
.image-preview {
border-radius: 16px;
margin-bottom: 5px;
object-fit: cover;
object-position: center;
border: 2px solid var(--border-color-primary);
aspect-ratio: 1 / 1;
}
button:focus {
outline: none;
}
/* Fix extra gaps for hidden elements on the right sidebar */
.svelte-sa48pu.stretch:has(> .hidden:only-child) {
display: none;
}
.delete-container {
position: absolute;
right: 8px;
display: flex;
gap: 6px;
opacity: 0;
transition: opacity 0.2s;
margin-left: 0;
}
.chat-label-with-delete {
position: relative;
padding-right: 60px;
}
.trash-btn {
border: none;
background: none;
cursor: pointer;
padding: 2px;
opacity: 0.7;
}
.cancel-btn {
border: none;
background: #ef4444;
color: white;
cursor: pointer;
width: 20px;
height: 20px;
border-radius: 2px;
font-family: monospace;
font-size: 12px;
align-items: center;
justify-content: center;
display: none;
}
.confirm-btn {
border: none;
background: #22c55e;
color: white;
cursor: pointer;
width: 20px;
height: 20px;
border-radius: 2px;
font-family: monospace;
font-size: 12px;
align-items: center;
justify-content: center;
display: none;
}
#character-context textarea {
height: calc((100vh - 358px) * 2/3) !important;
min-height: 90px !important;
}
#character-greeting textarea {
height: calc((100vh - 358px) * 1/3) !important;
min-height: 90px !important;
}
#user-description textarea {
height: calc(100vh - 342px) !important;
min-height: 90px !important;
}
#instruction-template-str textarea,
#chat-template-str textarea {
height: calc(100vh - 308px) !important;
min-height: 90px !important;
}
#textbox-notebook span {
display: none;
}
.chat-parent {
will-change: scroll-position;
contain: style;
transform: translateZ(0);
overflow-anchor: none;
}
#chat-input span {
display: none;
}
.sidebar-vertical-separator {
margin: 0;
border-bottom: var(--input-border-width) solid var(--input-border-color);
}
.dark .sidebar-vertical-separator {
border-bottom: 1px solid var(--border-soft);
}
button#swap-height-width {
position: absolute;
top: -50px;
right: 0;
border: 0;
}
#image-output-gallery, #image-output-gallery > :nth-child(2) {
height: calc(100vh - 91px);
max-height: calc(100vh - 91px);
}
#image-history-gallery, #image-history-gallery > :nth-child(2) {
height: calc(100vh - 182px);
max-height: calc(100vh - 182px);
}
/* Additional CSS for the paginated image gallery */
/* Page info styling */
#image-page-info {
display: flex;
align-items: center;
justify-content: center;
min-width: 200px;
font-size: 0.9em;
color: var(--body-text-color-subdued);
}
/* Settings display panel */
#image-ai-tab .settings-display-panel {
background: var(--background-fill-secondary);
padding: 12px;
border-radius: 8px;
font-size: 0.9em;
max-height: 300px;
overflow-y: auto;
margin-top: 8px;
}
/* Gallery status message */
#image-ai-tab .gallery-status {
color: var(--color-accent);
font-size: 0.85em;
margin-top: 4px;
}
/* Pagination button row alignment */
#image-ai-tab .pagination-controls {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
/* Selected image preview container */
#image-ai-tab .selected-preview-container {
border: 1px solid var(--border-color-primary);
border-radius: 8px;
padding: 8px;
background: var(--background-fill-secondary);
}
/* Fix a gr.Markdown UI glitch when clicking Next in the
* Image AI > Gallery tab */
.min.svelte-1yrv54 {
min-height: 0;
}
/* Image Generation Progress Bar */
#image-progress .image-ai-separator {
height: 24px;
margin: 20px 0;
border-top: 1px solid var(--input-border-color);
}
#image-progress .image-ai-progress-wrapper {
height: 24px;
margin: 20px 0;
}
#image-progress .image-ai-progress-track {
background: #e5e7eb;
border-radius: 4px;
overflow: hidden;
height: 8px;
}
.dark #image-progress .image-ai-progress-track {
background: #333;
}
#image-progress .image-ai-progress-fill {
background: #4a9eff;
height: 100%;
}
#image-progress .image-ai-progress-text {
text-align: center;
font-size: 12px;
color: #666;
margin-top: 4px;
}
.dark #image-progress .image-ai-progress-text {
color: #888;
}
#llm-prompt-variations {
position: absolute;
top: 0;
left: calc(100% - 174px);
}
table {
border-collapse: collapse;
}
.table-wrapper {
overflow-x: auto;
}
.message-body :is(td, th) {
word-break: normal;
overflow-wrap: normal;
}
table, tr, td, th, thead {
border: 0;
}
.prose hr {
border-color: var(--border-color-primary);
}
td + td,
th + th {
border-left: 1px solid var(--border-color-primary) !important;
}
tr + tr td,
tr + tr th {
border-top: 1px solid var(--border-color-primary) !important;
}
thead + tbody tr:first-child td,
thead + tbody tr:first-child th {
border-top: 1px solid var(--border-color-primary) !important;
}
/* ------------------------------------------------
Tools CheckboxGroup - vertical DragDrop-like style
------------------------------------------------ */
/* "Refresh list" link in the Tools label */
.tools-refresh-link {
cursor: pointer;
}
/* Checkbox list container */
#tools-group {
padding: 0 !important;
border-width: 0 !important;
background: transparent !important;
min-height: 0 !important;
}
#tools-group .wrap {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
gap: 4px;
padding: 0;
margin-top: var(--spacing-lg);
max-height: 350px;
overflow-y: auto;
}
/* Pretty scrollbar for the tools list */
#tools-group .wrap::-webkit-scrollbar {
width: 7px;
height: 7px;
}
#tools-group .wrap::-webkit-scrollbar-track {
background: transparent;
}
#tools-group .wrap::-webkit-scrollbar-thumb,
#tools-group .wrap::-webkit-scrollbar-thumb:hover {
background: var(--neutral-300);
border-radius: 9999px;
}
.dark #tools-group .wrap::-webkit-scrollbar-thumb,
.dark #tools-group .wrap::-webkit-scrollbar-thumb:hover {
background: rgb(255 255 255 / 6.25%);
border-radius: 9999px;
}
#tools-group .wrap::-webkit-scrollbar-corner {
background: transparent;
}
/* Each checkbox item */
#tools-group label {
display: flex;
align-items: center;
gap: 8px;
padding: 5px 8px;
border-radius: var(--radius-sm, 4px);
background: var(--block-background-fill);
border: 1px solid var(--border-color-primary);
color: var(--body-text-color);
font-size: var(--input-text-size);
font-weight: var(--input-text-weight);
cursor: pointer;
user-select: none;
transition: border-color 0.15s ease, background 0.15s ease;
box-shadow: none;
}
#tools-group label:hover {
border-color: var(--input-border-color-focus);
}
#tools-group label span {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Mode selector: segmented control
Targets the gr.Radio at #chat-mode and replaces the default
stacked / wrap-prone radio appearance with a 3-up segmented
control. The actual <input type=radio> is hidden; the parent
<label> carries the selected state. */
#chat-mode .wrap {
display: grid !important;
grid-template-columns: repeat(3, 1fr);
gap: 2px;
background: transparent;
border: 1px solid var(--border);
border-radius: var(--radius-md);
padding: 2px;
}
#chat-mode .wrap > label {
display: flex !important;
align-items: center;
justify-content: center;
margin: 0 !important;
padding: 6px 4px !important;
background: transparent !important;
border: none !important;
box-shadow: none !important;
border-radius: calc(var(--radius-md) - 2px);
color: var(--text-muted);
font-size: 12px;
line-height: 1.2;
white-space: nowrap;
cursor: pointer;
transition: background-color var(--motion), color var(--motion);
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
}
#chat-mode .wrap > label:hover {
background: var(--bg-hover) !important;
color: var(--text);
}
#chat-mode .wrap > label.selected {
background: var(--bg-active) !important;
color: var(--text);
font-weight: 500;
}
#chat-mode .wrap > label > input[type="radio"] {
display: none !important;
}
#chat-mode .wrap > label > span {
margin: 0 !important;
}
/* Sidebar collapse: left snappy on purpose. Animating width
on a flex container reflows its contents during the
transition, which looks worse than an instant snap. */
/* Sidebar toggle handles
The existing 2rem-square hitbox is preserved (so all the
positioning calc()s in media queries above still work) but
the visible affordance is reduced to a 3px hairline bar
that lightens on hover. The leftmost navigation-toggle keeps
its hamburger because it lives on the rail rather than at a
sidebar edge. */
#past-chats-toggle,
#chat-controls-toggle {
background: transparent !important;
}
#past-chats-toggle svg,
#chat-controls-toggle svg {
display: none !important;
}
#past-chats-toggle::before,
#chat-controls-toggle::before {
content: "";
display: block;
width: 3px;
height: 28px;
border-radius: 2px;
background: var(--text-muted);
opacity: 0.55;
}
/* Mobile: keep the original chunky toggle button + arrow SVG.
The hairline approach is a desktop affordance; on mobile
the sidebars slide over content and a regular icon button
reads more clearly than a thin handle. */
@media (max-width: 924px) {
#past-chats-toggle::before,
#chat-controls-toggle::before {
display: none !important;
}
#past-chats-toggle svg,
#chat-controls-toggle svg {
display: block !important;
}
#past-chats-toggle,
#chat-controls-toggle {
justify-content: center !important;
}
}
/* Bar lives at the inner edge of the hitbox so it stays glued
to the sidebar boundary even though the 32px clickable area
extends into the chat area. */
#past-chats-toggle {
justify-content: flex-start !important;
}
#chat-controls-toggle {
justify-content: flex-end !important;
}
/* Desktop-only: vertically center the toggle handles and
anchor them at the sidebar boundary. Narrow-screen layouts
keep the existing top-anchored positioning above. */
@media (min-width: 925px) {
#past-chats-toggle,
#chat-controls-toggle {
top: 50% !important;
transform: translateY(-50%);
}
/* Open states: hitbox flush with the sidebar's outer
edge. Sidebars have width 260px + padding-left 0.5rem
(box-sizing: content-box), so total visual width is
268px. The +0.5rem accounts for that padding so the bar
sits exactly on the outer edge, not 8px inside it. */
#past-chats-toggle.past-chats-open.negative-header {
left: calc(min(260px, 85vw) + 0.5rem) !important;
}
#past-chats-toggle.past-chats-open:not(.negative-header) {
left: calc(112px + min(260px, calc(85vw - var(--header-width))) + 0.5rem) !important;
}
#chat-controls-toggle.chat-controls-open {
right: calc(min(260px, 80vw) + 0.5rem) !important;
}
/* Closed states: hitbox flush with the adjacent edge
(rail right edge / viewport edge). Bar sits 16px into
the chat area / viewport, fully visible. */
#past-chats-toggle.past-chats-closed:not(.negative-header) {
left: 112px !important;
}
#past-chats-toggle.past-chats-closed.negative-header {
left: 0 !important;
}
#chat-controls-toggle.chat-controls-closed {
right: 0 !important;
}
}
#navigation-toggle {
transition: background-color var(--motion);
border-radius: var(--radius-sm);
}
#navigation-toggle:hover {
background: var(--bg-hover);
}
/* Focus system
Restores a visible keyboard focus ring while keeping
mouse-click button focus quiet. */
button:focus:not(:focus-visible),
.thinking-content:focus,
.thinking-header:focus {
outline: none;
}
button:focus-visible,
[role="tab"]:focus-visible,
[role="button"]:focus-visible,
.thinking-header:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
/* Inputs/textareas/selects use a border-color shift instead of
an outline, so the focus indication doesn't sit detached
around a pill-shaped textarea. */
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
outline: none;
}
/* Hover transitions */
#hover-element-button,
.hover-menu button,
#show-controls,
#past-chats label {
transition: background-color var(--motion), color var(--motion), border-color var(--motion);
}
/* Past-chats list items: token-bound hover/selected without
layered overrides. */
#past-chats label {
font-size: 13px;
border-radius: var(--radius-md);
}
#past-chats label:hover {
background-color: var(--bg-hover) !important;
}
#past-chats .selected {
background-color: var(--bg-active) !important;
}
/* Hover menu surfaces: consume tokens so the popover is
visible in both themes. */
.hover-menu button:hover {
background: var(--bg-hover) !important;
}
#show-controls:hover {
background-color: var(--bg-hover);
}
.dark #show-controls:hover,
.dark #hover-element-button:hover {
background-color: var(--bg-hover);
}
/* Composer: turn the three sibling columns inside
#chat-input-row (hover menu / textarea / send-stop) into a
single rounded card. The textarea is stripped of its own
border/background and the surrounding columns lose their
default chrome so the row reads as one bordered surface
that lights up on focus-within. */
#chat-input-row {
display: grid !important;
grid-template-columns: auto 1fr auto;
grid-template-rows: 1fr auto;
grid-template-areas:
"input input input"
"ham . send";
column-gap: 4px;
row-gap: 6px;
width: calc(100% - 20px);
max-width: 48rem;
margin: 0 auto 1rem;
padding: 8px 16px;
background: var(--bg-elevated);
border: 1px solid #d1d5db;
border-radius: 1.5rem;
position: relative;
}
.dark #chat-input-row {
background: var(--bg-input);
border-color: var(--border);
}
/* Composer pinned to bottom of #chat-col; chat-parent's
margin-bottom is kept in sync via JS. */
#chat-input-row.chat-input-positioned {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
}
#chat-input-row > #gr-hover-container { grid-area: ham; }
#chat-input-row > #chat-input-container { grid-area: input; }
#chat-input-row > #generate-stop-container { grid-area: send; }
/* Only the row's direct flex children get bottom-anchored.
The universal cascade (#chat-input-row *) was pushing SVGs
inside the icon buttons to the bottom of their button,
leaving a 6-7px offset vs the centered text and Send icon. */
#chat-input-row > * {
align-self: flex-end !important;
}
#chat-input-row > div,
#chat-input-row .hover-element,
#chat-input-row #chat-input,
#chat-input-row #chat-input > .form,
#chat-input-row #chat-input > .form > div {
margin-top: 0 !important;
margin-bottom: 0 !important;
padding-top: 0 !important;
padding-bottom: 0 !important;
min-height: 0 !important;
}
/* Strip default chrome from the sibling columns and the
MultimodalTextbox itself; the row supplies the visible
surface. */
#chat-input,
#chat-input-container,
#gr-hover-container,
#generate-stop-container,
#chat-input-container > .form {
background: transparent !important;
border: none !important;
box-shadow: none !important;
}
/* Paperclip pinned to the bottom-left of the composer.
Wrapper chain is position:static so the absolute resolves
up to #chat-input-row. */
#chat-input .input-container {
display: flex !important;
flex-direction: row !important;
align-items: stretch !important;
position: static !important;
}
#chat-input,
#chat-input > label,
#chat-input-container,
#chat-input-container > .form {
position: static !important;
}
#chat-input .upload-button {
position: absolute !important;
bottom: 8px;
left: calc(12px + 32px + 4px);
z-index: 5;
margin: 0 !important;
}
/* Kill the wrapper offsets that push each icon to a different
vertical position relative to the textarea / Send button.
- .hover-element has padding-top:4px → hamburger sits 4px high
- .upload-button has margin-bottom:7px → paperclip sits 7px high
- chat-input-container has 5px of internal padding above the
textarea from Gradio's MultimodalTextbox wrapper */
#chat-input-row .hover-element,
#chat-input-row #gr-hover,
#chat-input-row #gr-hover-container {
padding: 0 !important;
margin: 0 !important;
height: 32px !important;
min-height: 32px !important;
}
#chat-input .upload-button {
height: 32px !important;
width: 24px !important;
min-width: 24px !important;
min-height: 32px !important;
margin: 0 !important;
padding: 0 !important;
align-self: flex-end !important;
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
}
/* Tighten the hamburger button too: 32×32 leaves 6px of dead
space on each side of the 20px SVG, making the icon visually
far from its neighbors. */
#hover-element-button {
width: 24px !important;
min-width: 24px !important;
}
#chat-input-container,
#chat-input-container > .form,
#chat-input-container > .form > #chat-input,
#chat-input > label,
#chat-input .input-container {
padding: 0 !important;
margin: 0 !important;
min-height: 0 !important;
}
#chat-input textarea {
background: transparent !important;
border: none !important;
border-radius: 0 !important;
padding: 12px 4px 4px 2px !important;
margin: 0 !important;
box-shadow: none !important;
font-size: 16px !important;
overflow-wrap: anywhere !important;
}
/* Override Gradio's flex-grow scales (set by `scale=1/10/1`)
so the icon column and the send column size to their
content and stay flush against the textarea. */
#gr-hover-container,
#generate-stop-container {
flex: 0 0 auto !important;
padding: 0 !important;
}
#chat-input-container {
flex: 1 1 auto !important;
min-width: 0;
}
/* Multimodal attachment thumbnails: in-flow inside the
composer card (reserves layout space, chat content above
pushes up automatically). Styled as a distinct zone with
a subtle bottom divider rather than its own card. */
#chat-input .thumbnails {
padding: 6px 0 8px !important;
margin-left: -4px;
background: transparent;
gap: 8px !important;
}
/* Send and Stop icon buttons. Don't set `display`; it would
override Gradio's `.hidden { display: none }` used for
visible=False on the Stop button. */
#chat-input-row #Generate,
#chat-input-row #stop {
width: 32px !important;
min-width: 32px !important;
height: 32px !important;
padding: 0 !important;
border: none !important;
box-shadow: none !important;
font-size: 0 !important;
line-height: 32px;
text-align: center;
transition: opacity var(--motion), background-color var(--motion);
}
#chat-input-row #Generate {
background: var(--accent) !important;
color: #ffffff !important;
border-radius: 50% !important;
}
/* Stop button: tokenized hover progression. */
#chat-input-row #stop {
background: var(--bg-hover) !important;
color: var(--text) !important;
border: none !important;
border-radius: 50% !important;
transition: background-color var(--motion) !important;
}
#chat-input-row #stop:hover {
background: var(--bg-active) !important;
}
/* Send icon: paper airplane pointing right with a horizontal
accent line. */
#chat-input-row #Generate::before {
width: 18px;
height: 18px;
-webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M3 3 6 12l-3 9 19-9Z'/><path d='M6 12h16'/></svg>");
mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M3 3 6 12l-3 9 19-9Z'/><path d='M6 12h16'/></svg>");
}
/* Stop icon: filled square (no mask needed, just a colored
block via background-color: currentColor). */
#chat-input-row #stop::before {
content: "";
display: inline-block;
width: 12px;
height: 12px;
vertical-align: middle;
background-color: currentColor;
}
#chat-input-row #Generate:hover,
#chat-input-row #stop:hover {
opacity: 0.7;
}
/* Accordion chevron: Gradio renders the open/close indicator
as a Unicode ▼ inside a span that inherits section-header
font-size; in Inter that glyph paints ~2x its em-square,
producing a giant triangle. Constrain it. */
.label-wrap > .icon {
font-size: 11px !important;
line-height: 1;
color: var(--text-muted);
}
/* Dark sidebar surfaces use the sidebar token. The
.dark #chat-controls,#past-chats-row block above this
sets `border: 0 !important;`, so the previous attempts to
normalize border-left/right via var(--border-soft) here
were dead code (overridden by the !important on the
shorthand) and were removed. The `.sidebar-vertical-separator`
uses a separate dark rule (see line ~1750 in this file). */
.dark #chat-controls,
.dark #past-chats-row {
background-color: var(--bg-sidebar);
}
/* Inner Tabs (Parameters/Models/Image gen). The header_bar is
the leftmost rail (already styled) and is excluded via
:not(.header_bar). Default Gradio look has tab-shaped
buttons with rounded top corners and a bottom border that
creates the "browser tab" effect; replaced with a flat
underline on the active tab. */
.tab-nav:not(.header_bar) {
border-bottom: 1px solid var(--border) !important;
gap: 0;
padding: 0;
margin-bottom: 0;
}
.tab-nav:not(.header_bar) > button {
border: none !important;
border-radius: 0 !important;
background: transparent !important;
color: var(--text-muted) !important;
padding: 8px 14px !important;
margin: 0 !important;
font-weight: 500;
font-size: 14px;
box-shadow: none !important;
transition: color var(--motion), box-shadow var(--motion);
}
.tab-nav:not(.header_bar) > button:hover {
color: var(--text) !important;
background: var(--bg-hover) !important;
}
.tab-nav:not(.header_bar) > button.selected {
color: var(--text) !important;
background: transparent !important;
box-shadow: inset 0 -2px 0 var(--accent) !important;
}
/* Slider thumb: use the accent color so it matches the rest
of the design language (selected-tab indicator, etc.). */
input[type="range"]::-webkit-slider-thumb {
background: var(--accent) !important;
border: none !important;
height: 16px !important;
width: 16px !important;
box-shadow: none !important;
margin-top: 0 !important;
}
input[type="range"]::-moz-range-thumb {
background: var(--accent) !important;
border: none !important;
height: 16px !important;
width: 16px !important;
box-shadow: none !important;
}
/* Dropdown popover: kill Gradio's heavy default shadow,
replace with a subtle one matching design tokens. */
.options {
box-shadow: 0 4px 12px rgb(0 0 0 / 12%) !important;
}
.dark .options {
box-shadow: 0 4px 16px rgb(0 0 0 / 40%) !important;
}
/* Accordion: drop Gradio's default shadow_drop on the
accordion block. */
.block:has(> .label-wrap) {
box-shadow: none !important;
}
/* Icon buttons: hide the text label; the visible glyph is the
::before mask below. Original text stays in the DOM for a11y. */
.refresh-icon-btn,
.save-icon-btn,
.delete-icon-btn,
.trash-btn {
font-size: 0 !important;
}
/* Shared base for masked icon glyphs; per-icon rules set
width/height and mask-image. */
#chat-input-row #Generate::before,
.refresh-icon-btn::before,
.save-icon-btn::before,
.delete-icon-btn::before,
.trash-btn::before {
content: "";
display: inline-block;
vertical-align: middle;
background-color: currentColor;
-webkit-mask-position: center;
mask-position: center;
-webkit-mask-size: contain;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
}
/* Refresh icon (Lucide refresh-cw). */
.refresh-icon-btn::before {
width: 16px;
height: 16px;
-webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='23 4 23 10 17 10'/><polyline points='1 20 1 14 7 14'/><path d='M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15'/></svg>");
mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='23 4 23 10 17 10'/><polyline points='1 20 1 14 7 14'/><path d='M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15'/></svg>");
}
/* Save icon (Lucide save). */
.save-icon-btn::before {
width: 16px;
height: 16px;
-webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z'/><polyline points='17 21 17 13 7 13 7 21'/><polyline points='7 3 7 8 15 8'/></svg>");
mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z'/><polyline points='17 21 17 13 7 13 7 21'/><polyline points='7 3 7 8 15 8'/></svg>");
}
/* Delete + past-chats trash icon (Lucide trash-2). */
.delete-icon-btn::before,
.trash-btn::before {
width: 16px;
height: 16px;
-webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='3 6 5 6 21 6'/><path d='M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6'/><path d='M10 11v6'/><path d='M14 11v6'/><path d='M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2'/></svg>");
mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='3 6 5 6 21 6'/><path d='M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6'/><path d='M10 11v6'/><path d='M14 11v6'/><path d='M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2'/></svg>");
}
/* Past-chats trash uses 14px to match the smaller chat-list scale. */
.trash-btn::before {
width: 14px;
height: 14px;
}