mirror of
https://github.com/zhu1090093659/dsh-web.git
synced 2026-09-28 22:38:17 +08:00
The aggregate client bundle keyed every injected stylesheet tag by basename, so the eight same-named settings-card.module.css copies suppressed each other and seven family packages rendered their settings cards with UA defaults under every skin. Style tags now carry the full repo-relative file id. The shared card chrome lifts 12-13px hint text from label-tertiary to label-secondary (orca-link measures ~3.4:1 on tertiary) and points the error roles at state-error-primary, which the suite defines, instead of the nonexistent label-error token. sync-shared gains dsh-perf for the card chrome pair only: its settings-form.ts still runs the pre-0.1.2 per-field generation and must not be overwritten. Live GUI verified on 127.0.0.1:3080 under the orca-link skin and the default appearance.
418 lines
8.1 KiB
CSS
418 lines
8.1 KiB
CSS
/* Plugin settings card chrome + staged form fields.
|
|
* Aligned with the official ui-settings-plugins PluginCard / fields CSS:
|
|
* same semantic tokens, radius, typography and states so family cards read
|
|
* as siblings of the built-in Shell / Agent loop / Web search cards. */
|
|
|
|
.card {
|
|
border: 1px solid var(--dsw-alias-border-l2);
|
|
background: var(--dsw-alias-bg-layer-3);
|
|
border-radius: 12px;
|
|
list-style: none;
|
|
transition: border-color 0.16s, background 0.16s;
|
|
}
|
|
|
|
.card:hover {
|
|
border-color: var(--dsw-alias-label-dimmed);
|
|
}
|
|
|
|
.cardOpen {
|
|
background: var(--dsw-alias-bg-layer-2);
|
|
border-color: var(--dsw-alias-label-dimmed);
|
|
}
|
|
|
|
.header {
|
|
appearance: none;
|
|
width: 100%;
|
|
/* The suite does not force a global border-box, so width:100% + padding
|
|
would stretch the row 32px past the card and push the trailing pending
|
|
badge (last flex item) outside the card border. */
|
|
box-sizing: border-box;
|
|
font: inherit;
|
|
color: inherit;
|
|
text-align: left;
|
|
cursor: pointer;
|
|
background: transparent;
|
|
border: 0;
|
|
border-radius: 12px;
|
|
align-items: center;
|
|
gap: 12px;
|
|
padding: 14px 16px;
|
|
display: flex;
|
|
}
|
|
|
|
.header:focus-visible {
|
|
outline: 2px solid var(--dsw-alias-brand-primary);
|
|
outline-offset: -2px;
|
|
}
|
|
|
|
.headerStatic {
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
border-radius: 12px;
|
|
align-items: center;
|
|
gap: 12px;
|
|
padding: 14px 16px;
|
|
display: flex;
|
|
}
|
|
|
|
.headText {
|
|
flex-direction: column;
|
|
flex: 1;
|
|
gap: 4px;
|
|
min-width: 0;
|
|
display: flex;
|
|
}
|
|
|
|
.name {
|
|
color: var(--dsw-alias-label-primary);
|
|
font-size: 15px;
|
|
font-weight: 600;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.description {
|
|
/* Secondary, not tertiary: skins whose tertiary token is tuned for large
|
|
print leave 12-13px hint text below readable contrast (orca-link #778399
|
|
on cream measures ~3.4:1). */
|
|
color: var(--dsw-alias-label-secondary);
|
|
font-size: 13px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.pending {
|
|
white-space: nowrap;
|
|
background: var(--dsw-alias-bg-module-platform);
|
|
color: var(--dsw-alias-label-secondary);
|
|
border-radius: 999px;
|
|
flex: none;
|
|
padding: 1px 8px;
|
|
font-size: 11px;
|
|
font-weight: 500;
|
|
line-height: 17px;
|
|
}
|
|
|
|
.chevron {
|
|
color: var(--dsw-alias-label-tertiary);
|
|
flex: none;
|
|
transition: transform 0.16s;
|
|
}
|
|
|
|
.chevronOpen {
|
|
transform: rotate(180deg);
|
|
}
|
|
|
|
.body {
|
|
border-top: 1px solid var(--dsw-alias-border-l2);
|
|
margin: 0 16px;
|
|
padding-bottom: 8px;
|
|
}
|
|
|
|
.readOnly {
|
|
color: var(--dsw-alias-label-secondary);
|
|
margin: 12px 0 0;
|
|
font-size: 12px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.notExposed {
|
|
color: var(--dsw-alias-state-warn-primary);
|
|
margin: 12px 0 0;
|
|
font-size: 12px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.footer {
|
|
border-top: 1px solid var(--dsw-alias-border-l2);
|
|
justify-content: flex-end;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 12px 0 4px;
|
|
display: flex;
|
|
}
|
|
|
|
.failed {
|
|
min-width: 0;
|
|
/* The suite's error alias is state-error-primary; a label-error token does
|
|
not exist, so the var() would resolve to nothing and the message would
|
|
inherit the ink color, losing the failure signal. */
|
|
color: var(--dsw-alias-state-error-primary, #b42318);
|
|
flex: 1;
|
|
margin: 0;
|
|
font-size: 12px;
|
|
line-height: 1.5;
|
|
text-overflow: ellipsis;
|
|
overflow: hidden;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.discard,
|
|
.save {
|
|
appearance: none;
|
|
font: inherit;
|
|
cursor: pointer;
|
|
border: 1px solid transparent;
|
|
border-radius: 8px;
|
|
padding: 5px 14px;
|
|
font-size: 13px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.discard {
|
|
border-color: var(--dsw-alias-border-l2);
|
|
color: var(--dsw-alias-label-secondary);
|
|
background: transparent;
|
|
}
|
|
|
|
.discard:hover:not(:disabled) {
|
|
color: var(--dsw-alias-label-primary);
|
|
border-color: var(--dsw-alias-label-dimmed);
|
|
}
|
|
|
|
.save {
|
|
background: var(--dsw-alias-label-primary);
|
|
color: var(--dsw-alias-bg-layer-3);
|
|
}
|
|
|
|
.discard:disabled,
|
|
.save:disabled {
|
|
opacity: 0.4;
|
|
cursor: default;
|
|
}
|
|
|
|
.discard:focus-visible,
|
|
.save:focus-visible {
|
|
outline: 2px solid var(--dsw-alias-brand-primary);
|
|
outline-offset: 1px;
|
|
}
|
|
|
|
.field {
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
padding: 12px 0;
|
|
display: flex;
|
|
}
|
|
|
|
.field + .field {
|
|
border-top: 1px solid var(--dsw-alias-border-l2);
|
|
}
|
|
|
|
.head {
|
|
align-items: center;
|
|
gap: 8px;
|
|
display: flex;
|
|
}
|
|
|
|
.label {
|
|
min-width: 0;
|
|
color: var(--dsw-alias-label-primary);
|
|
flex: 1;
|
|
font-size: 13px;
|
|
font-weight: 500;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.badges {
|
|
align-items: center;
|
|
gap: 8px;
|
|
display: inline-flex;
|
|
}
|
|
|
|
.badge {
|
|
white-space: nowrap;
|
|
background: var(--dsw-alias-bg-module-platform);
|
|
color: var(--dsw-alias-label-secondary);
|
|
border-radius: 999px;
|
|
padding: 1px 8px;
|
|
font-size: 11px;
|
|
font-weight: 500;
|
|
line-height: 17px;
|
|
}
|
|
|
|
.reset {
|
|
font: inherit;
|
|
color: var(--dsw-alias-label-secondary);
|
|
cursor: pointer;
|
|
background: transparent;
|
|
border: none;
|
|
padding: 0;
|
|
font-size: 12px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.reset:hover:not(:disabled) {
|
|
color: var(--dsw-alias-label-primary);
|
|
}
|
|
|
|
.reset:disabled {
|
|
cursor: default;
|
|
}
|
|
|
|
.reset:focus-visible {
|
|
outline: 2px solid var(--dsw-alias-brand-primary);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
.reset:focus-visible {
|
|
outline: 2px solid var(--dsw-alias-brand-primary);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
.input,
|
|
.select {
|
|
border: 1px solid var(--dsw-alias-border-l2);
|
|
background: var(--dsw-alias-bg-layer-3);
|
|
height: 34px;
|
|
font: inherit;
|
|
color: var(--dsw-alias-label-primary);
|
|
border-radius: 8px;
|
|
padding: 0 12px;
|
|
font-size: 13px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.input:focus-visible,
|
|
.select:focus-visible {
|
|
border-color: var(--dsw-alias-brand-primary);
|
|
outline: none;
|
|
}
|
|
|
|
.input:disabled,
|
|
.select:disabled {
|
|
color: var(--dsw-alias-label-tertiary);
|
|
cursor: default;
|
|
}
|
|
|
|
.inputInvalid {
|
|
border: 1px solid var(--dsw-alias-state-error-primary, #b42318);
|
|
background: var(--dsw-alias-bg-layer-3);
|
|
height: 34px;
|
|
font: inherit;
|
|
color: var(--dsw-alias-label-primary);
|
|
border-radius: 8px;
|
|
padding: 0 12px;
|
|
font-size: 13px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.inputInvalid:focus-visible {
|
|
outline: 2px solid var(--dsw-alias-state-error-primary, #b42318);
|
|
outline-offset: 1px;
|
|
border-color: var(--dsw-alias-state-error-primary, #b42318);
|
|
}
|
|
|
|
.selectWrap {
|
|
position: relative;
|
|
}
|
|
|
|
.selectButton {
|
|
appearance: none;
|
|
width: 100%;
|
|
text-align: left;
|
|
cursor: pointer;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 8px;
|
|
display: flex;
|
|
}
|
|
|
|
.selectLabel {
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.selectChevron {
|
|
color: var(--dsw-alias-label-tertiary);
|
|
flex: none;
|
|
transition: transform 0.16s;
|
|
}
|
|
|
|
.selectChevronOpen {
|
|
transform: rotate(180deg);
|
|
}
|
|
|
|
.selectPopup {
|
|
position: absolute;
|
|
top: calc(100% + 4px);
|
|
left: 0;
|
|
right: 0;
|
|
z-index: 40;
|
|
flex-direction: column;
|
|
max-height: 240px;
|
|
overflow-y: auto;
|
|
border: 1px solid var(--dsw-alias-border-l2);
|
|
border-radius: 8px;
|
|
background: var(--dsw-alias-bg-layer-3);
|
|
box-shadow: 0 8px 24px var(--dsw-alias-bg-mask-2);
|
|
padding: 4px;
|
|
opacity: 0;
|
|
transform: translateY(-4px);
|
|
transition: opacity 0.1s ease, transform 0.1s ease;
|
|
display: flex;
|
|
}
|
|
|
|
.selectPopupOpen {
|
|
opacity: 1;
|
|
transform: none;
|
|
}
|
|
|
|
.selectPopupClose {
|
|
opacity: 0;
|
|
transform: translateY(-4px);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.selectOption {
|
|
/* 弹层是 max-height 受限的 flex 列:选项必须保持自然行高,超出交给弹层滚动 */
|
|
flex-shrink: 0;
|
|
border-radius: 6px;
|
|
padding: 6px 10px;
|
|
font-size: 13px;
|
|
line-height: 1.5;
|
|
color: var(--dsw-alias-label-primary);
|
|
cursor: pointer;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.selectOption:hover,
|
|
.selectOptionActive {
|
|
background: var(--dsw-alias-interactive-bg-hover);
|
|
}
|
|
|
|
.selectOptionSelected {
|
|
color: var(--dsw-alias-brand-primary);
|
|
font-weight: 500;
|
|
background: color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 10%, transparent);
|
|
}
|
|
|
|
.invalid {
|
|
color: var(--dsw-alias-state-error-primary, #b42318);
|
|
margin: 0;
|
|
font-size: 12px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.hint {
|
|
color: var(--dsw-alias-label-secondary);
|
|
margin: 0;
|
|
font-size: 12px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.card,
|
|
.header,
|
|
.chevron,
|
|
.chevronOpen,
|
|
.discard,
|
|
.save,
|
|
.selectChevron,
|
|
.selectChevronOpen,
|
|
.selectPopup {
|
|
transition: none;
|
|
}
|
|
}
|