agent-zero/webui/css/modals.css
Alessandro 0061b3a511 feat: add built-in plugin discovery cards to the welcome screen
Add the always-enabled `_discovery` plugin to turn the welcome screen into a discovery surface for the Plugin Hub and A0 integrations.

Includes a hero card plus Telegram, Email, and WhatsApp feature cards, with persistent dismiss/restore state, CTA routing to plugin config screens, and self-contained placeholder artwork. Implemented entirely through the existing WebUI extension mechanism with no core welcome-screen changes.

stores cleanup

layout polish and onboarding integration

Move feature card titles beside thumbnails for better space efficiency
and visibility. Restructure card markup and styles to support a fluid
grid layout and horizontal alignment.

Integrate discovery cards into the final onboarding step via a new
'onboarding-success-end' extension point, ensuring new users see
extension opportunities immediately after setup.

Hide discovery cards on the dashboard while the missing API key
onboarding banner is visible to reduce UI noise and user confusion during initial config.

update discovery card initialization and loading logic

Enhance the discovery store to fetch cards from the API, improving the dynamic loading of discovery cards based on user context. This change optimizes the user experience by ensuring relevant cards are displayed immediately after onboarding and when modals are closed.

And on top of that, there's a proper backend for these new cards.
2026-03-31 19:59:16 +02:00

609 lines
12 KiB
CSS

/* Modal Styles */
/* Until the full transition of A0 modals is complete,
consider these classes as part of the old modal system that will be deprecated soon
(currently used only by Settings modal). .modal-content, .modal-container, .modal-overlay
Do not maintain these classes, but be careful:
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: 2000;
}
.modal.show {
display: block;
}
.modal-inner {
display: flex;
flex-direction: column;
overflow: hidden;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: var(--color-background);
width: 90%;
max-width: 960px;
max-height: 90vh;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
z-index: 2;
}
/* Overlay (old system) */
.modal-overlay {
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: 2001;
}
/* Modal Backdrop */
.modal-backdrop {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 1;
cursor: pointer;
}
/* Modal Container (old system) */
.modal-container {
background-color: var(--color-panel);
border-radius: 12px;
width: 1100px; /* Reduced from 1200px to 1100px */
max-height: 90vh;
display: flex;
flex-direction: column;
overflow: hidden;
box-shadow: 0 4px 23px rgba(0, 0, 0, 0.2);
box-sizing: border-box;
}
/* Modal Header */
.modal-header {
display: grid;
grid-template-columns: 40fr 0.5fr;
align-items: center;
justify-content: space-between;
padding: 0.5rem 1.5rem 0.5rem 2rem;
background-color: var(--color-background);
color: var(--color-primary);
border-bottom: 1px solid var(--color-border);
}
.modal-header h2 {
margin: 0;
}
/* Modal Subheader */
.modal-subheader {
display: inline;
justify-content: space-between;
align-items: center;
padding: 0.7rem 1.5rem;
}
/* Modal Close Button */
.modal-close {
background: none;
border: none;
font-size: xx-large;
color: var(--color-text);
opacity: 0.7;
cursor: pointer;
padding: 0;
transition: opacity 0.2s;
}
.modal-close:hover {
opacity: 1;
}
/* 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-scroll {
max-height: 90vh;
overflow-y: auto;
padding: 1rem;
}
.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;
padding: var(--spacing-sm) var(--spacing-lg);
border-top: 1px solid var(--color-border);
background: var(--color-background);
gap: 1rem;
}
.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 var(--color-border);
background: var(--color-background);
}
/* 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;
padding: 0.5rem 1.5rem;
border-radius: 0.25rem;
cursor: pointer;
border: none;
font-size: 0.875rem;
font-family: "Rubik", Arial, Helvetica, sans-serif;
}
.btn.slim {
padding: 0.2em 0.4em;
}
.btn.primary {
background: #2196f3;
color: white;
width: fit-content;
align-items: center;
display: inline-flex;
}
.btn:disabled {
cursor: not-allowed;
}
.btn-ok {
background: #4248f1;
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 {
background: #353bc5;
}
.btn-ok:active {
background: #2b309c;
}
.btn-cancel {
background: transparent;
color: var(--color-accent);
border: 0.15rem solid var(--color-accent);
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 {
background: #2196f3;
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 {
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 500ms 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)
);
animation: shimmer 2s infinite;
animation-delay: 250ms;
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;
}