sdlc-hub/web/src/ui/ui.css
Andrey Epifancev 0a5ca2e00a fix(web): правки по финальному ревью: пометка хаба на доске, кнопка в загрузке, панель данных, контраст предупреждений (#65)
I-1 пометка «Хаб · данные на» убрана с доски; I-2 кнопка в loading сохраняет вид варианта;
I-3 статус пакета — постоянный live-регион, не сдвигает кнопку и высоту панели; I-4 текст
предупреждений затемнён через color-mix; M-1 точка «агент офлайн» и событие — предупреждение;
M-7 ошибка настроек в Notice; M-9 убраны IconGrid и IconReset; M-15 IBM Plex Mono 600;
M-16 aria-controls только при раскрытой сетке фильтров.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 01:52:58 +04:00

219 lines
16 KiB
CSS
Raw 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.

/* базовые компоненты дизайн-системы AURA: только переменные из styles/tokens.css, веса 400/600/700 */
.ui-btn, .ui-icon-btn, .ui-seg__item, .ui-theme, .ui-chip__x {
font-family: var(--font-ui); cursor: pointer;
transition: background var(--motion), border-color var(--motion), color var(--motion);
}
.ui-btn:focus-visible, .ui-icon-btn:focus-visible, .ui-seg__item:focus-visible, .ui-theme:focus-visible, .ui-chip__x:focus-visible {
outline: 2px solid var(--color-focus-ring); outline-offset: 2px;
}
.ui-btn {
display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
height: var(--control-h); padding: 0 var(--space-4); border: 1px solid transparent; border-radius: var(--radius-round);
font-size: var(--fs-body); line-height: var(--lh-body); font-weight: 600; white-space: nowrap;
}
.ui-btn--lg { height: var(--control-h-lg); padding: 0 var(--space-5); }
.ui-btn--primary { background: var(--color-action-primary); color: var(--color-text-on-primary); }
.ui-btn--primary:hover:not(:disabled) { background: var(--color-action-primary-hover); }
.ui-btn--secondary { background: transparent; border-color: var(--color-border-strong); color: var(--color-text-primary); }
.ui-btn--secondary:hover:not(:disabled) { border-color: var(--color-action-primary); }
.ui-btn--secondary[aria-pressed="true"] {
background: var(--color-bg-selected); border-color: var(--color-action-primary); color: var(--color-action-primary);
}
.ui-btn--danger { background: var(--color-action-danger); color: var(--color-text-on-primary); }
.ui-btn--danger:hover:not(:disabled) { background: var(--color-action-danger-hover); }
.ui-btn--ghost { background: transparent; color: var(--color-action-primary); }
.ui-btn--ghost:hover:not(:disabled) { background: var(--color-bg-hover); color: var(--color-action-primary-hover); }
.ui-btn:disabled { cursor: not-allowed; color: var(--color-text-disabled); }
.ui-btn--primary:disabled, .ui-btn--danger:disabled { background: var(--color-bg-track); border-color: var(--color-border-default); }
.ui-btn[aria-busy="true"] { cursor: progress; }
/* загрузка: вид своего варианта, а не серая «выключенная» кнопка (AURA); повторный щелчок невозможен — disabled */
.ui-btn--primary[aria-busy="true"]:disabled { background: var(--color-action-primary); border-color: transparent; color: var(--color-text-on-primary); }
.ui-btn--danger[aria-busy="true"]:disabled { background: var(--color-action-danger); border-color: transparent; color: var(--color-text-on-primary); }
.ui-btn--secondary[aria-busy="true"]:disabled { color: var(--color-text-primary); }
.ui-btn--ghost[aria-busy="true"]:disabled { color: var(--color-action-primary); }
.ui-btn--primary[aria-busy="true"] .ui-spinner, .ui-btn--danger[aria-busy="true"] .ui-spinner {
border-color: color-mix(in srgb, var(--color-text-on-primary) 35%, transparent); border-top-color: var(--color-text-on-primary);
}
.ui-spinner {
width: 16px; height: 16px; border-radius: var(--radius-round);
border: 2px solid var(--color-border-strong); border-top-color: var(--color-action-primary);
animation: ui-spin 800ms linear infinite;
}
@keyframes ui-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .ui-spinner { animation-duration: 2400ms; } }
.ui-icon-btn {
display: inline-flex; align-items: center; justify-content: center; width: var(--control-h); height: var(--control-h);
padding: 0; border: 1px solid transparent; border-radius: var(--control-radius); background: transparent; color: var(--color-text-secondary);
}
.ui-icon-btn:hover:not(:disabled) { background: var(--color-bg-hover); border-color: var(--color-border-strong); color: var(--color-text-primary); }
.ui-icon-btn:disabled { cursor: not-allowed; color: var(--color-text-disabled); }
.ui-seg {
display: inline-flex; gap: var(--space-1); padding: var(--space-1); border-radius: var(--radius-round); background: var(--color-bg-track);
}
.ui-seg__item {
display: inline-flex; align-items: center; height: 24px; padding: 0 var(--space-4); border: 1px solid transparent;
border-radius: var(--radius-round); background: transparent; color: var(--color-text-secondary);
font-size: var(--fs-body); line-height: var(--lh-body); font-weight: 400; text-decoration: none; white-space: nowrap;
}
.ui-seg__item:hover { color: var(--color-text-primary); }
.ui-seg__item[aria-checked="true"], .ui-seg__item[aria-current="page"] {
background: var(--color-bg-surface); border-color: var(--color-border-selected); color: var(--color-action-primary); font-weight: 600;
}
.ui-theme {
display: inline-flex; align-items: center; width: 44px; height: 24px; padding: 2px; border: 1px solid var(--color-border-strong);
border-radius: var(--radius-round); background: var(--color-bg-track); color: var(--color-text-secondary);
}
.ui-theme__knob {
display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border-radius: var(--radius-round);
background: var(--color-bg-surface); box-shadow: inset 0 0 0 1px var(--color-border-default); transition: transform var(--motion);
}
.ui-theme[aria-checked="true"] { border-color: var(--color-border-selected); color: var(--color-action-primary); }
.ui-theme[aria-checked="true"] .ui-theme__knob { transform: translateX(20px); }
.ui-badge {
display: inline-flex; align-items: center; height: 20px; padding: 0 var(--space-2); border: 1px solid transparent;
border-radius: var(--radius-round); font-size: var(--fs-caption); line-height: var(--lh-caption); font-weight: 600; white-space: nowrap;
}
.ui-badge--neutral { background: var(--color-bg-track); border-color: var(--color-border-default); color: var(--color-text-secondary); }
.ui-badge--success { background: var(--color-status-success-bg); border-color: var(--color-status-success); color: var(--color-status-success); }
.ui-badge--error { background: var(--color-status-error-bg); border-color: var(--color-status-error); color: var(--color-status-error); }
.ui-badge--warning { background: var(--color-status-warning-bg); border-color: var(--color-status-warning-border); color: color-mix(in srgb, var(--color-status-warning) 55%, var(--color-text-primary)); }
.ui-badge--info { background: var(--color-bg-subtle); border-color: var(--color-border-strong); color: var(--color-text-primary); }
.ui-chip {
display: inline-flex; align-items: center; gap: var(--space-1); height: 24px; padding: 0 var(--space-1) 0 var(--space-3);
border: 1px solid var(--color-border-selected); border-radius: var(--radius-round); background: var(--color-bg-selected);
color: var(--color-action-primary); font-size: var(--fs-caption); line-height: var(--lh-caption); font-weight: 600;
}
.ui-chip__x {
display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; padding: 0; border: 0;
border-radius: var(--radius-round); background: transparent; color: inherit;
}
.ui-chip__x:hover { background: var(--color-bg-hover); }
.ui-notice {
display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-3) var(--space-4);
border: 1px solid var(--color-border-default); border-radius: var(--radius-lg); background: var(--color-bg-subtle);
}
.ui-notice__icon {
display: inline-flex; flex: none; align-items: center; justify-content: center; width: 20px; height: 20px;
border-radius: var(--radius-round); color: var(--color-text-on-primary); background: var(--color-text-secondary);
}
.ui-notice__body { flex: 1; min-width: 0; }
.ui-notice__title { font-size: var(--fs-body); line-height: var(--lh-body); font-weight: 600; color: var(--color-text-primary); }
.ui-notice__text { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--color-text-primary); }
.ui-notice__action { flex: none; }
.ui-notice a { color: var(--color-action-primary); }
.ui-notice--warning a { color: var(--color-text-primary); text-decoration: underline; }
.ui-notice--success { background: var(--color-status-success-bg); border-color: var(--color-status-success); }
.ui-notice--success .ui-notice__icon { background: var(--color-status-success); }
.ui-notice--error { background: var(--color-status-error-bg); border-color: var(--color-status-error); }
.ui-notice--error .ui-notice__icon { background: var(--color-status-error); }
.ui-notice--warning { background: var(--color-status-warning-bg); border-color: var(--color-status-warning-border); }
.ui-notice--warning .ui-notice__icon { background: var(--color-status-warning); }
.ui-panel {
background: var(--color-bg-surface); border: 1px solid var(--color-border-default); border-radius: var(--radius-xl);
}
.ui-panel--md { padding: var(--space-4); }
.ui-panel--lg { padding: var(--space-6); }
.ui-panel--none { padding: 0; }
.ui-page-header { display: flex; flex-direction: column; gap: var(--space-4); margin-bottom: var(--space-4); }
.ui-page-header__row { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--space-4); }
.ui-page-header__text { min-width: 0; }
.ui-page-header__title { margin: 0; font-size: var(--fs-section); line-height: var(--lh-section); font-weight: 700; color: var(--color-text-primary); }
.ui-page-header__subtitle { margin: var(--space-1) 0 0; font-size: var(--fs-body); line-height: var(--lh-body); color: var(--color-text-secondary); }
.ui-page-header__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
/* поля */
.ui-field { display: flex; flex-direction: column; gap: var(--space-1); }
.ui-field__label { font-size: var(--fs-body); line-height: var(--lh-body); font-weight: 600; color: var(--color-text-primary); }
.ui-field__hint { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--color-text-secondary); }
.ui-field__error { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--color-status-error); }
.ui-input {
box-sizing: border-box; width: 100%; height: var(--control-h); padding: 0 var(--space-3);
border: 1px solid var(--color-border-default); border-radius: var(--control-radius);
background: var(--color-bg-surface); color: var(--color-text-primary);
font: inherit; font-family: var(--font-ui); font-size: var(--fs-body); line-height: var(--lh-body);
transition: border-color var(--motion), box-shadow var(--motion);
}
.ui-input--lg { height: var(--control-h-lg); }
.ui-input::placeholder { color: var(--color-text-placeholder); }
.ui-input:hover:not(:disabled) { border-color: var(--color-border-strong); }
.ui-input:focus-visible { outline: 2px solid var(--color-focus-ring); outline-offset: 2px; border-color: var(--color-action-primary); }
.ui-input[aria-invalid="true"] { border-color: var(--color-status-error); }
.ui-input:disabled { cursor: not-allowed; color: var(--color-text-disabled); background: var(--color-bg-track); }
.ui-textarea { height: auto; min-height: 80px; padding: var(--space-2) var(--space-3); resize: vertical; }
.ui-search { position: relative; display: inline-flex; align-items: center; width: 100%; }
.ui-search__icon { position: absolute; left: var(--space-3); display: inline-flex; color: var(--color-text-secondary); pointer-events: none; }
.ui-search__input { padding-left: calc(var(--space-3) + 24px); padding-right: calc(var(--space-2) + var(--control-h)); }
.ui-search__input::-webkit-search-cancel-button { display: none; }
.ui-search__clear { position: absolute; right: 0; }
.ui-select { position: relative; display: inline-flex; align-items: center; width: 100%; }
.ui-select__control { appearance: none; padding-right: calc(var(--space-3) + 24px); cursor: pointer; }
.ui-select--lg .ui-select__control { height: var(--control-h-lg); }
.ui-select__chevron { position: absolute; right: var(--space-3); display: inline-flex; color: var(--color-text-secondary); pointer-events: none; }
.ui-check { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--fs-body); line-height: var(--lh-body); color: var(--color-text-primary); cursor: pointer; }
.ui-check__box { width: 16px; height: 16px; margin: 0; border-radius: var(--radius-xs); accent-color: var(--color-action-primary); cursor: pointer; }
.ui-check__box:focus-visible { outline: 2px solid var(--color-focus-ring); outline-offset: 2px; }
/* окно */
.ui-dialog {
box-sizing: border-box; max-width: none; max-height: 90vh; padding: var(--space-6); overflow: auto;
border: 1px solid var(--color-border-default); border-radius: var(--radius-2xl);
background: var(--color-bg-surface); color: var(--color-text-primary); box-shadow: var(--shadow-dialog);
font-family: var(--font-ui);
}
.ui-dialog::backdrop { background: var(--color-overlay); }
.ui-dialog--sm { width: min(480px, calc(100vw - 32px)); }
.ui-dialog--md { width: min(640px, calc(100vw - 32px)); }
.ui-dialog--lg { width: min(1000px, calc(100vw - 32px)); }
@media (max-width: 700px) {
.ui-dialog { width: 100vw; max-width: 100vw; height: 100vh; max-height: 100vh; margin: 0; border-radius: 0; }
}
/* выпадающая панель и меню: пункты — кнопки; «выбрано» — цветом текста и галочкой */
.dd { position: relative; display: inline-block; }
.dd-menu {
position: absolute; top: calc(100% + var(--space-1)); left: 0; z-index: 20; min-width: 280px; max-width: 420px;
display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-2);
background: var(--color-bg-surface); border: 1px solid var(--color-border-default); border-radius: var(--radius-lg);
box-shadow: var(--shadow-popover); color: var(--color-text-primary); font-family: var(--font-ui);
}
.dd-menu.menu { right: 0; left: auto; min-width: 230px; gap: 0; padding: var(--space-1); }
.dd-list { max-height: 260px; overflow: auto; display: flex; flex-direction: column; }
.dd-item {
display: flex; align-items: center; gap: var(--space-2); padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm);
font-size: var(--fs-body); line-height: var(--lh-body); cursor: pointer;
}
.dd-item:hover { background: var(--color-bg-hover); }
.dd-item input { flex: none; width: 16px; height: 16px; margin: 0; accent-color: var(--color-action-primary); cursor: pointer; }
.dd-item input:focus-visible { outline: 2px solid var(--color-focus-ring); outline-offset: 2px; }
.dd-item .n { margin-left: auto; font-size: var(--fs-caption); color: var(--color-text-secondary); font-variant-numeric: tabular-nums; }
.dd-item.none { color: var(--color-text-secondary); font-style: italic; }
.dd-item.zero { opacity: .5; }
.dd-empty { padding: var(--space-2); font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--color-text-secondary); }
.dd-foot { display: flex; gap: var(--space-2); justify-content: space-between; border-top: 1px solid var(--color-border-default); padding-top: var(--space-2); }
.dd--start > .dd-menu.menu { left: 0; right: auto; }
.menu button {
display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); width: 100%;
min-height: var(--control-h); padding: var(--space-1) var(--space-3); border: 0; border-radius: var(--radius-sm);
background: none; color: var(--color-text-primary); font: inherit; font-family: var(--font-ui);
font-size: var(--fs-body); line-height: var(--lh-body); text-align: left; cursor: pointer;
transition: background var(--motion), color var(--motion);
}
.menu button:hover { background: var(--color-bg-hover); }
.menu button:focus-visible { outline: 2px solid var(--color-focus-ring); outline-offset: -2px; background: var(--color-bg-hover); }
.menu button[aria-pressed="true"] { color: var(--color-action-primary); }
.menu button[aria-pressed="true"]::after { content: "✓"; font-weight: 600; }
.menu button.danger { color: var(--color-status-error); }
.menu hr { border: 0; border-top: 1px solid var(--color-border-default); margin: var(--space-1) 0; }