mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-08-23 15:25:28 +00:00
Introduce a WebUI extension manifest and rewrite the asset bundler/server to support caller-supplied entry sets, extension-injected entries, and negotiated gzip. Key changes: add get_webui_extension_manifest() to helpers/extension, refactor Stop logic into stop_context() and reuse it from the connector `/stop` command, and add a new `/rename` slash command for chat naming. ui_bundler now accepts entry_urls, includes enabled extension entry files, raises the embedded text file size limit to 512 KiB, computes per-entry-set cache keys, and returns a bundle version based on the bundle signature. ui_server applies Starlette GZip middleware, adds routes (/, /index.html, /ui/index, /safe), serves splash/safe documents, injects the serialized webui_extension_manifest into the rendered index, and streamlines the /ui/asset-bundle endpoint with ETag and gzip handling. Also add multiple WebUI assets and fonts, new/updated plugin command YAML and Python command handlers, and corresponding tests covering bundling, commands, chat naming, and WebUI behaviors. Documentation (.dox.md) updated to reflect the new runtime contracts and guidance.
659 lines
14 KiB
CSS
659 lines
14 KiB
CSS
/* Modal Styles */
|
|
/* Until the full transition of A0 modals is complete,
|
|
consider .modal-content, .modal-container, and .modal-overlay part of the legacy modal system.
|
|
|
|
Keep changes conservative because some classes like modal-header are shared between
|
|
the old and the new system. */
|
|
|
|
.modal {
|
|
display: none;
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
z-index: 5000;
|
|
}
|
|
.modal.show {
|
|
display: block;
|
|
}
|
|
|
|
.modal-inner {
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: hidden;
|
|
position: fixed;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
width: min(92vw, 980px);
|
|
max-width: calc(100vw - 24px);
|
|
max-height: min(88vh, 900px);
|
|
border: 1px solid color-mix(in srgb, var(--color-border) 68%, transparent);
|
|
border-radius: 7px;
|
|
background: color-mix(in srgb, var(--color-background) 94%, #000 6%);
|
|
box-shadow: 0 18px 48px rgba(0, 0, 0, 0.32);
|
|
z-index: 2;
|
|
}
|
|
|
|
/* Overlay (old system) */
|
|
.modal-overlay {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: rgba(0, 0, 0, 0.48);
|
|
backdrop-filter: blur(8px) saturate(112%);
|
|
-webkit-backdrop-filter: blur(8px) saturate(112%);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
z-index: 5001;
|
|
}
|
|
|
|
/* Modal Backdrop */
|
|
.modal-backdrop {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: rgba(0, 0, 0, 0.48);
|
|
backdrop-filter: blur(8px) saturate(112%);
|
|
-webkit-backdrop-filter: blur(8px) saturate(112%);
|
|
z-index: 1;
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* Modal Container (old system) */
|
|
.modal-container {
|
|
background: color-mix(in srgb, var(--color-background) 94%, #000 6%);
|
|
border: 1px solid color-mix(in srgb, var(--color-border) 68%, transparent);
|
|
border-radius: 7px;
|
|
width: 1100px; /* Reduced from 1200px to 1100px */
|
|
max-height: 90vh;
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: hidden;
|
|
box-shadow: 0 18px 48px rgba(0, 0, 0, 0.32);
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
/* Modal Header */
|
|
.modal-header {
|
|
display: grid;
|
|
grid-template-columns: minmax(0, 1fr);
|
|
grid-auto-flow: column;
|
|
grid-auto-columns: auto;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 0.5rem;
|
|
min-height: 42px;
|
|
padding: 0.45rem 0.75rem 0.45rem 1rem;
|
|
background: color-mix(in srgb, var(--color-background) 92%, #000 8%);
|
|
color: var(--color-text);
|
|
border-bottom: 1px solid color-mix(in srgb, var(--color-border) 64%, transparent);
|
|
}
|
|
.modal-header h2 {
|
|
margin: 0;
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.modal-title {
|
|
font-size: 0.92rem;
|
|
font-weight: 750;
|
|
letter-spacing: 0;
|
|
}
|
|
|
|
/* Modal Subheader */
|
|
.modal-subheader {
|
|
display: inline;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 0.7rem 1.5rem;
|
|
}
|
|
|
|
/* Modal Close Button */
|
|
.modal-close {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 34px;
|
|
height: 34px;
|
|
min-width: 34px;
|
|
min-height: 34px;
|
|
background: transparent;
|
|
border: 1px solid transparent;
|
|
border-radius: 7px;
|
|
font-size: 1.45rem;
|
|
line-height: 1;
|
|
color: var(--color-text);
|
|
opacity: 0.72;
|
|
cursor: pointer;
|
|
padding: 0;
|
|
transition: background-color 0.16s ease, border-color 0.16s ease, opacity 0.16s ease;
|
|
}
|
|
|
|
.modal-close:hover {
|
|
opacity: 1;
|
|
border-color: color-mix(in srgb, var(--color-primary) 28%, var(--color-border));
|
|
background: color-mix(in srgb, var(--color-background-hover) 72%, transparent);
|
|
}
|
|
|
|
/* Modal Description */
|
|
.modal-description {
|
|
padding: 0.8rem 1rem 0 1rem;
|
|
flex-grow: 1;
|
|
}
|
|
|
|
/* Modal Content */
|
|
.modal-content {
|
|
padding: 0.5rem 1.5rem 0 1.5rem;
|
|
overflow-y: auto;
|
|
height: calc(90vh);
|
|
flex-grow: 1;
|
|
background-clip: border-box;
|
|
border: 6px solid transparent;
|
|
margin-bottom: 0;
|
|
padding-bottom: 10px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.modal-bd {
|
|
min-width: 0;
|
|
}
|
|
|
|
.modal-scroll {
|
|
min-height: 0;
|
|
max-height: min(88vh, 900px);
|
|
overflow-y: auto;
|
|
padding: 0.9rem 1rem 1rem;
|
|
background: color-mix(in srgb, var(--color-background) 95%, #000 5%);
|
|
}
|
|
|
|
.modal-x {
|
|
position: absolute;
|
|
top: 1rem;
|
|
right: 1rem;
|
|
background: none;
|
|
border: none;
|
|
font-size: 1.5rem;
|
|
cursor: pointer;
|
|
color: var(--color-text);
|
|
padding: 0.5rem;
|
|
line-height: 1;
|
|
z-index: 3;
|
|
}
|
|
|
|
.modal-content::-webkit-scrollbar, .modal-scroll::-webkit-scrollbar {
|
|
width: 6px;
|
|
height: 6px;
|
|
}
|
|
.modal-content::-webkit-scrollbar-track, .modal-scroll::-webkit-scrollbar-track {
|
|
background: transparent;
|
|
margin: 4px 0;
|
|
border-radius: 6px;
|
|
}
|
|
.modal-content::-webkit-scrollbar-thumb, .modal-scroll::-webkit-scrollbar-thumb {
|
|
background-color: rgba(155, 155, 155, 0.5);
|
|
border-radius: 6px;
|
|
transition: background-color 0.2s ease;
|
|
}
|
|
.modal-content::-webkit-scrollbar-thumb:hover, .modal-scroll::-webkit-scrollbar-thumb:hover {
|
|
background-color: rgba(155, 155, 155, 0.7);
|
|
}
|
|
|
|
/* Modal with footer support */
|
|
.modal-footer {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
align-items: center;
|
|
min-height: 54px;
|
|
padding: 0.55rem 1rem;
|
|
border-top: 1px solid color-mix(in srgb, var(--color-border) 58%, transparent);
|
|
background: color-mix(in srgb, var(--color-background) 92%, #000 8%);
|
|
gap: 0.75rem;
|
|
}
|
|
.modal-inner.modal-with-footer {
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
.modal-inner.modal-with-footer .modal-scroll {
|
|
flex: 1;
|
|
min-height: 0;
|
|
overflow-y: auto;
|
|
}
|
|
.modal-footer-slot {
|
|
flex-shrink: 0;
|
|
border-top: 1px solid color-mix(in srgb, var(--color-border) 58%, transparent);
|
|
background: color-mix(in srgb, var(--color-background) 92%, #000 8%);
|
|
}
|
|
|
|
.modal-footer-slot .modal-footer {
|
|
border-top: 0;
|
|
}
|
|
|
|
/* Section Styles */
|
|
.section {
|
|
margin-bottom: 2rem;
|
|
padding: 1rem;
|
|
/* padding-bottom: 0; */
|
|
border: 1px solid var(--color-border);
|
|
border-radius: 0.5rem;
|
|
}
|
|
.section-title {
|
|
font-size: 1.25rem;
|
|
font-weight: bold;
|
|
color: var(--color-primary);
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
.section-description {
|
|
color: var(--color-text);
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
/* Buttons Container */
|
|
.modal-button-container {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
gap: 10px;
|
|
width: 100%;
|
|
margin-top: 20px;
|
|
}
|
|
.modal-button-container .button {
|
|
flex: 1;
|
|
min-width: 0;
|
|
padding: 10px;
|
|
text-align: center;
|
|
white-space: nowrap;
|
|
font-size: 0.9em;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
#buttons-container {
|
|
display: flex;
|
|
gap: 0.875rem !important;
|
|
}
|
|
|
|
/* Button Styles */
|
|
.btn {
|
|
font-weight: 500;
|
|
min-height: 32px;
|
|
padding: 0.42rem 1rem;
|
|
border-radius: 7px;
|
|
cursor: pointer;
|
|
border: 1px solid transparent;
|
|
font-size: 0.84rem;
|
|
font-family: "Rubik", Arial, Helvetica, sans-serif;
|
|
transition: background-color 0.16s ease, border-color 0.16s ease, color 0.16s ease, opacity 0.16s ease;
|
|
}
|
|
.btn.slim {
|
|
padding: 0.2em 0.4em;
|
|
}
|
|
.btn.primary {
|
|
border-color: color-mix(in srgb, var(--color-primary) 42%, var(--color-border));
|
|
background: color-mix(in srgb, #2196f3 78%, var(--color-panel));
|
|
color: white;
|
|
width: fit-content;
|
|
align-items: center;
|
|
display: inline-flex;
|
|
}
|
|
.btn:disabled {
|
|
cursor: not-allowed;
|
|
}
|
|
.btn-ok {
|
|
border-color: color-mix(in srgb, #4248f1 56%, var(--color-border));
|
|
background: color-mix(in srgb, #4248f1 86%, var(--color-panel));
|
|
color: white;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
transition: background 0.3s ease-in-out;
|
|
}
|
|
.btn-ok > svg {
|
|
max-width: 20px;
|
|
}
|
|
.btn-ok:hover {
|
|
border-color: color-mix(in srgb, #656bff 70%, var(--color-border));
|
|
background: #353bc5;
|
|
}
|
|
.btn-ok:active {
|
|
background: #2b309c;
|
|
}
|
|
.btn-cancel {
|
|
background: transparent;
|
|
color: var(--color-accent);
|
|
border: 1px solid color-mix(in srgb, var(--color-accent) 82%, var(--color-border));
|
|
transition: background 0.3s ease-in-out, color 0.3s ease-in-out;
|
|
}
|
|
.btn-cancel:hover {
|
|
background: var(--color-accent);
|
|
color: var(--color-text);
|
|
}
|
|
.btn-cancel:active {
|
|
background: #a94658;
|
|
color: var(--color-text);
|
|
}
|
|
.light-mode .btn-cancel:hover {
|
|
background: var(--color-accent);
|
|
color: var(--color-background);
|
|
}
|
|
.light-mode .btn-cancel:active {
|
|
background: #a94658;
|
|
color: var(--color-background);
|
|
}
|
|
.btn-field {
|
|
border-color: color-mix(in srgb, #2196f3 48%, var(--color-border));
|
|
background: color-mix(in srgb, #2196f3 78%, var(--color-panel));
|
|
color: white;
|
|
width: fit-content;
|
|
}
|
|
.btn-field:disabled {
|
|
background: #ccc;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
/* Editor Toolbar */
|
|
.editor-toolbar {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 1rem;
|
|
padding: 0.5rem 1rem;
|
|
}
|
|
.toolbar-group {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
padding: 0 0.5rem;
|
|
border-right: 1px solid var(--color-border);
|
|
}
|
|
.toolbar-group:last-child {
|
|
border-right: none;
|
|
}
|
|
.toolbar-button {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 32px;
|
|
height: 32px;
|
|
padding: 0.4rem;
|
|
background: transparent;
|
|
border: 1px solid transparent;
|
|
border-radius: 4px;
|
|
color: var(--color-text);
|
|
opacity: 0.7;
|
|
cursor: pointer;
|
|
transition: all 0.2s ease;
|
|
}
|
|
.toolbar-button svg {
|
|
width: 18px;
|
|
height: 18px;
|
|
}
|
|
.toolbar-button:hover {
|
|
opacity: 1;
|
|
background-color: rgba(255, 255, 255, 0.1);
|
|
}
|
|
.toolbar-button:active {
|
|
transform: translateY(1px);
|
|
}
|
|
.toolbar-button.active {
|
|
background-color: rgba(255, 255, 255, 0.15);
|
|
border-color: var(--color-border);
|
|
opacity: 1;
|
|
}
|
|
.toolbar-button:disabled {
|
|
opacity: 0.3;
|
|
cursor: not-allowed;
|
|
}
|
|
.toolbar-button:disabled:hover {
|
|
background-color: transparent;
|
|
}
|
|
|
|
/* Range Input Styles */
|
|
input[type="range"] {
|
|
width: 100%;
|
|
cursor: pointer;
|
|
height: 4px;
|
|
-webkit-appearance: none;
|
|
appearance: none;
|
|
background: var(--color-border);
|
|
border-radius: 2px;
|
|
outline: none;
|
|
transition: all 0.2s ease;
|
|
}
|
|
input[type="range"]::-webkit-slider-thumb {
|
|
-webkit-appearance: none;
|
|
appearance: none;
|
|
width: 16px;
|
|
height: 16px;
|
|
background: var(--color-primary);
|
|
border-radius: 50%;
|
|
cursor: pointer;
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
input[type="range"]::-moz-range-thumb {
|
|
width: 16px;
|
|
height: 16px;
|
|
background: var(--color-primary);
|
|
border-radius: 50%;
|
|
cursor: pointer;
|
|
border: none;
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.range-value {
|
|
min-width: 3em;
|
|
text-align: right;
|
|
}
|
|
|
|
/* Light mode overrides */
|
|
.light-mode input[type="range"]::-webkit-slider-thumb {
|
|
background: #777;
|
|
}
|
|
.light-mode input[type="range"]::-moz-range-thumb {
|
|
background: #777;
|
|
}
|
|
|
|
/* Responsive Design */
|
|
@media (max-width: 1280px) {
|
|
.modal-container {
|
|
width: 95%;
|
|
min-width: unset; /* Remove min-width constraints */
|
|
max-width: 95%;
|
|
}
|
|
.section {
|
|
overflow-x: auto;
|
|
}
|
|
}
|
|
@media (max-width: 768px) {
|
|
.modal-header {
|
|
padding-left: 1.1rem;
|
|
text-wrap: nowrap;
|
|
}
|
|
.modal-content {
|
|
padding: 0.5rem;
|
|
overflow-y: auto;
|
|
flex-grow: 1;
|
|
}
|
|
.modal-footer {
|
|
padding: var(--spacing-sm) !important;
|
|
}
|
|
.section {
|
|
margin-bottom: 1.5rem;
|
|
padding: 1rem;
|
|
/* padding-bottom: 0; */
|
|
border: 1px solid var(--color-border);
|
|
border-radius: 0.5rem;
|
|
}
|
|
#buttons-container {
|
|
margin: 0 auto;
|
|
}
|
|
.btn {
|
|
padding: 0.5rem 1.7rem;
|
|
}
|
|
}
|
|
@media (max-width: 540px) {
|
|
.modal-header h2 {
|
|
font-size: var(--font-size-normal);
|
|
margin: 0;
|
|
}
|
|
#buttons-container {
|
|
max-height: 50px;
|
|
}
|
|
.btn {
|
|
text-wrap: wrap;
|
|
font-size: var(--font-size-small);
|
|
}
|
|
.btn-upload {
|
|
margin: 0 auto;
|
|
gap: 0.5rem;
|
|
align-items: center;
|
|
}
|
|
.btn-upload > svg {
|
|
width: 20px;
|
|
}
|
|
}
|
|
|
|
.loading {
|
|
--loading-delay: 500ms;
|
|
width: calc(100% - 4rem);
|
|
max-width: 1200px;
|
|
min-height: 50px;
|
|
border-radius: 12px;
|
|
background: var(--color-border);
|
|
position: relative;
|
|
overflow: hidden;
|
|
margin: 2rem auto;
|
|
opacity: 0;
|
|
animation: fadeIn 500ms ease-out var(--loading-delay) forwards;
|
|
}
|
|
|
|
@keyframes fadeIn {
|
|
0% {
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
.loading::before {
|
|
content: "";
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: linear-gradient(
|
|
90deg,
|
|
var(--color-background),
|
|
var(--color-border),
|
|
var(--color-background)
|
|
);
|
|
opacity: 0;
|
|
animation:
|
|
shimmer 2s linear var(--loading-delay) infinite,
|
|
fadeIn 0s linear var(--loading-delay) forwards;
|
|
background-size: 200% 100%;
|
|
}
|
|
|
|
@keyframes shimmer {
|
|
0% {
|
|
background-position: 200% 0;
|
|
}
|
|
100% {
|
|
background-position: -200% 0;
|
|
}
|
|
}
|
|
|
|
/* Confirm Dialog */
|
|
.confirm-dialog-backdrop {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: rgba(0, 0, 0, 0.5);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
z-index: 10000;
|
|
opacity: 0;
|
|
transition: opacity 0.2s ease;
|
|
}
|
|
|
|
.confirm-dialog-backdrop.visible {
|
|
opacity: 1;
|
|
}
|
|
|
|
.confirm-dialog {
|
|
background: var(--color-panel);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: 8px;
|
|
max-width: 450px;
|
|
width: 90%;
|
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
|
|
transform: scale(0.95);
|
|
transition: transform 0.2s ease;
|
|
}
|
|
|
|
.confirm-dialog-backdrop.visible .confirm-dialog {
|
|
transform: scale(1);
|
|
}
|
|
|
|
.confirm-dialog-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.75em;
|
|
padding: 1em 1.25em;
|
|
border-bottom: 1px solid var(--color-border);
|
|
}
|
|
|
|
.confirm-dialog-icon {
|
|
font-size: 1.5em;
|
|
}
|
|
|
|
.confirm-dialog-title {
|
|
font-size: 1.1em;
|
|
font-weight: 600;
|
|
color: var(--color-text);
|
|
}
|
|
|
|
.confirm-dialog-body {
|
|
padding: 1.25em;
|
|
color: var(--color-text);
|
|
line-height: 1.6;
|
|
font-size: 0.95em;
|
|
}
|
|
|
|
.confirm-dialog-body ul {
|
|
margin: 0.75em 0;
|
|
padding-left: 1.5em;
|
|
}
|
|
|
|
.confirm-dialog-body p {
|
|
margin: 0;
|
|
}
|
|
|
|
.confirm-dialog-footer {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 0.75em;
|
|
padding: 1em 1.25em;
|
|
border-top: 1px solid var(--color-border);
|
|
}
|
|
|
|
.confirm-dialog-footer .confirm-dialog-install-button {
|
|
padding-inline: 1.1rem;
|
|
}
|
|
|
|
.confirm-dialog-footer .confirm-dialog-plugin-scan-button {
|
|
padding-inline: 1.65rem;
|
|
font-size: 1rem;
|
|
}
|