/* базовые компоненты 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-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; } .dd--up > .dd-menu { top: auto; bottom: calc(100% + var(--space-1)); } .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; } /* таблица: внутри ; шапка липнет; строки 44 px, hover — фоном. Узко — прокрутка внутри обёртки (@container page), а не превращение в карточки; там шапка не липнет (липкость внутри прокручиваемой обёртки сдвинула бы её на --topbar-h поверх первой строки). position: relative — чтобы .visually-hidden в ячейках не растягивал страницу за правый край. */ .ui-table-wrap { position: relative; overflow: clip; } /* --table-min: ширина, уже которой таблица не сжимается, а прокручивается (style={{"--table-min": "760px"}}) */ .ui-table { width: 100%; min-width: var(--table-min, 0); border-collapse: separate; border-spacing: 0; font-size: var(--fs-body); line-height: var(--lh-body); } .ui-table th, .ui-table td { height: 44px; padding: 0 var(--space-3); text-align: left; vertical-align: middle; border-bottom: 1px solid var(--color-border-default); } .ui-table tbody tr:last-child td { border-bottom: 0; } .ui-table th { position: sticky; top: var(--topbar-h, 0); z-index: 1; background: var(--color-bg-surface); color: var(--color-text-secondary); font-size: var(--fs-caption); line-height: var(--lh-caption); font-weight: 600; white-space: nowrap; } .ui-table th:first-child { border-top-left-radius: calc(var(--radius-xl) - 1px); } .ui-table th:last-child { border-top-right-radius: calc(var(--radius-xl) - 1px); } .ui-table td { color: var(--color-text-primary); } .ui-table td.num, .ui-table th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; } .ui-table tbody tr.is-clickable { cursor: pointer; } /* постоянные действия строки — IconButton в последней ячейке, справа */ .ui-table td.actions { width: 1%; white-space: nowrap; text-align: right; } .ui-table td.actions .ui-icon-btn + .ui-icon-btn { margin-left: var(--space-1); } .ui-table tbody tr:hover td { background: var(--color-bg-hover); } /* после правил шапки: при равной специфичности побеждает то, что ниже */ @container page (max-width: 1051.98px) { .ui-table-wrap { overflow-x: auto; } .ui-table th { position: static; } } /* просрочка/срок: цвет ошибки и полужирный у самой даты, без заливки строки; рядом visually-hidden «, просрочено» */ .ui-late { color: var(--color-status-error); font-weight: 600; } /* пустое состояние: по центру панели, вторичным текстом, с действием */ .ui-empty { display: flex; flex-direction: column; align-items: center; gap: var(--space-3); padding: var(--space-8) var(--space-4); text-align: center; color: var(--color-text-secondary); } .ui-empty__title { font-size: var(--fs-lg); line-height: var(--lh-lg); font-weight: 700; color: var(--color-text-primary); } /* строка фильтров над списком: поиск растягивается (до 480), остальное — по содержимому, перенос по ширине */ .ui-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin-bottom: var(--space-4); } .ui-toolbar > .ui-search { flex: 1 1 280px; max-width: 480px; } @container page (max-width: 607.98px) { .ui-toolbar > .ui-search { max-width: none; } } .ui-chips { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: calc(-1 * var(--space-2)) 0 var(--space-4); } /* форма и окно: поля столбцом с шагом 16, кнопки внизу справа («Отмена» слева от основной) */ .ui-form { display: flex; flex-direction: column; gap: var(--space-4); } .ui-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-2); } .ui-dialog__title { margin: 0 0 var(--space-4); font-size: var(--fs-lg); line-height: var(--lh-lg); font-weight: 700; } .ui-dialog__text { margin: 0 0 var(--space-2); color: var(--color-text-secondary); } /* цветная точка категории: */ .ui-dot { display: inline-block; flex: none; width: 8px; height: 8px; border-radius: var(--radius-round); background: var(--dot, currentColor); vertical-align: middle; }