1028 lines
28 KiB
CSS
1028 lines
28 KiB
CSS
/* Токены — палитра 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);
|
||
}
|