:root {
  --bg: #fbfaf8;
  --surface: #ffffff;
  --text: #1f1f1d;
  --muted: #6b6a65;
  --line: #e3e1db;
  --accent: #1f6f4a;
  --accent-soft: #e6f2ec;
  --danger: #a83232;
  --danger-soft: #f7e8e8;
  --disabled: #b9b7b0;
  --radius: 12px;
  --max-width: 720px;
}

* { box-sizing: border-box; }

/* 07.09.2026: in-app browser notice (see detectInAppBrowser/
   renderInAppBrowserBanner in app.js) — injected directly onto
   document.body, outside #app, so it survives every SPA re-render and
   sits above onboarding/app alike. Sticky rather than fixed so it
   doesn't need extra top-padding hacks on every other screen; amber
   "notice" tone (not --accent, not --danger) since this isn't a brand
   moment or an error, just a heads-up. */
.inapp-browser-banner {
  position: sticky;
  top: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  background: #fff4d6;
  color: #6b4f00;
  font-size: 15px;
  line-height: 1.35;
  border-bottom: 1px solid #f0dfa0;
}

.inapp-browser-banner span { flex: 1; }

.inapp-browser-banner-close {
  flex: none;
  background: none;
  border: none;
  color: inherit;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  padding: 0 2px;
}

/* 07.09.2026: renderInAppBrowserGate's escape hatch — deliberately NOT
   styled like .btn, so it doesn't compete with "Скопировать ссылку"
   (the actually-recommended action) for attention. Plain muted text,
   underlined so it still reads as clickable. */
.gate-continue-link {
  display: block;
  width: 100%;
  margin-top: 14px;
  background: none;
  border: none;
  color: var(--muted);
  text-decoration: underline;
  font-size: 15px;
  cursor: pointer;
  padding: 6px 0;
}

/* App-shell layout (17.08.2026 fix — see .bottom-nav below for why):
   html/body never scroll; #app is a full-height flex column and only
   its middle item (.wrap) scrolls. This is the second time a "fixed"
   bottom-nav has visually disappeared during scroll on mobile WebKit/
   Blink (position:fixed pinned to a page that itself scrolls is a
   known source of that class of bug — momentum-scroll repaint glitches,
   dynamic toolbar show/hide changing the viewport). Moving the nav out
   of the scrolling page entirely and making it a normal flex item
   removes the whole bug category, not just this one occurrence — no
   future long screen can reintroduce it by adding content, since
   nothing scrolls except .wrap. */
html, body {
  height: 100%;
  margin: 0;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  line-height: 1.5;
  /* 02.09.2026: dialed back from ×1.5 to ×1.25 of the original implicit
     browser default (16px) — ×1.5 read as too large on screen. Everything
     without its own explicit font-size — h1-h3, plain text inside
     kb-card-body, etc. — scales along with the explicit px values below,
     which were each also recalculated at ×1.25 (previously ×1.5, see
     31.08.2026 history in git log for that original pass). */
  font-size: 20px;
}

#app {
  height: 100vh;
  height: 100dvh; /* modern browsers only; ignored (falls back to 100vh) elsewhere */
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.wrap {
  flex: 1 1 auto;
  min-height: 0; /* flexbox default min-height:auto would otherwise ignore overflow-y and grow with content instead of scrolling */
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  width: 100%;
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 24px 20px calc(24px + env(safe-area-inset-bottom));
}

/* 20.08.2026 fix, take 3 — the take-2 negative-margin trick on
   .dashboard-sticky-top LOOKED right unscrolled but was still broken:
   per spec, a sticky element's stuck position is computed against its
   scrolling ancestor's PADDING edge, not its margin box — so the moment
   scrolling actually engaged stickiness, the browser re-anchored the
   header 24px below the true top (at .wrap's padding edge), exposing
   the exact gap the fix was meant to remove. Confirmed live via
   devtools: rect.y was 76 instead of 52 the instant it stuck.
   The only sticky-safe fix is to not give .wrap any top padding to
   begin with when a sticky child needs to reach the true top — this
   class (toggled in renderApp for the dashboard nav only) zeroes just
   that, while .dashboard-sticky-top supplies the same 24px visually via
   its own padding-top instead. */
.wrap.wrap-no-top-pad {
  padding-top: 0;
}

h1, h2, h3 { margin: 0 0 8px; }

/* TZ section 7, 13.08.2026: only the top-of-screen title centers (also
   fixes the edge-clipping compactness bug on narrow screens) — mid-page
   sub-headers (e.g. "Что почитать" in База знаний) stay left-aligned,
   so this is a dedicated class, not a blanket h2 rule. */
.screen-title {
  text-align: center;
}

button {
  font-family: inherit;
  cursor: pointer;
}

.btn {
  display: inline-block;
  border: none;
  border-radius: 8px;
  padding: 12px 20px;
  font-size: 20px;
  font-weight: 600;
  background: var(--accent);
  color: #fff;
}

.btn:disabled {
  background: var(--disabled);
  cursor: not-allowed;
}

.btn.secondary {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--line);
}

.field {
  margin-bottom: 18px;
}

.field label {
  display: block;
  font-size: 17.5px;
  font-weight: 600;
  color: var(--muted);
  margin-bottom: 6px;
}

.field input[type="text"],
.field input[type="number"],
.field input[type="email"],
.field input[type="password"],
.field select,
.field textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 20px;
  background: var(--surface);
  color: var(--text);
}

.field textarea { resize: vertical; min-height: 90px; }

/* Referral share text (31.08.2026) — same look as .field textarea above,
   but a plain block instead of a form control, so it grows with its
   content and can't clip like a fixed rows="N" textarea can. See
   renderReferralSettings in app.js for why a real textarea isn't
   needed here. */
.referral-text-box {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text);
  white-space: pre-wrap;
  word-break: break-word;
}

/* Bedtime picker (TZ, 17.08.2026) — two selects side by side instead of
   a native <input type="time">, see timePickerHtml in app.js. */
.time-picker-row {
  display: flex;
  align-items: center;
  gap: 6px;
}

.time-picker-row select {
  flex: 1;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 20px;
  background: var(--surface);
  color: var(--text);
}

.time-picker-sep {
  color: var(--muted);
  font-weight: 600;
}

.field .hint {
  font-size: 16.5px;
  color: var(--muted);
  margin-top: 4px;
}

.hint-details {
  margin-top: 6px;
}

.hint-details summary {
  cursor: pointer;
  display: inline-block;
  font-size: 20px;
  color: var(--muted);
  list-style: none;
}

.hint-details summary::-webkit-details-marker { display: none; }
.hint-details summary::marker { content: ""; }

.hint-details[open] summary {
  margin-bottom: 2px;
}

.hint-details .hint {
  margin-top: 0;
}

/* Ideal-target hints (05.09.2026) — same collapsed .hint-details mechanism,
   marked with a short "(цель)"/"(target)" word instead of "ⓘ" and tinted
   with the accent color so it reads as a distinct kind of hint (the
   formula's target value) even on fields that already show a plain ⓘ
   methodology hint.
   05.09.2026, second pass (user feedback: the standalone "★" sat on its
   own line eating vertical space and didn't self-explain): this variant
   is inline-sized so call sites can append it straight onto a field's
   <label> text (same line, small trailing note) instead of stacking it
   as its own block under the input/select. Only the closed summary is
   inline — once tapped open, the revealed .hint text still flows as a
   normal block underneath, same as every other .hint-details. */
.ideal-hint-details {
  display: inline;
  margin-top: 0;
  margin-left: 6px;
}

.ideal-hint-details summary {
  display: inline;
  font-size: 15.5px;
  color: var(--accent);
}

.ideal-hint-details .hint {
  display: block;
  margin-top: 4px;
}

/* Alcohol input, collapsed by default (17.08.2026) — same details/
   summary pattern as .hint-details above, but the summary itself is a
   full field-label-sized tappable row (it replaces three separate field
   labels), with a chevron instead of hidden native marker.
   21.08.2026: styled as a bordered card (same look as .kb-card in the
   Knowledge base accordion) — plain muted text with no border read as
   inert, not tappable, in onboarding testing. */
.alcohol-details {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 16px;
}

.alcohol-details summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 19px;
  font-weight: 600;
  color: var(--text);
}

.alcohol-details[open] summary {
  margin-bottom: 10px;
}

.alcohol-details summary::-webkit-details-marker { display: none; }
.alcohol-details summary::marker { content: ""; }

.alcohol-details summary::after {
  content: " ▾";
}

.alcohol-details[open] summary::after {
  content: " ▴";
}

.radio-row {
  display: flex;
  gap: 16px;
}

.radio-row label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 19px;
  font-weight: 400;
  color: var(--text);
}

.optional-badge {
  display: inline-block;
  font-size: 15px;
  font-weight: 600;
  color: var(--muted);
  background: var(--accent-soft);
  border-radius: 4px;
  padding: 2px 6px;
  margin-left: 6px;
}

.required-mark {
  color: var(--danger);
  margin-left: 2px;
}

.checkbox-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.checkbox-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 19px;
  font-weight: 400;
  color: var(--text);
}

.checkbox-list input[type="text"] {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 20px;
  background: var(--surface);
  color: var(--text);
}

/* Settings sub-navigation (TZ section 7, 13.08.2026): Служба заботы/
   Фонд идей and the factor-visibility checklist live behind these two
   rows now instead of their own bottom-nav icons. */
.settings-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 24px;
}

.settings-row {
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 16px;
  font-size: 20px;
  font-weight: 600;
  color: var(--text);
  text-decoration: none;
}

.settings-row-disabled {
  color: var(--muted);
  cursor: default;
}

/* Onboarding */
/* Single-button language switcher (30.08.2026): was two always-visible
   RU/EN buttons; now a <details> disclosure — .lang-current is the
   <summary> showing just the active language's code, .lang-menu is the
   dropdown body with one .lang-option button per SUPPORTED_LANGUAGES
   entry. Positioned relatively so the dropdown can sit absolutely under
   it without shifting layout. */
.lang-switcher {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 12px;
  position: relative;
}

.lang-current {
  display: inline-block;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--muted);
  border-radius: 6px;
  padding: 4px 10px;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}

.lang-current::-webkit-details-marker { display: none; }
.lang-current::marker { content: ""; }

.lang-switcher[open] .lang-current {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}

.lang-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 20;
  min-width: 120px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.lang-option {
  border: none;
  background: transparent;
  text-align: left;
  padding: 6px 8px;
  border-radius: 6px;
  font-size: 17.5px;
  color: var(--text);
  cursor: pointer;
}

.lang-option.active {
  font-weight: 700;
  color: var(--accent);
  cursor: default;
}

.onboarding-step-counter {
  font-size: 16.5px;
  font-weight: 600;
  color: var(--muted);
  margin-bottom: 6px;
}

.onboarding-header {
  margin-bottom: 24px;
}

.onboarding-header p {
  color: var(--muted);
  margin: 4px 0 0;
}

/* 07.09.2026: the "5 required questions" line demoted from the hook
   (see welcome.title/intro + renderWelcomeScreen) to a small effort-
   preview note — same muted, slightly smaller treatment as .field .hint
   so it doesn't compete visually with the headline above it. */
.welcome-questions-note {
  font-size: 16.5px;
  color: var(--muted);
  margin: 0 0 20px;
}

/* 11.09.2026, Welmi onboarding audit: a short trust beat right before the
   consent checkbox — separate from the legal dataNote/disclaimer text
   above it, and visually distinct (tinted card, not another muted
   paragraph) so it reads as reassurance, not more fine print. */
.welcome-trust-card {
  display: flex;
  align-items: center;
  gap: 12px;
  background: rgba(31, 111, 74, 0.08);
  border-radius: 12px;
  padding: 14px 16px;
  margin: 0 0 20px;
}

.welcome-trust-icon {
  font-size: 22px;
  line-height: 1;
  flex-shrink: 0;
}

.welcome-trust-card p {
  margin: 0;
  font-size: 15px;
  color: var(--text);
}

.progress-dots {
  display: flex;
  gap: 6px;
  margin-bottom: 20px;
}

.progress-dots span {
  height: 4px;
  flex: 1;
  border-radius: 2px;
  background: var(--line);
}

.progress-dots span.done {
  background: var(--accent);
}

.step-nav {
  display: flex;
  justify-content: space-between;
  margin-top: 28px;
}

.reveal-number {
  text-align: center;
  padding: 40px 0;
}

.reveal-number .value {
  font-size: 60px;
  font-weight: 700;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.reveal-number .label {
  color: var(--muted);
  margin-top: 8px;
}

.reveal-number .reveal-phrase {
  margin-top: 14px;
  font-size: 21.5px;
  font-weight: 600;
  color: var(--accent);
}

.reveal-number .reveal-comparison {
  margin-top: 8px;
  font-size: 17.5px;
  color: var(--muted);
}

/* Nav (TZ section 7, 13.08.2026: icon-only bottom nav + minimal top bar).
   Both bars are now plain flex items of the #app column (see the
   app-shell layout above) — neither needs sticky/fixed positioning
   since the page around them never scrolls; only .wrap does. */
.top-bar {
  flex: 0 0 auto;
  height: 52px;
  background: var(--bg);
  display: flex;
  align-items: stretch;
  justify-content: flex-end;
  border-bottom: 1px solid var(--line);
}

.top-icons {
  display: flex;
  align-items: center;
  padding-right: 16px;
}

.icon-btn {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: none;
  padding: 8px;
  color: var(--muted);
}

/* Bell sits right up against Профиль (TZ, 13.08.2026) — only the pair
   between them is tight, the icon-btn's own padding still gives the
   rest of the row (and the touch target) room to breathe. */
.top-icons .icon-btn + .icon-btn {
  margin-left: -4px;
}

/* Raised, floating bar (TZ, 13.08.2026 — "по аналогии с Гармином"),
   not flush against the screen edge like the earlier flush version.
   17.08.2026: no longer position:fixed — it's a normal flex item at
   the bottom of #app's column, so the 12px/14px inset that used to be
   left/right/bottom offsets is now plain margin instead. */
.bottom-nav {
  flex: 0 0 auto;
  margin: 0 12px calc(14px + env(safe-area-inset-bottom));
  height: 56px;
  display: flex;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 18px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
}

.icon-nav-btn {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: none;
  color: var(--muted);
}

.icon-nav-btn.active {
  color: var(--accent);
}

/* Dashboard */
/* 20.08.2026 fix, take 3 (see .wrap.wrap-no-top-pad above for the full
   explanation of why take 2's negative-margin trick didn't survive
   actual stickiness). .wrap has no top padding for the dashboard now,
   so this element's own top edge IS the scrollport's true top — "top:0"
   sticks it flush with no gap, in both the unscrolled and stuck states.
   padding-top here reproduces the same 24px visual spacing .wrap used
   to provide; horizontal padding still comes from .wrap as before. */
.dashboard-sticky-top {
  position: sticky;
  top: 0;
  z-index: 5;
  padding-top: 24px;
  background: var(--bg);
}

.dashboard-sticky-top .screen-title {
  padding-top: 4px;
}

.capital-header {
  text-align: center;
  padding: 28px 0 8px;
}

.capital-header .capital-value {
  font-size: 50px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.capital-header .capital-value.positive { color: var(--accent); }
.capital-header .capital-value.negative { color: var(--danger); }

/* 31.08.2026: the number and the unit word are now separate spans (see
   renderDashboard) specifically so this word can run smaller than the
   number next to it — "дней" spelled out in full at the same 60px as
   the number risked not fitting/wrapping on narrower phones, "дн." did
   fit but the user wants the full word. 0.5em keeps it legible while
   keeping the number itself the visual focus. */
.capital-value-unit {
  font-size: 0.5em;
  font-weight: 600;
  margin-left: 2px;
}

.capital-trend {
  font-size: 19px;
  color: var(--muted);
  margin-top: 6px;
}

.capital-trend.positive { color: var(--accent); }
.capital-trend.negative { color: var(--danger); }

.starting-ref {
  text-align: center;
  font-size: 17.5px;
  color: var(--muted);
  margin-bottom: 16px;
}

.disclaimer {
  font-size: 16.5px;
  color: var(--muted);
  text-align: center;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding: 10px 0;
  margin: 16px 0 24px;
}

.period-switch {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin: 12px 0 20px;
}

.period-switch button {
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: 999px;
  padding: 6px 16px;
  font-size: 17.5px;
  color: var(--muted);
}

.period-switch button.active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

.chart-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 20px;
}

.chart-card svg { width: 100%; height: auto; display: block; }

.log-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 18px;
  margin-bottom: 20px;
}

.log-row {
  display: flex;
  gap: 12px;
  align-items: flex-end;
  margin-bottom: 12px;
}

.log-row .field { flex: 1; margin-bottom: 0; }

/* Nutrition redesign (20.08.2026) — 6 separate cards instead of fields
   inside one shared .log-card; see nutritionRowHtml/renderFactorEditScreen
   in app.js. Same visual language as .log-card, just repeated per tile
   with spacing between so each reads as its own plate. */
.nutrition-tile {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 12px;
}

.nutrition-tile h3 {
  font-size: 20px;
  margin-bottom: 12px;
}

.nutrition-tile .field:last-child { margin-bottom: 0; }
.nutrition-tile .log-row:last-child { margin-bottom: 0; }

/* Amount + unit side by side (same pattern as .time-picker-row) — the
   amount input gets most of the width, the мл/л select stays narrow. */
.nutrition-water-row input[type="number"] {
  flex: 3;
}

.nutrition-water-row select {
  flex: 1;
  min-width: 72px;
}

.methodology-warning {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 10px 14px;
  font-size: 17.5px;
  color: var(--text);
  margin: 4px 0 16px;
}

.next-step-card {
  background: var(--accent-soft);
  border-radius: var(--radius);
  padding: 16px 18px;
  margin-bottom: 20px;
}

.next-step-card .kicker {
  font-size: 15px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--accent);
  margin-bottom: 4px;
}

.engagement-card {
  text-align: center;
  font-weight: 600;
  font-size: 20px;
  border-radius: var(--radius);
  padding: 12px 18px;
  margin-bottom: 20px;
}

.engagement-card.positive {
  background: var(--accent-soft);
  color: var(--accent);
}

.engagement-card.negative {
  background: var(--danger-soft);
  color: var(--danger);
}

.factor-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 24px;
}

.factor-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px;
  position: relative;
}

/* "Отметить сегодня" card already filled in today's ledger — added
   04.09.2026 per Sergey's request, so reopening the app mid-day shows
   at a glance what's already logged instead of the user having to
   remember or reopen each card. Reuses the app's existing positive/
   accent tokens (same ones the capital header and engagement card use)
   rather than a new color, and pairs the tint with a checkmark glyph
   rather than relying on color alone. */
.factor-card.filled {
  background: var(--accent-soft);
  border-color: var(--accent);
}

.filled-check {
  position: absolute;
  top: 10px;
  right: 12px;
  color: var(--accent);
  font-weight: 700;
  font-size: 16px;
  line-height: 1;
}

.factor-card.clickable {
  cursor: pointer;
  text-align: left;
  width: 100%;
  font-family: inherit;
  appearance: none;
  -webkit-appearance: none;
}

/* Per-factor entry screen (20.08.2026, take 2 — replaces the earlier
   bottom-sheet overlay, which on real devices left the Save/Cancel row
   unreachable behind the on-screen keyboard/looked "criво-косо"). Now a
   plain full-screen page, same pattern as "Транзакции за день" /
   "Изменить день": a normal scrolling page in the flow of .wrap, with a
   full-width Save button as the last element — nothing fixed/overlaid,
   nothing for the keyboard to cover. */
.factor-edit-screen h3 {
  margin-bottom: 16px;
}

.factor-edit-save {
  width: 100%;
  margin-top: 8px;
}

.factor-card .name { font-weight: 600; font-size: 19px; }

/* "Полная история" summary card at the bottom of История (26.08.2026,
   renamed from "Вложения и дивиденды" 29.08.2026) reuses
   .factor-card.clickable but adds a muted subtitle line below the
   name — same visual language as .field .hint, scoped here since this
   card sits outside any .field. */
.factor-card .hint { font-size: 16.5px; color: var(--muted); margin-top: 4px; }

.feed-list {
  list-style: none;
  margin: 0 0 24px;
  padding: 0;
}

.feed-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
  font-size: 19px;
}

.feed-item .badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.feed-item .icon {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 16.5px;
  font-weight: 700;
  color: #fff;
}

.icon.smoke { background: var(--danger); }
.icon.sport { background: var(--accent); }
.icon.sleep { background: var(--muted); }
.icon.alcohol { background: var(--muted); }

.feed-item .amount.positive { color: var(--accent); font-weight: 600; }
.feed-item .amount.negative { color: var(--danger); font-weight: 600; }

.feed-item .date { color: var(--muted); font-size: 16.5px; }

/* Knowledge — cards are <details> accordions (20.08.2026: was one long
   wall of text per card, now collapsed by default; tap the name to
   expand). */
.kb-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px 18px;
  margin-bottom: 14px;
}

.kb-card summary {
  cursor: pointer;
  list-style: none;
}

.kb-card summary::-webkit-details-marker { display: none; }
.kb-card summary::marker { content: ""; }

/* Down when closed, up when open (31.08.2026, take 2). The earlier
   "always down" version above was working around a real CSS bug, not a
   design choice: `.kb-card[open] summary::after` (no child combinator)
   matches ANY summary nested inside an open .kb-card, so once nesting
   was introduced ("8 маркеров" wrapping the marker cards), opening the
   outer card flipped every inner card's arrow too, even ones still
   collapsed — that's what actually looked "inconsistent". The real fix
   is scoping each rule to the card's OWN summary with `>`, so a card's
   arrow only reflects its own [open] state, never an ancestor's. */
.kb-card > summary::after {
  content: " ▾";
  color: var(--muted);
  font-weight: 400;
}

.kb-card[open] > summary::after {
  content: " ▴";
}

.kb-card-body {
  margin-top: 10px;
}

.kb-card .name { font-weight: 700; }
.kb-card .source { font-size: 16.5px; color: var(--muted); margin-top: 8px; }
.kb-card.disabled { opacity: 0.7; }

/* Norm tables inside kb-card-body (31.08.2026: "8 маркеров долголетия"
   section — the only place in the Knowledge Base that renders <table>). */
.kb-card-body table {
  width: 100%;
  border-collapse: collapse;
  font-size: 17.5px;
  margin: 4px 0;
}
.kb-card-body th,
.kb-card-body td {
  text-align: left;
  padding: 6px 8px;
  border-bottom: 1px solid var(--line);
}
.kb-card-body th { color: var(--muted); font-weight: 600; }

/* Ideal-targets cheat sheet (05.09.2026) — summary table at the top of the
   Knowledge Base screen, same bordered-card look as .kb-card so it reads
   as part of the same screen rather than a different component. */
.ideal-targets-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 18px;
  margin-bottom: 20px;
}

.ideal-targets-table {
  width: 100%;
  border-collapse: collapse;
}

.ideal-targets-table tr:not(:last-child) td {
  border-bottom: 1px solid var(--line);
}

.ideal-targets-table td {
  padding: 8px 0;
  font-size: 17.5px;
  vertical-align: top;
}

.ideal-targets-factor {
  font-weight: 700;
  white-space: nowrap;
  width: 40%;
  padding-right: 12px;
}

.ideal-targets-value {
  color: var(--muted);
}

.reading-list {
  padding-left: 18px;
  color: var(--muted);
  font-size: 19px;
}

.note {
  font-size: 16.5px;
  color: var(--muted);
  margin-top: -6px;
  margin-bottom: 16px;
}

/* Amounts (generic — used in the feed list, and in the История modal) */
.amount.positive { color: var(--accent); }
.amount.negative { color: var(--danger); }

/* Tappable amount → breakdown (TZ, 12.08.2026 pattern; reused 13.08.2026
   inside the "Транзакции за день" modal instead of a table cell). */
.report-cell summary {
  cursor: pointer;
  list-style: none;
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}

.report-cell summary::-webkit-details-marker { display: none; }
.report-cell summary::marker { content: ""; }

/* 31.08.2026, user request: same down-closed/up-open convention as
   .kb-card (see that rule for why the `>` child combinator matters —
   .report-cell can itself sit nested inside a .kb-card-body, on the
   "История по дням" per-date cards, so scoping to each element's own
   direct summary avoids the same open/closed leak bug fixed there). */
.report-cell > summary::after {
  content: " ▾";
  color: var(--muted);
  font-weight: 400;
}

.report-cell[open] > summary::after {
  content: " ▴";
}

.report-cell[open] {
  white-space: normal;
}

.decay-detail-row {
  font-size: 17.5px;
  color: var(--muted);
  padding: 4px 0;
  white-space: nowrap;
}

/* History (calendar heatmap), TZ section 7, 13.08.2026 */
.history-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
}

.history-nav .btn.secondary {
  padding: 8px 16px;
}

.month-label {
  font-weight: 600;
  font-size: 20px;
}

.history-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
  margin-bottom: 4px;
}

.history-weekdays {
  margin-bottom: 8px;
}

.weekday-label {
  text-align: center;
  font-size: 15px;
  color: var(--muted);
  font-weight: 600;
}

.day-cell {
  aspect-ratio: 1;
  border: none;
  border-radius: 6px;
  font-size: 16.5px;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  padding: 0;
  background: none;
  width: 100%;
}

.day-cell.pad {
  background: transparent;
}

.day-cell.empty {
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--muted);
}

/* Binary legend (TZ, 13.08.2026 — replaces the earlier 4-tier
   intensity idea): green/red/no-color only, no on-screen legend text —
   colors are meant to read as self-evident, same convention as most
   habit-tracker apps. */
.day-cell.positive { background: #1f6f4a; color: #fff; }
.day-cell.negative { background: #a83232; color: #fff; }

/* Outside the retroactive-editing window (TZ, 16.08.2026) — still
   visible with its real color, just dimmed; a day with no data becomes
   non-interactive (native disabled) instead of opening an empty form. */
.day-cell.locked {
  opacity: 0.45;
}

.day-cell.locked:disabled {
  cursor: not-allowed;
}

/* "Транзакции за день" row (now a full screen, not a modal — TZ
   13.08.2026 — kept the .modal-row name since it's still just a row
   layout, no longer inside an actual modal). */
.modal-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
  font-size: 19px;
}

.modal-row:last-child {
  border-bottom: none;
}

/* Ideas */
.idea-item {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 16px;
  margin-bottom: 12px;
}

.idea-item .cat {
  display: inline-block;
  font-size: 15px;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-soft);
  border-radius: 4px;
  padding: 2px 6px;
  margin-bottom: 6px;
}

.idea-item .date { font-size: 16.5px; color: var(--muted); float: right; }

.empty-state {
  text-align: center;
  color: var(--muted);
  padding: 40px 0;
  font-size: 19px;
}

.section-tabs {
  display: flex;
  gap: 8px;
  margin-bottom: 18px;
}

.section-tabs button {
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: 999px;
  padding: 8px 16px;
  font-size: 17.5px;
  color: var(--muted);
}

.section-tabs button.active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
