Bicycle/App/media/css/dashboard.css
2026-08-15 10:39:22 +03:00

1028 lines
28 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.

/* Токены — палитра Nocturne (App/design_handoff_personal_finance/nocturne.css), перенесённая на
существующие имена переменных проекта, чтобы не переписывать разметку/JS (см. README хендоффа —
пересобрать в целевом окружении, не копировать HTML как есть). Акцентные цвета счетов/статей
(--teal/--green/--purple/...) — уже тёмная палитра под этот же принцип (прямые цвета, не токены
системы), оставлены как есть. */
:root {
--bg: #161826;
--surface: #232532;
--surface-2: #292b31;
--surface-3: #3f424d;
--ink: #e9e9ed;
--ink-soft: #cfd3e5;
--muted: #9397ab;
--shadow: rgba(0, 0, 0, 0.5);
--divider: color-mix(in srgb, var(--ink) 16%, transparent);
--accent: #9184d9;
--accent-tint: #d2cefd;
/* тональные рампы nocturne.css — донор для мест, где нужен не плоский, а ступенчатый цвет
(например §Аналитика — легенда донат-диаграммы, .tag-* варианты) */
--color-neutral-100: #f3f5fe;
--color-neutral-200: #e4e7f5;
--color-neutral-300: #cfd3e5;
--color-neutral-400: #b2b6ca;
--color-neutral-500: #9397ab;
--color-neutral-600: #75798c;
--color-neutral-700: #595d6c;
--color-neutral-800: #3f424d;
--color-neutral-900: #292b31;
--color-accent-100: #f5f4ff;
--color-accent-200: #e7e5fe;
--color-accent-300: #d2cefd;
--color-accent-400: #b5abfc;
--color-accent-500: #968ae0;
--color-accent-600: #796cbf;
--color-accent-700: #5d5294;
--color-accent-800: #423a6a;
--color-accent-900: #2b2741;
--color-accent-2-100: #f5f4ff;
--color-accent-2-200: #e7e5fe;
--color-accent-2-300: #d2cefd;
--color-accent-2-400: #b5afe8;
--color-accent-2-500: #9690c9;
--color-accent-2-600: #7972a9;
--color-accent-2-700: #5c5783;
--color-accent-2-800: #423e5d;
--color-accent-2-900: #2b293a;
--teal: #2dd4bf;
--green: #34d399;
--purple: #a78bfa;
--blue: #4c8dff;
--orange: #fb923c;
--pink: #f472b6;
--red: #f87171;
--amber: #fbbf24;
--gray: #6b7280;
/* единый "зелёный" для дохода/положительной динамики — раньше по проекту было два несовпадающих
зелёных (--green:#34d399 и россыпь литералов oklch(0.7x 0.13 155)), теперь один источник */
--positive: oklch(0.72 0.13 155);
--positive-text: oklch(0.78 0.13 155);
--sans: "Inter", system-ui, sans-serif;
--font-heading: "Inter", system-ui, sans-serif;
--space-1: 2.8px;
--space-2: 5.6px;
--space-3: 8.4px;
--space-4: 11.2px;
--space-6: 16.8px;
--space-8: 22.4px;
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 14px;
--shadow-card: 0 0 0 1px var(--surface-3), 0 6px 18px var(--shadow);
--shadow-pop: 0 0 0 1px var(--surface-3), 0 16px 40px var(--shadow);
--shadow-sm: 0 0 0 1px var(--surface-3);
--shadow-md: 0 0 0 1px #595d6c, 0 6px 18px rgba(0,0,0,0.55);
--shadow-lg: 0 0 0 1px #9397ab, 0 16px 40px rgba(0,0,0,0.65);
}
/* ---------- типографическая шкала (nocturne.css) ---------- */
h1 { font: 700 42px/1.15 var(--font-heading); margin: 0; }
h2 { font: 600 32px/1.2 var(--font-heading); margin: 0; }
h3 { font: 600 25px/1.25 var(--font-heading); margin: 0; }
h4 { font: 600 20px/1.3 var(--font-heading); margin: 0; }
h5 { font: 500 16px/1.35 var(--font-heading); margin: 0; }
h6 {
font: 600 13px/1.3 var(--font-heading);
letter-spacing: 0.08em;
text-transform: uppercase;
margin: 0;
}
/* затухающая по краям линия — "фирменная деталь" nocturne */
.hr {
height: 1px;
border: none;
background: linear-gradient(
to right,
transparent,
var(--divider) 48px,
var(--divider) calc(100% - 48px),
transparent
);
margin: 0;
}
/* ---------- теги (варианты nocturne, .tag/.tag-outline уже были) ---------- */
.tag-accent {
background: var(--color-accent-900);
color: var(--color-accent-100);
}
.tag-accent-2 {
background: var(--color-accent-2-900);
color: var(--color-accent-2-100);
}
.tag-neutral {
background: var(--color-neutral-900);
color: var(--color-neutral-100);
}
body {
background: var(--bg);
color: var(--ink);
font-family: var(--sans);
margin: 0;
}
.page-wrap {
min-height: 100vh;
background:
radial-gradient(600px 300px at 8% 0%, color-mix(in srgb, oklch(0.72 0.19 330) 14%, transparent), transparent 70%),
radial-gradient(500px 260px at 95% 10%, color-mix(in srgb, oklch(0.78 0.17 230) 12%, transparent), transparent 70%),
radial-gradient(500px 300px at 50% 60%, color-mix(in srgb, var(--positive) 8%, transparent), transparent 70%),
var(--bg);
}
main {
max-width: 72rem;
margin: 0 auto;
padding: 1.5rem 1.5rem 6.5rem;
}
.num { font-variant-numeric: tabular-nums; }
.ico { width: 1.05em; height: 1.05em; flex-shrink: 0; }
.ico-sm { width: 0.9em; height: 0.9em; }
.card {
display: flex;
flex-direction: column;
background: var(--surface);
border-radius: var(--radius-md);
}
.elev-md { box-shadow: var(--shadow-md); }
.elev-lg { box-shadow: var(--shadow-lg); }
/* ---------- шапка: дата-плашка + теги ---------- */
.dash-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
flex-wrap: wrap;
gap: 0.9rem;
margin-bottom: 1.6rem;
}
.dash-kicker {
font-size: 0.69rem;
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
color: color-mix(in srgb, var(--ink) 55%, transparent);
}
.dash-tags {
display: flex;
gap: 0.6rem;
flex-wrap: wrap;
}
.tag {
display: inline-flex;
align-items: center;
font-size: 0.69rem;
letter-spacing: 0.01em;
padding: 0.2rem 0.65rem;
border-radius: var(--radius-sm);
}
.tag-outline {
border: 1px solid var(--accent);
color: var(--accent);
}
/* ---------- шапка: баланс ---------- */
.balance-block {
margin-bottom: 2rem;
}
.balance-label {
font-size: 0.69rem;
font-weight: 600;
letter-spacing: 0.09em;
text-transform: uppercase;
color: var(--accent-tint);
}
.balance {
font-family: var(--font-heading);
font-size: 3rem;
font-weight: 700;
letter-spacing: -0.02em;
line-height: 1;
margin: 0.375rem 0 0;
}
.balance-total {
font-size: 0.81rem;
margin-top: 0.25rem;
color: color-mix(in srgb, var(--ink) 55%, transparent);
}
.balance-total span {
color: var(--ink);
}
/* ---------- карточки счетов ---------- */
.grid-cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 14px;
}
.grid-cards-goals {
grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
}
.room-card {
position: relative;
background: var(--surface);
border-radius: var(--radius-md);
box-shadow: var(--shadow-md);
padding: 18px 18px 20px;
display: flex;
flex-direction: column;
gap: 0.625rem;
transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.room-card:hover { transform: translateY(-2px); }
/* акцентная подсветка снизу карточки (nocturne .acc-card::after) — цвет из --card-accent,
уже проставленного инлайново на каждой карточке счёта/цели */
.room-card::after {
content: "";
position: absolute;
left: 16%;
right: 16%;
bottom: 0;
height: 2px;
border-radius: 0 0 2px 2px;
background: linear-gradient(90deg, transparent, var(--card-accent, var(--accent)), transparent);
opacity: 0.9;
}
.room-card-head {
display: flex;
align-items: flex-start;
justify-content: space-between;
}
.room-icon {
width: 38px;
height: 38px;
border-radius: 10px;
display: inline-flex;
align-items: center;
justify-content: center;
background: color-mix(in srgb, var(--card-accent, var(--blue)) 18%, transparent);
color: var(--card-accent, var(--blue));
}
.room-icon .ico { width: 1.2em; height: 1.2em; }
.room-title {
font-size: 0.875rem;
font-weight: 500;
color: color-mix(in srgb, var(--ink) 85%, transparent);
}
.room-sub {
font-size: 0.69rem;
color: color-mix(in srgb, var(--ink) 50%, transparent);
margin-top: 1px;
}
.room-value {
font-size: 1.375rem;
font-weight: 600;
color: var(--card-accent, var(--ink));
}
.acc-dot {
display: flex;
align-items: center;
gap: 5px;
font-size: 0.69rem;
color: color-mix(in srgb, var(--ink) 45%, transparent);
margin-top: auto;
}
.acc-dot span {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--card-accent, var(--blue));
display: inline-block;
flex-shrink: 0;
}
/* три точки на карточке счёта */
.room-menu { position: relative; }
.room-menu-btn {
width: 26px;
height: 26px;
padding: 0;
min-width: 0;
border: none;
border-radius: var(--radius-md);
background: transparent;
color: var(--accent);
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
}
.room-menu-btn:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.room-menu-list {
display: none;
position: absolute;
right: 0;
top: 1.8rem;
z-index: 5;
min-width: 160px;
background: var(--surface-2);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-pop);
padding: 0.35rem;
}
.room-menu.open .room-menu-list { display: block; }
.room-menu-list a {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem 0.6rem;
border-radius: var(--radius-md);
font-size: 0.82rem;
color: var(--ink-soft);
}
.room-menu-list a:hover { background: var(--surface-3); color: var(--ink); }
.room-menu-list a.danger { color: var(--red); }
.room-menu-move {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem 0.6rem;
border-radius: var(--radius-md);
font-size: 0.82rem;
color: var(--ink-soft);
cursor: pointer;
}
.room-menu-move:hover { background: var(--surface-3); color: var(--ink); }
.room-menu-move select {
flex: 1;
background: transparent;
border: none;
color: inherit;
font-size: inherit;
padding: 0;
}
/* ---------- бюджет по категориям ---------- */
.pm-wrap {
container-type: inline-size;
overflow: hidden;
margin-bottom: 1.75rem;
padding: 6px 0;
}
.stat-row {
display: flex;
align-items: center;
gap: 16px;
padding: 12px 20px;
border-bottom: 1px solid var(--divider);
}
.stat-row:last-child { border-bottom: none; }
.stat-row > *:first-child { width: 160px; flex-shrink: 0; }
.stat-row > *:nth-child(2) { flex: 1; min-width: 0; }
.stat-row > *:last-child { width: 90px; flex-shrink: 0; text-align: right; }
@container (max-width: 440px) {
.stat-row { flex-wrap: wrap; padding: 12px 16px; row-gap: 6px; }
.stat-row > *:first-child { width: auto; flex: 1; order: 1; }
.stat-row > *:last-child { width: auto; order: 2; }
.stat-row > *:nth-child(2) { width: 100%; order: 3; }
}
.stat-name { font-size: 0.81rem; font-weight: 600; color: var(--ink); }
.stat-caption {
font-size: 0.69rem;
color: color-mix(in srgb, var(--ink) 55%, transparent);
margin-top: 4px;
}
.budget-bar {
height: 7px;
border-radius: 4px;
background: var(--surface-3);
overflow: hidden;
margin-top: 5px;
}
.budget-bar-fill { height: 100%; border-radius: 4px; }
.budget-group-head {
display: flex;
justify-content: space-between;
padding: 10px 20px;
background: var(--surface-2);
}
.budget-group-name {
font-size: 0.69rem;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--accent-tint);
}
.budget-group-sum {
font-size: 0.69rem;
color: color-mix(in srgb, var(--ink) 55%, transparent);
}
/* ---------- заголовок секции — единый источник отступа/цвета для всех "Счета"/"Копилки и
цели"/"Доходы"/"Бюджет на..."/"Доходы"+"Расходы" на /budgets (была россыпь инлайновых
style="margin:...;color:..." с разными значениями в каждом месте — свели к одному классу).
:first-of-type сбрасывает верхний отступ у первой секции страницы без ручного margin:0. ---------- */
.section-label {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
font-family: var(--font-heading);
font-size: 0.72rem;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--muted);
margin: 2rem 0 0.9rem;
}
.section-label:first-of-type { margin-top: 0; }
/* ---------- card-title / card-meta (nocturne) ---------- */
.card-title { font-weight: 500; line-height: 1.2; }
.card-meta {
display: flex;
align-items: center;
gap: 4px;
font-size: 0.75rem;
color: color-mix(in srgb, var(--ink) 50%, transparent);
}
.card-meta .num { color: var(--ink); }
/* пустое состояние + кнопка добавить */
.empty-state {
border: 1px dashed var(--surface-3);
border-radius: var(--radius-lg);
padding: 2.5rem 1rem;
text-align: center;
color: var(--muted);
}
.btn-add {
width: 2.1rem;
height: 2.1rem;
border-radius: 50%;
border: none;
background: var(--surface-3);
color: var(--ink);
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.btn-add:hover { background: var(--accent); }
.btn-add.active { background: var(--accent); color: var(--bg); }
/* ---------- режим ручной сортировки карточек счетов (drag & drop) ---------- */
.grid-cards.reorder-mode .room-card {
cursor: grab;
box-shadow: var(--shadow-md), inset 0 0 0 1.5px color-mix(in srgb, var(--accent) 55%, transparent);
}
.grid-cards.reorder-mode .room-card:active { cursor: grabbing; }
.grid-cards.reorder-mode .room-card.dragging { opacity: 0.4; }
/* в режиме сортировки клики по ⋮-меню отключены — не мешают drag-жесту */
.grid-cards.reorder-mode .room-menu { pointer-events: none; }
/* ---------- архив счетов (модалка) ---------- */
.archive-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
padding: 0.7rem 0;
border-bottom: 1px solid var(--surface-3);
}
.archive-row:last-child { border-bottom: none; }
/* ---------- список статей (категории) ---------- */
.category-list {
display: flex;
flex-direction: column;
gap: 0.4rem;
margin-bottom: 1.5rem;
}
.category-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
background: var(--surface);
border-radius: var(--radius-lg);
padding: 0.7rem 0.9rem;
}
.category-row-main {
display: flex;
align-items: center;
gap: 0.6rem;
min-width: 0;
}
.category-group { font-family: var(--font-heading); font-weight: 600; }
.category-sub {
margin-left: 1.6rem;
background: var(--surface-2);
}
/* ---------- план на год: карточки (комп/планшет) + аккордeон (телефон) ----------
Своя раскладка на каждую ширину, ни одна не даёт горизонтальный скролл (см. обсуждение
дизайна в .claude/memory/бюджет_текущий_план.md):
- комп: карточка статьи — все 12 месяцев в один ряд;
- планшет: та же карточка, но сеткой 6×2 — через container query, ничего не жмётся;
- телефон: карточки-таблицы пропадают совсем, вместо них — раскрывающиеся аккордeоны
(тап по статье показывает все 12 месяцев в два столбика).
.budget-zoom — container для container query (не завязано на реальный viewport, а на
ширину самого блока — так раскладка одинаково работает и в узком, и в широком main). */
.budget-zoom { container-type: inline-size; }
.budget-plan-group { margin-bottom: 0.9rem; }
.budget-cards-wrap { display: block; }
.budget-accordion { display: none; }
.budget-cards { display: flex; flex-direction: column; gap: 0.5rem; }
.budget-card {
background: var(--surface);
border-radius: var(--radius-lg);
padding: 0.75rem 0.85rem;
box-shadow: var(--shadow-card);
}
.budget-card-name { font-family: var(--font-heading); font-size: 0.84rem; font-weight: 600; margin-bottom: 0.5rem; }
.budget-months-inline { display: flex; gap: 0.35rem; }
.budget-cell {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
gap: 0.15rem;
background: var(--surface-2);
border-radius: var(--radius-md);
padding: 0.35rem 0.15rem;
min-width: 0;
}
.budget-cell-label { font-size: 0.6rem; color: var(--muted); text-transform: uppercase; }
.plan-input {
width: 100%;
background: transparent;
border: none;
color: var(--ink);
text-align: center;
font-size: 0.72rem;
font-family: inherit;
padding: 0;
}
.plan-input:focus-visible { outline: 1px solid var(--accent); border-radius: 3px; }
.plan-input::-webkit-outer-spin-button, .plan-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.plan-input { -moz-appearance: textfield; }
/* планшет: та же карточка, но 12 месяцев — сеткой 6×2, не в один сжатый ряд */
@container (max-width: 740px) {
.budget-months-inline { display: grid; grid-template-columns: repeat(6, 1fr); gap: 0.4rem; }
}
/* телефон: карточки меняются на другой компонент — раскрывающиеся аккордeоны */
@container (max-width: 420px) {
.budget-cards-wrap { display: none; }
.budget-accordion { display: block; }
}
.budget-acc-card {
background: var(--surface);
border-radius: var(--radius-lg);
margin-bottom: 0.5rem;
overflow: hidden;
}
.budget-acc-card summary {
display: flex;
align-items: center;
gap: 0.6rem;
padding: 0.7rem 0.9rem;
font-family: var(--font-heading);
font-size: 0.84rem;
font-weight: 600;
cursor: pointer;
list-style: none;
}
.budget-acc-name { flex: 1; min-width: 0; }
.budget-acc-card summary::-webkit-details-marker { display: none; }
.budget-acc-card summary::after { content: "▾"; color: var(--muted); font-size: 0.7rem; margin-left: 0.3rem; }
.budget-acc-card details[open] summary::after { content: "▴"; }
.budget-acc-total { font-size: 0.76rem; color: var(--muted); font-weight: 500; white-space: nowrap; }
.budget-acc-caption {
padding: 0 0.9rem;
margin: 0.5rem 0 0.3rem;
font-size: 0.7rem;
color: var(--muted);
}
.budget-acc-body {
padding: 0 0.9rem 0.8rem;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.4rem 0.7rem;
}
.budget-acc-month {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.4rem;
background: var(--surface-2);
border-radius: var(--radius-md);
padding: 0.3rem 0.5rem;
}
.budget-acc-month span { font-size: 0.68rem; color: var(--muted); }
.budget-acc-month .plan-input { width: 4rem; flex-shrink: 0; text-align: right; }
/* ---------- нижний dock-навбар ---------- */
.dock {
position: fixed;
left: 50%;
bottom: 1.1rem;
transform: translateX(-50%);
display: flex;
align-items: center;
gap: 6px;
background: var(--surface);
border-radius: 999px;
padding: 6px;
box-shadow: var(--shadow-md);
z-index: 30;
max-width: calc(100vw - 2rem);
overflow-x: auto;
}
.dock-item {
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
border-radius: 50%;
color: var(--muted);
text-decoration: none;
flex-shrink: 0;
transition: color 0.15s ease, background 0.15s ease;
cursor: pointer;
border: none;
background: transparent;
}
.dock-item .ico { width: 1.15rem; height: 1.15rem; transition: transform 0.15s ease; }
a.dock-item:hover { color: var(--ink-soft); }
.dock-item.active {
color: var(--positive);
background: color-mix(in srgb, var(--positive) 20%, transparent);
}
.dock-item.active .ico { transform: translateY(-1px); }
@media (max-width: 640px) {
.balance { font-size: 2.4rem; }
}
/* ---------- Bootstrap: формы/кнопки/модалки под токены Nocturne ----------
Разметка форм (модалки счетов/статей) — штатные Bootstrap-компоненты (.form-control, .btn-primary
и т.п.), меняем только их отрисовку под палитру/радиусы проекта, не трогая JS/структуру. */
.btn { border-radius: var(--radius-md); }
.btn-ghost {
color: var(--accent);
background: transparent;
border-color: transparent;
}
.btn-ghost:hover,
.btn-ghost:focus,
.btn-ghost:active { background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--accent); box-shadow: none; }
.btn-icon { width: 36px; height: 36px; padding: 0; min-width: 0; }
.btn-primary {
background: var(--accent);
border-color: var(--accent);
}
.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active {
background: color-mix(in srgb, var(--accent) 85%, black) !important;
border-color: color-mix(in srgb, var(--accent) 85%, black) !important;
}
.btn-outline-light {
border-color: var(--surface-3);
color: var(--ink-soft);
}
.btn-outline-light:hover,
.btn-outline-light:focus,
.btn-outline-light:active {
background: var(--surface-3) !important;
border-color: var(--surface-3) !important;
color: var(--ink) !important;
}
.btn-secondary {
background: transparent;
border-color: var(--surface-3);
color: var(--ink-soft);
}
.btn-secondary:hover,
.btn-secondary:focus,
.btn-secondary:active {
background: var(--surface-3) !important;
border-color: var(--surface-3) !important;
color: var(--ink) !important;
}
.form-control,
.form-select {
background: var(--bg);
border-color: var(--surface-3);
color: var(--ink);
border-radius: var(--radius-md);
}
.form-control:focus,
.form-select:focus {
background: var(--bg);
border-color: var(--accent);
color: var(--ink);
box-shadow: 0 0 0 0.2rem color-mix(in srgb, var(--accent) 25%, transparent);
}
.form-check-input {
background-color: var(--bg);
border-color: var(--surface-3);
}
.form-check-input:checked {
background-color: var(--accent);
border-color: var(--accent);
}
.form-check-input:focus {
box-shadow: 0 0 0 0.2rem color-mix(in srgb, var(--accent) 25%, transparent);
}
.modal-content { border-radius: var(--radius-lg); }
/* ---------- диалог: содержимое шапки модалок (модалки теперь Bootstrap, см. .modal-content
выше — .dialog-backdrop/.dialog как самостоятельный компонент больше не используются) ---------- */
.dialog-icon {
width: 40px;
height: 40px;
border-radius: 10px;
background: color-mix(in srgb, var(--accent) 20%, transparent);
color: var(--accent);
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.dialog-sub {
font-size: 0.75rem;
color: color-mix(in srgb, var(--ink) 50%, transparent);
margin-top: 2px;
}
.dialog-section-label {
font-size: 0.69rem;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
color: color-mix(in srgb, var(--ink) 55%, transparent);
margin: 1rem 0 0.625rem;
}
.btn-icon-round {
width: 32px;
height: 32px;
border-radius: 50%;
border: none;
background: transparent;
color: color-mix(in srgb, var(--ink) 55%, transparent);
cursor: pointer;
font-size: 1rem;
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
line-height: 1;
}
.btn-icon-round:hover { background: var(--surface-3); color: var(--ink); }
/* ---------- тайлы выбора типа ---------- */
.pm-tiles-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(145px, 1fr));
gap: 10px;
}
.pm-tile {
border: 1.5px solid var(--divider);
border-radius: 10px;
padding: 12px 14px;
cursor: pointer;
display: flex;
align-items: flex-start;
gap: 10px;
background: var(--surface-2);
position: relative;
transition: border-color 0.15s;
}
.pm-tile:hover { border-color: color-mix(in srgb, var(--ink) 30%, transparent); }
.pm-tile.selected {
border-color: var(--accent);
background: color-mix(in srgb, var(--accent) 10%, var(--surface-2));
}
.pm-check {
position: absolute;
top: 10px;
right: 10px;
width: 16px;
height: 16px;
border-radius: 50%;
background: var(--accent);
display: none;
align-items: center;
justify-content: center;
color: var(--bg);
font-size: 10px;
}
.pm-tile.selected .pm-check { display: flex; }
.pm-tile-icon {
width: 34px;
height: 34px;
border-radius: 8px;
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.pm-tile-title { font-size: 0.81rem; font-weight: 600; }
.pm-tile-desc { font-size: 0.69rem; color: color-mix(in srgb, var(--ink) 50%, transparent); margin-top: 2px; }
/* ---------- поля формы ---------- */
.field > label {
display: block;
font-size: 0.75rem;
margin-bottom: 5px;
color: color-mix(in srgb, var(--ink) 70%, transparent);
}
.input {
width: 100%;
min-height: 36px;
padding: 6px 10px;
font: inherit;
font-size: 0.875rem;
color: var(--ink);
caret-color: var(--accent);
background: var(--bg);
border: 1px solid var(--divider);
border-radius: var(--radius-md);
appearance: none;
-webkit-appearance: none;
box-sizing: border-box;
}
.input:hover { border-color: color-mix(in srgb, var(--ink) 45%, transparent); }
.input:focus, .input:focus-visible { border-color: var(--accent); outline: none; }
/* ---------- сегментированный контрол ---------- */
.seg {
display: inline-flex;
overflow: hidden;
border: 1px solid var(--divider);
border-radius: var(--radius-md);
}
.seg-opt {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 7px 12px;
font-size: 0.81rem;
cursor: pointer;
}
.seg-opt input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.seg-opt + .seg-opt { border-left: 1px solid var(--divider); }
.seg-opt:has(input:checked) { color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.seg-opt:not(:has(input:checked)):hover { background: color-mix(in srgb, var(--ink) 7%, transparent); }
/* ---------- ошибка в форме диалога ---------- */
.alert-error {
background: color-mix(in srgb, var(--red) 15%, transparent);
border: 1px solid color-mix(in srgb, var(--red) 35%, transparent);
border-radius: var(--radius-md);
padding: 0.5rem 0.75rem;
font-size: 0.81rem;
color: var(--red);
}