mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-25 12:21:17 +00:00
* feat(ui): add settings design-language foundation (tokens, settings.css, helpers) * refactor(ui): move settings workspace shell styles into settings.css * refactor(ui): migrate all settings surfaces to the unified settings design language Every settings surface (General quick+advanced schema form, Appearance, Communications, Automation, MCP, Infrastructure, AI Agents, Channels, Connection, About, Profile, Model Providers, Plugins, Skills, Skill Workshop chrome, Devices, Worktrees, Debug, Logs, Activity, Automations, Sessions, Usage chrome) now renders through the settings-ui helpers and settings.css: sections as plain uppercase headings outside one flat group surface, hairline-divided rows, a single toggle/segmented/status vocabulary, status dots instead of pills, and no cards-in-cards or enter animations. Deletes the qs-*/cfg-*/config-section-card/account-card/ plugins-row/cron-editor-card/session-badge/agent-pill families and orphaned shared rules. * style(ui-docs): format design-system docs * fix(ui): make activity statusKind lookup exhaustive for consistent-return lint * fix(ui): address settings design-language review findings Label-wrapped toggle rows with required accessible names, named selects and cron form controls, busy-disabled segmented controls with restored theme-transition anchors, collapsible skill groups, semantic plugin headings, gateway connected status, paired-devices empty state, logs subtitle, cron prompt help, and keyboard-accessible session goal objectives. * fix(ui): harden settings primitives per review round two Wrap row action clusters, fully-inset nav focus ring, restore number steppers in the schema form, cap node capability lines, keep the named Activity region landmark, and associate cron help text via the row label. * fix(ui): skip empty section headings and fix the toggle doc example * docs(ui): import renderSettingsToggleRow in the settings example * fix(ui): rename number stepper delta to avoid shadowing
422 lines
9.1 KiB
CSS
422 lines
9.1 KiB
CSS
/* ── Config page leftovers ─────────────────────────────────────────────────
|
|
*
|
|
* Quick Settings now renders through the shared settings design language
|
|
* (ui/src/styles/settings.css). This file keeps only genuinely page-specific
|
|
* rules: the logs-page fill layout, the Simple/Advanced view toggle, the
|
|
* advanced-view accordion nav (used by view.ts), and the two documented
|
|
* escape hatches (identity blocks, gateway-host stats grid).
|
|
*/
|
|
|
|
.content:has(openclaw-logs-page) {
|
|
overflow: hidden;
|
|
}
|
|
|
|
.content:has(openclaw-logs-page) > openclaw-router-outlet {
|
|
display: flex;
|
|
flex-direction: column;
|
|
margin-top: 0;
|
|
min-height: 0;
|
|
height: 100%;
|
|
width: 100%;
|
|
}
|
|
|
|
openclaw-logs-page {
|
|
display: contents;
|
|
}
|
|
|
|
.content:has(openclaw-logs-page) .content-header {
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
.settings-workspace--fill-height .logs-card {
|
|
flex: 1 1 auto;
|
|
min-height: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.settings-workspace--fill-height .log-stream {
|
|
flex: 1 1 auto;
|
|
min-height: 0;
|
|
max-height: none;
|
|
}
|
|
|
|
/* Persistent Simple/Advanced switch in the page header; keeps the way back
|
|
from advanced settings visible at all times. */
|
|
.config-view-toggle {
|
|
flex: 0 0 auto;
|
|
align-self: center;
|
|
}
|
|
|
|
/* Mobile fallback: layout.mobile.css hides .content-header at small widths,
|
|
which would strand users in advanced mode with no way back. Mirror the
|
|
switch in an in-body row that only shows when the header is hidden. */
|
|
.config-view-toggle-row {
|
|
display: none;
|
|
}
|
|
|
|
@media (max-width: 768px), (max-width: 932px) and (max-height: 500px) and (orientation: landscape) {
|
|
.config-view-toggle-row {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
width: 100%;
|
|
max-width: 760px;
|
|
margin: 0 auto;
|
|
padding: var(--space-3) var(--space-4) 0;
|
|
}
|
|
}
|
|
|
|
/* ── Config Accordion Nav (Advanced Settings, rendered by view.ts) ── */
|
|
|
|
.config-accordion-nav {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.config-accordion-group {
|
|
border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
|
|
border-radius: var(--radius-md);
|
|
margin-bottom: 4px;
|
|
overflow: hidden;
|
|
transition: border-color var(--duration-fast) var(--ease-out);
|
|
}
|
|
|
|
.config-accordion-group:hover {
|
|
border-color: var(--border);
|
|
}
|
|
|
|
.config-accordion-group__header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
width: 100%;
|
|
padding: 12px 16px;
|
|
font-size: 0.8125rem;
|
|
font-weight: 650;
|
|
letter-spacing: -0.01em;
|
|
color: var(--text-strong);
|
|
background: color-mix(in srgb, var(--bg-elevated) 50%, var(--card) 50%);
|
|
border: none;
|
|
transition: background var(--duration-fast) var(--ease-out);
|
|
}
|
|
|
|
.config-accordion-group__header:hover {
|
|
background: var(--bg-hover);
|
|
}
|
|
|
|
.config-accordion-group__header--active {
|
|
background: var(--bg-hover);
|
|
}
|
|
|
|
.config-accordion-group__icon {
|
|
display: flex;
|
|
align-items: center;
|
|
color: var(--accent);
|
|
opacity: 0.7;
|
|
}
|
|
|
|
.config-accordion-group__icon svg {
|
|
width: 16px;
|
|
height: 16px;
|
|
}
|
|
|
|
.config-accordion-group__chevron {
|
|
margin-left: auto;
|
|
opacity: 0.35;
|
|
transition: transform var(--duration-normal) var(--ease-out);
|
|
}
|
|
|
|
.config-accordion-group__chevron--open {
|
|
transform: rotate(180deg);
|
|
}
|
|
|
|
.config-accordion-group__items {
|
|
border-top: 1px solid color-mix(in srgb, var(--border) 50%, transparent);
|
|
padding: 4px 0;
|
|
background: var(--card);
|
|
}
|
|
|
|
.config-accordion-group__item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
width: 100%;
|
|
padding: 9px 16px 9px 40px;
|
|
font-size: 0.8125rem;
|
|
font-weight: 450;
|
|
color: var(--muted);
|
|
background: none;
|
|
border: none;
|
|
transition:
|
|
background var(--duration-fast) var(--ease-out),
|
|
color var(--duration-fast) var(--ease-out);
|
|
}
|
|
|
|
.config-accordion-group__item:hover {
|
|
background: var(--bg-hover);
|
|
color: var(--text);
|
|
}
|
|
|
|
.config-accordion-group__item--active {
|
|
color: var(--accent);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.config-accordion-group__item-icon {
|
|
display: flex;
|
|
align-items: center;
|
|
opacity: 0.45;
|
|
}
|
|
|
|
.config-accordion-group__item-icon svg {
|
|
width: 14px;
|
|
height: 14px;
|
|
}
|
|
|
|
/* ── Escape hatch: Personal identity blocks (avatar-led rows) ──
|
|
The standard settings row (text left, one control right) cannot lead with
|
|
an avatar preview; these blocks stay inside one .settings-group and match
|
|
the row paddings. */
|
|
|
|
.config-identity {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: var(--space-3);
|
|
padding: var(--space-3) var(--space-4);
|
|
min-width: 0;
|
|
}
|
|
|
|
.config-identity + .config-identity {
|
|
border-top: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
|
|
}
|
|
|
|
.config-identity__avatar {
|
|
width: 48px;
|
|
height: 48px;
|
|
flex: 0 0 auto;
|
|
border-radius: var(--radius-md);
|
|
border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
|
|
object-fit: cover;
|
|
object-position: center;
|
|
}
|
|
|
|
.config-identity__avatar--text,
|
|
.config-identity__avatar--default {
|
|
display: grid;
|
|
place-items: center;
|
|
background: var(--accent-subtle);
|
|
color: var(--accent);
|
|
font-size: var(--control-ui-text-md);
|
|
font-weight: 650;
|
|
}
|
|
|
|
.config-identity__avatar--fallback {
|
|
padding: var(--space-2);
|
|
background: color-mix(in srgb, var(--bg) 84%, var(--bg-elevated) 16%);
|
|
object-fit: contain;
|
|
}
|
|
|
|
.config-identity__avatar--default svg {
|
|
width: 18px;
|
|
height: 18px;
|
|
fill: currentColor;
|
|
}
|
|
|
|
.config-identity__copy {
|
|
min-width: 0;
|
|
flex: 1 1 auto;
|
|
}
|
|
|
|
.config-identity__eyebrow {
|
|
font-size: var(--control-ui-text-xs);
|
|
font-weight: 600;
|
|
letter-spacing: 0.06em;
|
|
text-transform: uppercase;
|
|
color: var(--muted);
|
|
}
|
|
|
|
.config-identity__title {
|
|
font-size: var(--control-ui-text-md);
|
|
font-weight: 500;
|
|
color: var(--text-strong);
|
|
line-height: 1.35;
|
|
overflow-wrap: anywhere;
|
|
}
|
|
|
|
.config-identity__sub {
|
|
margin-top: 2px;
|
|
font-size: var(--control-ui-text-sm);
|
|
color: var(--muted);
|
|
line-height: 1.45;
|
|
}
|
|
|
|
.config-identity__source {
|
|
display: grid;
|
|
gap: 2px;
|
|
margin-top: var(--space-2);
|
|
font-size: var(--control-ui-text-xs);
|
|
color: var(--muted);
|
|
}
|
|
|
|
.config-identity__source code {
|
|
color: var(--text);
|
|
font-family: var(--mono);
|
|
font-size: var(--control-ui-text-xs);
|
|
overflow-wrap: anywhere;
|
|
}
|
|
|
|
.config-identity__issue {
|
|
margin-top: var(--space-2);
|
|
}
|
|
|
|
.config-identity__error {
|
|
margin-top: var(--space-2);
|
|
color: var(--danger);
|
|
font-size: var(--control-ui-text-sm);
|
|
line-height: 1.35;
|
|
}
|
|
|
|
.config-identity__repair {
|
|
display: grid;
|
|
gap: var(--space-2);
|
|
margin-top: var(--space-2);
|
|
}
|
|
|
|
.config-identity__field {
|
|
display: grid;
|
|
gap: var(--space-1);
|
|
max-width: 320px;
|
|
}
|
|
|
|
.config-identity__field-label {
|
|
font-size: var(--control-ui-text-sm);
|
|
color: var(--muted);
|
|
}
|
|
|
|
.config-identity__actions {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: var(--space-2);
|
|
}
|
|
|
|
.config-identity__actions .btn {
|
|
width: fit-content;
|
|
}
|
|
|
|
.config-identity__hint {
|
|
font-size: var(--control-ui-text-sm);
|
|
line-height: 1.45;
|
|
}
|
|
|
|
/* ── Escape hatch: Gateway host identity + metered stats grid ──
|
|
A genuine two-column stat grid with usage meters; stays flat (no nested
|
|
borders/surfaces) inside one .settings-group with row-matched paddings. */
|
|
|
|
.config-host {
|
|
display: grid;
|
|
grid-template-columns: minmax(180px, 240px) minmax(0, 1fr);
|
|
gap: var(--space-4) var(--space-5);
|
|
align-items: start;
|
|
padding: var(--space-3) var(--space-4);
|
|
}
|
|
|
|
.config-host__identity {
|
|
display: grid;
|
|
align-content: start;
|
|
gap: var(--space-1);
|
|
min-width: 0;
|
|
}
|
|
|
|
.config-host__name {
|
|
font-size: var(--control-ui-text-md);
|
|
font-weight: 600;
|
|
line-height: 1.3;
|
|
color: var(--text-strong);
|
|
overflow-wrap: anywhere;
|
|
}
|
|
|
|
.config-host__meta {
|
|
font-size: var(--control-ui-text-sm);
|
|
line-height: 1.4;
|
|
color: var(--muted);
|
|
}
|
|
|
|
.config-host__address {
|
|
font-family: var(--mono);
|
|
font-size: var(--control-ui-text-xs);
|
|
color: var(--text);
|
|
overflow-wrap: anywhere;
|
|
}
|
|
|
|
.config-host__stats {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(min(140px, 100%), 1fr));
|
|
gap: var(--space-3);
|
|
}
|
|
|
|
.config-host__stat {
|
|
display: grid;
|
|
align-content: start;
|
|
gap: var(--space-1);
|
|
min-width: 0;
|
|
}
|
|
|
|
.config-host__stat-label {
|
|
font-size: var(--control-ui-text-xs);
|
|
font-weight: 600;
|
|
letter-spacing: 0.06em;
|
|
text-transform: uppercase;
|
|
color: var(--muted);
|
|
}
|
|
|
|
.config-host__stat-value {
|
|
display: flex;
|
|
align-items: baseline;
|
|
gap: var(--space-1);
|
|
font-size: var(--control-ui-text-lg);
|
|
font-weight: 600;
|
|
line-height: 1.2;
|
|
color: var(--text-strong);
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
.config-host__stat-unit {
|
|
font-size: var(--control-ui-text-xs);
|
|
font-weight: 500;
|
|
color: var(--muted);
|
|
}
|
|
|
|
.config-host__stat-detail {
|
|
font-size: var(--control-ui-text-xs);
|
|
line-height: 1.35;
|
|
color: var(--muted);
|
|
overflow-wrap: anywhere;
|
|
}
|
|
|
|
.config-host__meter {
|
|
height: 4px;
|
|
border-radius: var(--radius-full);
|
|
background: color-mix(in srgb, var(--border) 55%, transparent);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.config-host__meter-fill {
|
|
width: var(--config-host-meter-fill, 0%);
|
|
height: 100%;
|
|
border-radius: inherit;
|
|
background: var(--ok);
|
|
}
|
|
|
|
.config-host__meter-fill--warn {
|
|
background: var(--warn);
|
|
}
|
|
|
|
.config-host__meter-fill--critical {
|
|
background: var(--danger);
|
|
}
|
|
|
|
@media (max-width: 640px) {
|
|
.config-host {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
}
|