Bicycle/App/media/css/dashboard.css
Egor Isaev c9b81cdcd1 dev
2026-08-14 13:09:54 +03:00

524 lines
13 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.

:root {
--bg: #0b0b0f;
--surface: #17171d;
--surface-2: #1e1e26;
--surface-3: #24242d;
--ink: #f2f2f5;
--ink-soft: #c4c4cc;
--muted: #85858f;
--shadow: rgba(0, 0, 0, 0.5);
--teal: #2dd4bf;
--green: #34d399;
--purple: #a78bfa;
--blue: #4c8dff;
--orange: #fb923c;
--pink: #f472b6;
--red: #f87171;
--amber: #fbbf24;
--gray: #6b7280;
--sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
body {
background: var(--bg);
color: var(--ink);
font-family: var(--sans);
margin: 0;
}
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; }
/* ---------- шапка: приветствие + баланс ---------- */
.top-row {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 1.5rem;
flex-wrap: wrap;
margin-bottom: 2rem;
}
.hello {
font-size: 0.95rem;
color: var(--ink-soft);
}
.balance-label {
font-size: 0.72rem;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--muted);
margin-top: 0.6rem;
}
.balance {
font-size: 3rem;
font-weight: 800;
letter-spacing: -0.02em;
line-height: 1;
}
.balance span { font-size: 1.4rem; font-weight: 600; color: var(--muted); }
.balance-total {
font-size: 1.15rem;
font-weight: 700;
margin-top: 0.4rem;
color: var(--ink-soft);
}
.balance-total .label {
font-size: 0.78rem;
font-weight: 500;
color: var(--muted);
margin-right: 0.4rem;
}
/* ---------- заголовок секции ---------- */
.section-label {
display: flex;
align-items: center;
justify-content: space-between;
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; }
/* ---------- карточки счетов ---------- */
.grid-cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
gap: 0.9rem;
}
.room-card {
position: relative;
background: var(--surface);
border-radius: 18px;
padding: 1rem 1.1rem 1.15rem;
overflow: hidden;
box-shadow: 0 2px 10px var(--shadow);
}
.room-card::after {
content: "";
position: absolute;
left: 14%;
right: 14%;
bottom: 0;
height: 3px;
border-radius: 3px;
background: linear-gradient(90deg, transparent, var(--card-accent, var(--blue)), transparent);
opacity: 0.9;
}
.room-card-head {
display: flex;
align-items: flex-start;
justify-content: space-between;
}
.room-icon {
width: 2.1rem;
height: 2.1rem;
border-radius: 10px;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 1rem;
background: color-mix(in srgb, var(--card-accent, var(--blue)) 20%, transparent);
color: var(--card-accent, var(--blue));
margin-bottom: 0.7rem;
}
.room-title { font-size: 0.92rem; font-weight: 600; }
.room-sub {
font-size: 0.76rem;
color: var(--muted);
margin-top: 0.15rem;
}
.room-value {
font-size: 1.3rem;
font-weight: 700;
margin-top: 0.6rem;
color: var(--card-accent, var(--ink));
}
/* три точки на карточке счёта */
.room-menu { position: relative; }
.room-menu-btn {
border: none;
background: transparent;
color: var(--muted);
padding: 0.15rem 0.3rem;
border-radius: 6px;
cursor: pointer;
}
.room-menu-btn:hover { color: var(--ink); background: var(--surface-3); }
.room-menu-list {
display: none;
position: absolute;
right: 0;
top: 1.8rem;
z-index: 5;
min-width: 160px;
background: var(--surface-2);
border-radius: 12px;
box-shadow: 0 8px 24px var(--shadow);
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: 8px;
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: 8px;
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;
}
/* ---------- бюджет по категориям — компактный список (дашборд, макет "Бюджет — обзор") ---------- */
.budget-list {
background: var(--surface);
border-radius: 16px;
box-shadow: 0 2px 10px var(--shadow);
overflow: hidden;
margin-bottom: 1.5rem;
}
.budget-row {
padding: 0.65rem 1.1rem;
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
}
.budget-row + .budget-row { border-top: 1px solid rgba(255, 255, 255, 0.06); }
.budget-group-head {
display: flex;
align-items: baseline;
justify-content: space-between;
padding: 0.55rem 1.1rem;
background: var(--surface-2);
}
.budget-group-head + .budget-row { border-top: none; }
.budget-row + .budget-group-head { border-top: 1px solid rgba(255, 255, 255, 0.06); }
.budget-group-name {
font-size: 0.74rem;
font-weight: 700;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--card-accent, var(--ink-soft));
}
.budget-group-sum { font-size: 0.72rem; color: var(--muted); }
.budget-name { font-size: 0.84rem; font-weight: 600; }
.budget-plan-amount { font-size: 0.84rem; font-weight: 600; color: var(--ink-soft); white-space: nowrap; }
/* пустое состояние + кнопка добавить */
.empty-state {
border: 1px dashed var(--surface-3);
border-radius: 18px;
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(--blue); }
/* ---------- архив счетов (модалка) ---------- */
.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: 14px;
padding: 0.7rem 0.9rem;
}
.category-row-main {
display: flex;
align-items: center;
gap: 0.6rem;
min-width: 0;
}
.category-group { 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: 14px;
padding: 0.75rem 0.85rem;
box-shadow: 0 2px 8px var(--shadow);
}
.budget-card-name { 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: 8px;
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(--teal); 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: 12px;
margin-bottom: 0.5rem;
overflow: hidden;
}
.budget-acc-card summary {
display: flex;
align-items: center;
gap: 0.6rem;
padding: 0.7rem 0.9rem;
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: 8px;
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: stretch;
gap: 0.2rem;
background: rgba(23, 23, 29, 0.86);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 26px;
padding: 0.5rem;
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.04);
z-index: 30;
max-width: calc(100vw - 2rem);
overflow-x: auto;
}
.dock-item {
display: flex;
align-items: center;
justify-content: center;
padding: 0.7rem;
border-radius: 18px;
color: var(--muted);
text-decoration: none;
flex-shrink: 0;
transition: color 0.15s ease, background 0.15s ease;
}
.dock-item .ico { width: 1.35rem; height: 1.35rem; transition: transform 0.15s ease; }
a.dock-item:hover { color: var(--ink-soft); }
.dock-item.active {
color: var(--teal);
background: color-mix(in srgb, var(--teal) 16%, transparent);
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--teal) 35%, transparent);
}
.dock-item.active .ico { transform: translateY(-1px); }
@media (max-width: 640px) {
.top-row { flex-direction: column; }
.balance { font-size: 2.4rem; }
.dock-item { padding: 0.5rem 0.65rem; }
}