/* * Единая визуальная основа Magistr. * * Файл подключается последним во всех пользовательских оболочках и задаёт * общие инварианты: типографику, размеры элементов управления, фокус, * радиусы, ритм и поведение на узких экранах. Локальные CSS отвечают только * за компоновку и предметные компоненты конкретного раздела. */ :root { --ui-font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; --ui-font-display: var(--ui-font-sans); --ui-font-mono: "Cascadia Mono", "SFMono-Regular", Consolas, monospace; --ui-control-sm: 32px; --ui-control-md: 40px; --ui-control-lg: 48px; --ui-radius-control: 8px; --ui-radius-field: 10px; --ui-radius-panel: 16px; --ui-radius-large: 24px; --ui-space-1: 4px; --ui-space-2: 8px; --ui-space-3: 12px; --ui-space-4: 16px; --ui-space-5: 20px; --ui-space-6: 24px; --ui-space-8: 32px; --ui-shadow-panel: 0 12px 32px rgba(15, 23, 42, 0.08); --ui-shadow-floating: 0 20px 56px rgba(15, 23, 42, 0.18); --ui-transition: 160ms cubic-bezier(0.2, 0, 0, 1); --ui-focus-ring: var(--button-focus-ring, rgba(79, 70, 229, 0.35)); /* Совместимость с уже существующими токенами разделов. */ --button-radius: var(--ui-radius-control); } html { color-scheme: dark; font-size: 16px; text-size-adjust: 100%; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } html[data-theme="light"] { color-scheme: light; } body { font-family: var(--ui-font-sans); font-size: 1rem; line-height: 1.5; text-rendering: optimizeLegibility; } button, input, select, textarea { font: inherit; letter-spacing: inherit; } button, [role="button"], a { -webkit-tap-highlight-color: transparent; } h1, h2, h3, h4, h5, h6 { font-family: var(--ui-font-display); font-weight: 700; line-height: 1.18; letter-spacing: -0.025em; text-wrap: balance; } p, li, dd { text-wrap: pretty; } time, input[type="date"], input[type="time"], .schedule-overview-next-time, .academic-year-code, .version-number, .metric-value { font-variant-numeric: tabular-nums; } ::selection { background: color-mix(in srgb, var(--accent, #4f46e5) 28%, transparent); } /* ===== Доступный фокус ===== */ :where(a, button, input, select, textarea, [tabindex]):focus-visible { outline: 2px solid var(--accent, #4f46e5); outline-offset: 2px; } :where(input, select, textarea):focus-visible { border-color: var(--accent, #4f46e5); box-shadow: 0 0 0 3px var(--ui-focus-ring); } /* ===== Кнопки ===== */ .btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--ui-space-2); min-width: 0; min-height: var(--ui-control-md); padding: 0 var(--ui-space-4); border: 1px solid var(--button-secondary-border, var(--panel-border, var(--bg-card-border))); border-radius: var(--ui-radius-control); font-family: var(--ui-font-sans); font-size: 0.875rem; font-weight: 650; line-height: 1; text-align: center; text-decoration: none; white-space: nowrap; cursor: pointer; user-select: none; transition: background-color var(--ui-transition), border-color var(--ui-transition), color var(--ui-transition), box-shadow var(--ui-transition), transform var(--ui-transition); } .btn:hover:not(:disabled):not([aria-disabled="true"]) { transform: translateY(-1px); } .btn:active:not(:disabled):not([aria-disabled="true"]) { transform: translateY(0); } .btn:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--ui-focus-ring); } .btn:disabled, .btn[aria-disabled="true"] { cursor: not-allowed; opacity: 0.62; transform: none; } .btn-sm { min-height: var(--ui-control-sm); padding-inline: var(--ui-space-3); font-size: 0.8125rem; } .btn-md { min-height: var(--ui-control-md); padding-inline: var(--ui-space-4); font-size: 0.875rem; } .btn-lg { min-height: var(--ui-control-lg); padding-inline: var(--ui-space-5); font-size: 0.9375rem; font-weight: 700; } .btn-icon-sm, .btn-icon-md { flex: 0 0 auto; padding: 0; border-radius: var(--ui-radius-control); } .btn-icon-sm { width: var(--ui-control-sm); height: var(--ui-control-sm); min-height: var(--ui-control-sm); } .btn-icon-md { width: var(--ui-control-md); height: var(--ui-control-md); min-height: var(--ui-control-md); } .btn-primary { border-color: var(--button-primary-border, var(--accent, #4f46e5)); background: var(--button-primary-bg, var(--accent, #4f46e5)); color: var(--button-primary-text, #fff); } .btn-primary:hover:not(:disabled) { border-color: var(--button-primary-border, var(--accent-strong, var(--accent-hover, #4338ca))); background: var(--button-primary-bg-hover, var(--accent-strong, var(--accent-hover, #4338ca))); color: var(--button-primary-text, #fff); } .btn-secondary { border-color: var(--button-secondary-border, var(--panel-border, var(--bg-card-border))); background: var(--button-secondary-bg, var(--panel, var(--bg-card))); color: var(--button-secondary-text, var(--text, var(--text-primary))); } .btn-secondary:hover:not(:disabled) { border-color: color-mix(in srgb, var(--accent, #4f46e5) 38%, var(--button-secondary-border, var(--panel-border, var(--bg-card-border)))); background: var(--button-secondary-bg-hover, var(--bg-hover, color-mix(in srgb, var(--accent, #4f46e5) 7%, var(--panel, var(--bg-card))))); color: var(--button-secondary-text, var(--text, var(--text-primary))); } .btn-ghost { border-color: var(--button-ghost-border, transparent); background: transparent; color: var(--text-secondary, var(--muted)); } .btn-ghost:hover:not(:disabled) { border-color: var(--button-ghost-border, var(--panel-border, var(--bg-card-border))); background: var(--button-ghost-bg-hover, var(--bg-hover, rgba(148, 163, 184, 0.1))); color: var(--text-primary, var(--text)); } .btn-danger { border-color: var(--button-danger-border, #b91c1c); background: var(--button-danger-bg, #dc2626); color: #fff; } .btn-danger-subtle { border-color: var(--button-danger-subtle-border, rgba(239, 68, 68, 0.28)); background: var(--button-danger-subtle-bg, rgba(239, 68, 68, 0.12)); color: var(--button-danger-subtle-text, #b91c1c); } .btn-danger-subtle:hover:not(:disabled) { border-color: var(--button-danger-subtle-border, rgba(239, 68, 68, 0.38)); background: var(--button-danger-subtle-bg-hover, rgba(239, 68, 68, 0.18)); color: var(--button-danger-subtle-text, #b91c1c); } .input-wrapper .toggle-password { border-color: transparent; background: transparent; color: var(--text-placeholder, var(--muted)); } /* ===== Поля форм ===== */ input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]), select, textarea { border-radius: var(--ui-radius-field); } input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]), select { min-height: var(--ui-control-md); } textarea { min-height: 96px; line-height: 1.5; resize: vertical; } input::placeholder, textarea::placeholder { color: var(--text-placeholder, var(--muted)); opacity: 1; } label { line-height: 1.35; } /* ===== Поверхности и ритм ===== */ .card, .settings-card, .toolbar, .schedule-overview, .teacher-absence-panel, .preference-board, .preference-card, .request-ledger-head, .request-dialog { border-radius: var(--ui-radius-panel); } .card, .settings-card, .toolbar, .schedule-overview { box-shadow: var(--ui-shadow-panel); } .card:hover { transform: none; box-shadow: var(--ui-shadow-panel); } .card-header-row, .settings-header-row, .dashboard-card-header, .preference-board-head { gap: var(--ui-space-4); } .form-row, .filter-row, .actions, .week-nav { column-gap: var(--ui-space-3); } table { font-variant-numeric: tabular-nums; } th { font-size: 0.75rem; font-weight: 700; letter-spacing: 0.035em; } .table-actions-cell { text-align: right; } .table-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--ui-space-2); } .schedule-visual-lesson { padding-right: 2.55rem; } /* ===== Унифицированные кнопки закрытия ===== */ .modal-close, .version-modal-close, .settings-modal-close { display: inline-flex; align-items: center; justify-content: center; width: var(--ui-control-md); height: var(--ui-control-md); min-height: var(--ui-control-md); padding: 0; border: 1px solid var(--button-ghost-border, var(--panel-border, var(--bg-card-border))); border-radius: var(--ui-radius-control); background: transparent; color: var(--text-secondary, var(--muted)); font-family: var(--ui-font-sans); font-size: 1.35rem; line-height: 1; cursor: pointer; transition: background-color var(--ui-transition), border-color var(--ui-transition), color var(--ui-transition); } .modal-close:hover, .version-modal-close:hover, .settings-modal-close:hover { border-color: color-mix(in srgb, var(--error, #ef4444) 35%, transparent); background: color-mix(in srgb, var(--error, #ef4444) 10%, transparent); color: var(--error, #ef4444); } .modal-close--static { position: static; flex: 0 0 auto; } /* ===== Скролл и движение ===== */ * { scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--text-secondary, var(--muted)) 42%, transparent) transparent; } @media (max-width: 640px) { .shell { padding: var(--ui-space-4); } .actions .btn:not(.btn-icon-sm):not(.btn-icon-md) { flex: 1 1 auto; } .modal-content, .request-dialog, .version-modal-card { border-radius: var(--ui-radius-panel); } } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { scroll-behavior: auto !important; animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } }