/* Дневник — Modernist skin, ported from the sibling salary project.
   Same design tokens/class contract as salary/static/style.css, plus the
   journal-specific feed/sheet/wizard blocks below, which have no salary
   counterpart. */
@import url('https://fonts.googleapis.com/css2?family=Archivo:wght@400;600;800&display=swap');

:root {
	--bg: #f3f2f2;
	--paper: #eae9e9;
	--surface: #ffffff;
	--text: #201e1d;
	--muted: color-mix(in srgb, #201e1d 55%, transparent);
	--line: color-mix(in srgb, #201e1d 20%, transparent);
	--line-strong: color-mix(in srgb, #201e1d 40%, transparent);
	--accent: #ec3013;
	--accent-text: #f3f2f2;
	--accent-100: #fff2ef;
	--accent-600: #dd2b0f;
	--accent-700: #ae1800;
	--accent-800: #7c1405;
	--neutral-100: #f8f4f4;
	--neutral-800: #444141;
	--ink-red: var(--accent-700);
	--radius: 0;
	--font-heading: "Archivo", system-ui, sans-serif;
	--font-body: "Archivo", system-ui, sans-serif;
}

* { box-sizing: border-box; }

body {
	margin: 0;
	background: var(--bg);
	color: var(--text);
	font: 400 15px/1.55 var(--font-body);
}

main {
	max-width: 1100px;
	margin: 0 auto;
	padding: 2rem 1.25rem 4rem;
}

main.centered {
	display: flex;
	min-height: 100vh;
	align-items: center;
	justify-content: center;
}

h1 { font: 800 34px/1.15 var(--font-heading); margin: 0 0 1rem; letter-spacing: -.015em; }
h2 {
	font: 800 .8rem/1 var(--font-heading);
	margin: 0 0 .75rem;
	text-transform: uppercase;
	letter-spacing: .08em;
	color: var(--muted);
}

a { color: var(--accent); text-underline-offset: 3px; }
a:hover { color: var(--accent-600); }

.muted { color: var(--muted); font-size: .9rem; }
.strong { font-weight: 800; }
.num { text-align: right; font-variant-numeric: tabular-nums; }

/* header */

.topbar {
	display: flex;
	flex-wrap: wrap;
	gap: 1rem;
	align-items: center;
	padding: .9rem 1.25rem;
	background: var(--bg);
	border-bottom: 2px solid var(--line-strong);
}

.brand { font: 800 18px var(--font-heading); text-decoration: none; color: var(--text); letter-spacing: -.01em; margin-right: auto; }

.topbar nav { display: flex; gap: 1.5rem; }
.topbar nav a {
	text-decoration: none;
	color: var(--text);
	opacity: .7;
	font-size: .85rem;
}
.topbar nav a:hover { color: var(--accent); opacity: 1; }
.topbar nav a.active { color: var(--accent); opacity: 1; font-weight: 800; }

.topbar .user { display: flex; align-items: center; gap: .6rem; font-size: .85rem; color: var(--muted); margin-left: auto; }
.avatar { width: 26px; height: 26px; border-radius: 0; filter: grayscale(1) contrast(1.08); object-fit: cover; }

/* banners — flush rules, not tinted boxes */

.banner {
	padding: .8rem 0;
	border-top: 2px solid var(--line-strong);
	border-bottom: 2px solid var(--line-strong);
	margin: 0 0 1.5rem;
	font-size: .9rem;
	border-radius: 0;
}
.banner-warn, .banner-error { color: var(--ink-red); }
.banner-info { color: var(--text); }

/* month/year header */

.month-header {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	margin-bottom: 1.5rem;
}
.month-header h1 { flex: none; text-align: left; margin: 0; }
.nav-arrow {
	text-decoration: none;
	font: 800 1rem var(--font-heading);
	padding: .35rem .8rem;
	color: var(--text);
	border: 1px solid var(--line-strong);
	border-radius: 0;
}
.nav-arrow:hover { background: var(--accent); color: var(--accent-text); border-color: var(--accent); }

/* summary tiles — modular grid, visible lines on all sides */

.summary {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
	gap: 0;
	margin-bottom: 1.5rem;
	border-top: 2px solid var(--line-strong);
	border-left: 2px solid var(--line-strong);
}
.stat {
	border-bottom: 2px solid var(--line-strong);
	border-right: 2px solid var(--line-strong);
	padding: .9rem 1rem;
	display: flex;
	flex-direction: column;
	gap: .35rem;
}
.stat-label { color: var(--muted); font-size: .78rem; text-transform: uppercase; letter-spacing: .05em; }
.stat-value { font: 800 1.1rem var(--font-heading); font-variant-numeric: tabular-nums; }
strong.stat-value { color: var(--text); }

.tag {
	display: inline-flex; align-items: center;
	font-size: .68rem; font-weight: 600;
	letter-spacing: .02em;
	padding: .18rem .55rem;
	border-radius: 0;
	border: 1px solid transparent;
}
.tag-fact { background: var(--accent-100); color: var(--accent-800); }
.tag-extra { background: var(--neutral-100); color: var(--neutral-800); }
.tag-vacation { border-color: var(--accent); color: var(--ink-red); }
.tag-unpaid { border-color: var(--line-strong); color: var(--muted); }
.tag-forecast { border-color: var(--line-strong); color: var(--muted); }

.absences { list-style: none; margin: 0 0 1rem; padding: 0; display: grid; gap: 0; }
.absence {
	display: flex;
	flex-wrap: wrap;
	gap: .6rem;
	align-items: center;
	padding: .7rem 0;
	border-bottom: 1px solid var(--line);
}

label.checkbox { flex-direction: row; align-items: center; gap: .4rem; color: var(--text); }

.cumulative { color: var(--muted); font-size: .88rem; }
.empty { color: var(--muted); font-style: italic; }

/* cards and forms */

.card {
	background: var(--paper);
	border: none;
	border-top: 2px solid var(--line-strong);
	border-radius: 0;
	padding: 1.25rem 1.5rem 1.5rem;
	margin-bottom: 1.5rem;
}
.card-nested { margin-top: 1rem; }

/* .stack lays a form's direct children out with one consistent vertical gap
   — without it, a <form class="card"> full of <label> children (each its
   own flex box) touch with no space between them, unlike every other card
   on the site, which uses a flex form (.inline-form etc.) with its own gap. */
.stack { display: flex; flex-direction: column; gap: .75rem; }

.filter-bar label, .filter-bar .field { min-width: 9rem; }
.filter-bar input, .filter-bar select { width: 100%; }

label { display: flex; flex-direction: column; gap: .3rem; font-size: .8rem; color: var(--muted); }
.field { display: flex; flex-direction: column; gap: .3rem; }
.field-label { font-size: .8rem; color: var(--muted); }

/* Счета filter — a <details>/<summary> dropdown of checkboxes, so picking
   several accounts doesn't need a tall native multi-select box. */
.dropdown { position: relative; }
.dropdown summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: .5rem;
	width: 100%;
	font: inherit;
	color: var(--text);
	background: var(--surface);
	border: 1px solid var(--line-strong);
	padding: .5rem .65rem;
	cursor: pointer;
	list-style: none;
}
.dropdown summary::-webkit-details-marker { display: none; }
.dropdown summary::after {
	content: "";
	width: .35rem;
	height: .35rem;
	flex: none;
	border-right: 1px solid var(--text);
	border-bottom: 1px solid var(--text);
	transform: rotate(45deg);
	margin-bottom: .15rem;
}
.dropdown[open] summary::after { transform: rotate(-135deg); margin-bottom: -.15rem; }
.dropdown[open] summary { border-color: var(--accent); }
.dropdown-menu {
	position: absolute;
	z-index: 10;
	top: calc(100% + .3rem);
	left: 0;
	min-width: 100%;
	max-height: 14rem;
	overflow-y: auto;
	display: flex;
	flex-direction: column;
	gap: .4rem;
	background: var(--surface);
	border: 1px solid var(--line-strong);
	padding: .6rem .75rem;
	white-space: nowrap;
}

input, select, textarea, button {
	font: inherit;
	color: var(--text);
	background: var(--surface);
	border: 1px solid var(--line-strong);
	border-radius: 0;
	padding: .5rem .65rem;
}
input:focus-visible, select:focus-visible, textarea:focus-visible, button:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}

select {
	appearance: none;
	-webkit-appearance: none;
	padding-right: 1.8rem;
	background-image: linear-gradient(45deg, transparent 50%, var(--text) 50%), linear-gradient(135deg, var(--text) 50%, transparent 50%);
	background-position: right .9rem center, right .65rem center;
	background-size: .35rem .35rem, .35rem .35rem;
	background-repeat: no-repeat;
}

input[type="radio"], input[type="checkbox"] {
	appearance: none;
	-webkit-appearance: none;
	width: 1rem;
	height: 1rem;
	padding: 0;
	margin: 0;
	border: 1px solid var(--line-strong);
	background: var(--surface);
	display: inline-grid;
	place-content: center;
	flex: none;
	cursor: pointer;
}
input[type="radio"] { border-radius: 50%; }
input[type="checkbox"] { border-radius: 0; }
input[type="radio"]::before, input[type="checkbox"]::before {
	content: "";
	width: .55rem;
	height: .55rem;
	transform: scale(0);
	background: var(--accent);
}
input[type="radio"]::before { border-radius: 50%; }
input[type="checkbox"]:checked::before {
	clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
	width: .8rem;
	height: .8rem;
}
input[type="radio"]:checked::before, input[type="checkbox"]:checked::before {
	transform: scale(1);
}

button {
	background: var(--accent);
	color: var(--accent-text);
	border-color: var(--accent);
	cursor: pointer;
	font-weight: 800;
	font-size: .85rem;
	text-align: left;
	justify-content: flex-start;
}
button:hover { background: var(--accent-600); border-color: var(--accent-600); }
button:active { background: var(--accent-700); border-color: var(--accent-700); }

/* Buttons that deliberately drop button chrome — list rows, phone tabs, a
   sheet's close × — still match the bare button:hover above, whose (0,1,1)
   outranks the (0,1,0) `background: none` each of them sets. Left alone they
   repaint as primary buttons mid-hover, which also drags their text onto an
   accent fill it was never contrasted against: a muted subtitle stays muted
   and a red amount stays red. A quiet wash at a specificity that wins keeps
   every one of them legible. */
.feed-row:hover, .sheet-row:hover, .tab:hover, .sheet-close:hover {
	background: color-mix(in srgb, var(--text) 7%, transparent);
}

button.primary, a.button.primary {
	display: inline-block;
	padding: .5rem .65rem;
	font-size: .85rem;
	border-radius: 0;
	background: var(--accent);
	color: var(--accent-text);
	border: 1px solid var(--accent);
	text-decoration: none;
	cursor: pointer;
	font-weight: 800;
	text-align: left;
}
button.primary:hover, a.button.primary:hover { background: var(--accent-600); border-color: var(--accent-600); }

button.link {
	background: none;
	border: none;
	color: var(--accent);
	padding: .2rem .3rem;
	text-decoration: none;
	font-weight: 600;
	font-size: .85rem;
}
button.link:hover { color: var(--accent-600); }
button.link.danger { color: var(--ink-red); }
button.link.danger:hover { color: var(--accent-800); }

.inline-form, .income-form, .scale-form, .filter-bar {
	display: flex;
	flex-wrap: wrap;
	gap: .75rem;
	align-items: flex-end;
}
.income-form label, .scale-form label { min-width: 12rem; flex: 1; }
.scale-form { flex-direction: column; align-items: stretch; }

fieldset { border: none; margin: 0; padding: 0; min-width: 0; }

.radios {
	border: 1px solid var(--line-strong);
	border-radius: 0;
	padding: .4rem .65rem;
	display: flex;
	gap: .75rem;
	align-items: center;
}
.radios legend { padding: 0 0 .3rem; font-size: .78rem; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.radios label { flex-direction: row; align-items: center; gap: .3rem; color: var(--text); }

/* tables */

.table-scroll { overflow-x: auto; }

table { width: 100%; border-collapse: collapse; }
th, td { padding: .55rem .55rem; border-bottom: 1px solid var(--line); text-align: left; }
td { white-space: nowrap; }
.year-table .num { font-size: .88rem; }
thead th {
	font-size: .72rem;
	color: var(--muted);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: .05em;
	border-bottom: 2px solid var(--line-strong);
}
tfoot th, tfoot td { border-bottom: none; border-top: 2px solid var(--line-strong); font-weight: 800; }

.pay-days input[type="number"] { width: 4.5rem; }
.pay-days input[type="text"] { width: 100%; min-width: 8rem; }
.period-cell { display: flex; align-items: center; gap: .3rem; }
.row-actions { display: flex; gap: .4rem; align-items: baseline; white-space: nowrap; }

/* tax scales / vacation rules */

.scale { border-top: 1px solid var(--line); padding-top: .8rem; margin-top: .8rem; }
.scale-head { display: flex; gap: .75rem; align-items: baseline; flex-wrap: wrap; }
.brackets { margin: .5rem 0 0; padding-left: 1.2rem; color: var(--muted); font-size: .9rem; }

/* login */

.login {
	background: var(--paper);
	border: none;
	border-top: 2px solid var(--accent);
	border-radius: 0;
	padding: 2.5rem 2rem;
	max-width: 26rem;
	text-align: left;
}
.login h1 { font-size: 2rem; margin-bottom: .6rem; }

@media (max-width: 640px) {
	.topbar { gap: .5rem; }
}

/* sheets — one <dialog>, content swapped in by htmx. Phone: slides up from
   the bottom, capped height, its own scroll. Desktop: a centered modal. */

.sheet {
	position: fixed;
	inset: auto 0 0 0;
	margin: 0;
	width: 100%;
	/* The UA stylesheet gives dialog:modal max-width/max-height
	   calc(100% - 6px - 2em), which clamps the phone sheet ~36px short of the
	   viewport no matter what width says. Both axes have to be reset here. */
	max-width: 100%;
	max-height: 92vh;
	padding: 0;
	/* keeps the last row clear of the home indicator */
	padding-bottom: env(safe-area-inset-bottom);
	border: none;
	border-top: 2px solid var(--line-strong);
	background: var(--paper);
	overflow-y: auto;
}
.sheet::backdrop { background: color-mix(in srgb, var(--text) 40%, transparent); }
.sheet-body { padding: 1.1rem 1.25rem 1.5rem; display: flex; flex-direction: column; gap: 1rem; }
/* .sheet-head is a *sibling* of .sheet-body, not a child: both sit directly
   under the unpadded #sheet-body wrapper htmx swaps into. So it carries its
   own padding and no negative margin — pulling it outwards would make it
   wider than the dialog's content box, which is horizontal overflow in a
   container that scrolls (see .sheet's overflow-y above: one axis auto makes
   the other auto too). */
.sheet-head {
	display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
	padding: 1.1rem 1.25rem .8rem;
	border-bottom: 2px solid var(--line-strong);
}
.sheet-title { font: 800 1.05rem var(--font-heading); letter-spacing: -.01em; }
.sheet-close { background: none; border: none; color: var(--text); font: 800 1.2rem var(--font-heading); cursor: pointer; padding: .1rem .3rem; }

@media (min-width: 641px) {
	.sheet {
		inset: 50% auto auto 50%;
		transform: translate(-50%, -50%);
		width: min(560px, calc(100vw - 2rem));
		max-height: 84vh;
		border-top: 2px solid var(--accent);
		box-shadow: var(--shadow-lg, 0 18px 48px color-mix(in srgb, var(--text) 22%, transparent));
	}
}

/* phone bottom nav — hidden on desktop */

.tabbar {
	display: none;
	position: fixed; left: 0; right: 0; bottom: 0;
	grid-template-columns: repeat(4, 1fr);
	border-top: 2px solid var(--line-strong);
	background: var(--bg);
	z-index: 5;
}
.tab {
	display: flex; align-items: center; justify-content: center;
	background: none; border: none; border-top: 3px solid transparent;
	padding: .7rem .2rem 1rem; cursor: pointer; text-decoration: none;
	font: 600 .74rem var(--font-heading); color: var(--muted); text-align: center; min-height: 56px;
}
.tab.active { font-weight: 800; color: var(--accent); border-top-color: var(--accent); }

.fab {
	display: none;
	position: fixed; right: 16px; bottom: 76px; z-index: 5;
	width: 64px; height: 64px;
	background: var(--accent); color: var(--accent-text); border: 1px solid var(--accent);
	font: 800 2rem/1 var(--font-heading); cursor: pointer;
	align-items: center; justify-content: center;
	border-radius: var(--radius);
}
.fab:hover { background: var(--accent-600); border-color: var(--accent-600); }

.sheet-row {
	display: flex; justify-content: space-between; align-items: center;
	background: none; border: none; border-bottom: 1px solid var(--line);
	padding: .9rem .6rem; font: 600 .95rem var(--font-heading); color: var(--text);
	cursor: pointer; text-align: left; text-decoration: none; min-height: 48px; width: 100%;
}
.sheet-row-danger { color: var(--ink-red); border-bottom: none; }

/* filter sheet: chip rows for date presets and accounts */

.chip-row { display: flex; flex-wrap: wrap; gap: .5rem; }
.field-row { display: flex; gap: .75rem; flex-wrap: wrap; }
.field-row label { flex: 1; min-width: 8.5rem; }

.chip {
	display: inline-flex; align-items: center; gap: .4rem;
	font: 600 .82rem var(--font-heading); padding: .55rem .75rem; min-height: 44px;
	cursor: pointer; border: 1px solid var(--line-strong);
	background: var(--surface); color: var(--text); text-decoration: none;
	border-radius: var(--radius);
}
/* A chip that is a <button> has the same leak; only its border was ever meant
   to react. The :not keeps an active chip's accent fill, which sits at a lower
   specificity than this hover; a checked toggle's fill matches specificity and
   is declared below, so source order carries it. */
.chip:not(.chip-active):hover { background: var(--surface); border-color: var(--accent); }
.chip-active, .chip-toggle:has(input:checked) .chip {
	border-color: var(--accent); background: var(--accent); color: var(--accent-text);
}
.chip-toggle input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }

.sheet-actions { display: flex; gap: .6rem; padding-top: .4rem; border-top: 2px solid var(--line-strong); }

@media (max-width: 640px) {
	.topbar nav, .topbar .user span:not(:first-child) { display: none; }
	.tabbar { display: grid; }
	.fab { display: flex; }
	.desktop-only { display: none; } /* its job is done by the fab down here */
	main { padding-bottom: 6rem; } /* clears the fixed tab bar */
}

.page-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; }

.feed { list-style: none; margin: 0 0 1rem; padding: 0; }
.feed-day {
	display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
	padding: 1.1rem .6rem .5rem; border-bottom: 2px solid var(--line-strong);
	font: 800 .74rem var(--font-heading); text-transform: uppercase; letter-spacing: .08em;
}
.feed-day .num { font: 400 .78rem var(--font-body); color: var(--muted); text-transform: none; letter-spacing: normal; }
.feed-item { border-bottom: 1px solid var(--line); }
/* Inset, not bled outwards: the accounts list sits inside a .card whose
   background makes any overhang visible. .feed-day carries the same .6rem so
   headers and rows stay on one left edge.

   --depth is the accounts tree's indentation level, set per row as an inline
   style. It is added here rather than written into that inline style so the
   base inset lives in one place — an inline `padding-left` would win outright
   and flatten every top-level row back against the edge. */
.feed-row {
	display: flex; width: 100%; gap: 1rem; align-items: center;
	background: none; border: none; padding: .8rem .6rem;
	padding-left: calc(.6rem + var(--depth, 0rem));
	text-align: left; cursor: pointer; font: inherit; color: inherit;
}
.feed-main { display: flex; flex-direction: column; gap: .15rem; min-width: 0; flex: 1; }
.feed-desc { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.feed-accline { font-size: .78rem; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.feed-amount { font: 800 1.05rem var(--font-heading); font-variant-numeric: tabular-nums; white-space: nowrap; }
.feed-amount.amount-income { color: var(--ink-red); }
.feed-amount.amount-transfer { color: var(--muted); }

.detail-head { display: flex; flex-direction: column; gap: .2rem; }
.detail-amount { font: 800 1.6rem/1.15 var(--font-heading); letter-spacing: -.015em; }
.detail-meta { font-size: .85rem; color: var(--muted); }
.detail-lines { display: flex; flex-direction: column; gap: .35rem; border-top: 2px solid var(--line-strong); padding-top: .8rem; }
.detail-line { display: flex; justify-content: space-between; gap: 1rem; padding: .35rem 0; border-bottom: 1px solid var(--line); }

.wizard-steps { display: flex; gap: 4px; }
.wizard-steps span { flex: 1; height: 3px; background: var(--line-strong); }
.wizard-steps span.wizard-step-on { background: var(--accent); }
.hint { margin: 0; font-size: .82rem; color: var(--muted); }

.wizard-leg { display: grid; grid-template-columns: 1fr 7.5rem auto; gap: .5rem; align-items: center; margin-bottom: .5rem; }
@media (max-width: 640px) {
	.wizard-leg { grid-template-columns: 1fr 6rem auto; }
}

.seg { display: inline-flex; border: 1px solid var(--line-strong); border-radius: var(--radius); overflow: hidden; }
.seg-opt {
	display: inline-flex; align-items: center; gap: 6px;
	padding: .6rem 1rem; font: 800 .82rem var(--font-heading); cursor: pointer;
	min-height: 44px;
}
.seg-opt + .seg-opt { border-left: 1px solid var(--line-strong); }
.seg-opt input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.seg-opt:has(input:checked) { background: var(--accent); color: var(--accent-text); }
.seg-opt:not(:has(input:checked)):hover { background: color-mix(in srgb, var(--text) 7%, transparent); }

a.seg-opt { text-decoration: none; color: var(--text); }
a.seg-opt[aria-current] { background: var(--accent); color: var(--accent-text); }

/* In a sheet the switcher is a form control inside a stretching flex column,
   so the box spans the full width whatever its display is — the options have
   to divide that width or the border runs on past them. On the reports page
   .seg sits in normal flow and is meant to hug its two labels, hence the
   scope. */
.sheet-body .seg { display: flex; }
.sheet-body .seg-opt { flex: 1; justify-content: center; }
