/* ── Design tokens from Telegram theme ──────────────────────────────────── */
:root {
  /* FIXED brand palette (design 668) — the app no longer consumes the Telegram theme:
     one identical look on every device/theme. Derived tokens (--separator, --surface-2,
     color-mix tints) now compute from these fixed values. */
  --bg:          #0f1216;
  --text:        #e8edf2;
  --hint:        #8a94a0;
  --link:        #5aa7e8;
  --accent:      #2481cc;
  --accent-text: #ffffff;
  --card-bg:     #171c22;

  /* Two-step radius scale (design pass 664): --r-md = cards/surfaces/full-width buttons,
     --r-sm = pills, compact buttons, inputs, small chips. --radius stays as a back-compat
     alias of --r-md (all in-file usages migrated to var(--r-md)). */
  --r-sm:    10px;
  --r-md:    14px;
  --radius:  var(--r-md);
  --pad:     18px;
  --gap:     12px;
  --tab-h:   56px;

  /* Semantic status/brand colors — intentionally theme-INDEPENDENT (NOT --tg-theme-* backed):
     they must stay legible on both light and dark. One value per family, collapsing the former
     literal sprawl (see PROMPT 618/621). */
  --danger:        #e05c5c;
  --danger-tint:   rgba(224,92,92,.15);
  --success:       #34c759;
  --success-tint:  rgba(52,199,89,.16);
  --warning:       #ff9500;
  --warning-text:  var(--warning);   /* fixed dark palette: warning text reads bright (was dark amber for light fills) */
  --warning-tint:  rgba(255,149,0,.15);
  --info:          #6490c8;
  --info-tint:     rgba(100,144,200,.14);
  --surface-2:     rgba(128,128,128,.14);   /* DEFINE the phantom — was only ever a fallback */
  /* Hairline separators (row borders, section dividers, underlines): ONE strength derived
     from --text so it reads on any Telegram theme (light AND dark). */
  --separator:     color-mix(in srgb, var(--text) 12%, transparent);
  --pill-radius:   var(--r-sm);
  --fs-pill:       12px;
  --fw-pill:       700;
  --btn-compact-radius: var(--r-sm);
}

/* ── Reset ──────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: system-ui, -apple-system, "Helvetica Neue", sans-serif;
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  /* Belt-and-suspenders: no document-level rubber-band even if a scroll chain escapes. */
  overscroll-behavior: none;
}

/* ── App shell ──────────────────────────────────────────────────────────── */
#app {
  display: flex;
  flex-direction: column;
  height: 100dvh;
  overflow: hidden;
  /* Disable iOS double-tap-to-zoom (annoying with the double-confirm buttons) while KEEPING
     single taps, scrolling (pan), and pinch-zoom. `manipulation` = auto minus double-tap-zoom;
     NOT `none` (which would kill scrolling). Child elements with their own touch-action
     (.dw-col pan-y, .csvg-wrap/.chain-box none) still override for their subtrees. */
  touch-action: manipulation;
}

#main {
  flex: 1;
  overflow: hidden;
  position: relative;
}

/* ── Screens & panels ───────────────────────────────────────────────────── */
.screen,
.panel {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  /* contain = stop scroll-chaining to the document (no whole-app drift) while keeping the
     element's own native rubber-band (small pull → springs back to the last item). */
  overscroll-behavior-y: contain;
}

.screen {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: var(--pad);
  text-align: center;
}

.panel {
  padding: var(--pad) var(--pad) 20px;
}

/* WIP placeholder panels override padding for centering */
.panel.wip {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: var(--pad);
}

[hidden] { display: none !important; }

/* ── Detail overlay ─────────────────────────────────────────────────────── */
.detail-overlay {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overscroll-behavior-y: contain;
  background: var(--bg);
  padding: var(--pad) var(--pad) 32px;
}

/* ── Typography ─────────────────────────────────────────────────────────── */
.big-icon   { font-size: 48px; line-height: 1; }
.wip-title  { font-size: 20px; font-weight: 600; color: var(--text); }
.panel-title { font-size: 22px; font-weight: 700; margin-bottom: 20px; padding-top: 2px; }
.body-text  { font-size: 16px; line-height: 1.55; }
.hint-text  { font-size: 14px; color: var(--hint); }
.center-text { text-align: center; }

/* ── Spinner ────────────────────────────────────────────────────────────── */
.spinner {
  width: 36px;
  height: 36px;
  border: 3px solid var(--card-bg);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin .75s linear infinite;
  flex-shrink: 0;
}

@keyframes spin { to { transform: rotate(360deg); } }

/* ── Tab bar ────────────────────────────────────────────────────────────── */
#tab-bar {
  display: flex;
  background: var(--card-bg);
  border-top: 1px solid var(--separator);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  flex-shrink: 0;
}

.tab-btn {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-height: var(--tab-h);
  border: none;
  background: none;
  cursor: pointer;
  color: var(--hint);
  padding: 8px 4px 6px;
  -webkit-tap-highlight-color: transparent;
  transition: color .15s;
  font-size: inherit;
}

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

.tab-btn svg {
  width: 22px;
  height: 22px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex-shrink: 0;
}

.tab-label {
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
}

/* ── Cards (дела list) ──────────────────────────────────────────────────── */
.card-list {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}

.delo-card {
  background: var(--card-bg);
  border-radius: var(--r-md);
  padding: 14px 16px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: opacity .12s;
  user-select: none;
}

.delo-card:active { opacity: .65; }

@keyframes _deloCardIn {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.delo-card.delo-new {
  animation: _deloCardIn .32s cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
}
@media (prefers-reduced-motion: reduce) {
  .delo-card.delo-new { animation: none; }
}

/* Read-only дело card (restore triage panel) — no tap affordance. */
.delo-card--static { cursor: default; }
.delo-card--static:active { opacity: 1; }

/* One row of the restore panel: the read-only дело line + its Да/Нет segmented toggle. */
.restore-row {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.restore-step {
  font-size: 12px;
  color: var(--hint);
  align-self: center;
}

.card-top {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-bottom: 10px;
}

/* ── Canonical pill system ──────────────────────────────────────────────────
   .pill = the shared geometry for every small badge/chip; .pill--X = the color role.
   The дело-card top-pill family (apt/urgent/chain/sys/party) is migrated to this; other
   badge families follow in later steps. flex-shrink/letter-spacing/font-family are carried
   over from the old family so the look is preserved (only radius 7→8 shifts, by design). */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
  border: none;                                       /* button-pills w/o --outline show no UA border */
  border-radius: var(--pill-radius);
  padding: 3px 9px;
  font-family: inherit;
  font-size: var(--fs-pill, 12px);
  font-weight: var(--fw-pill, 700);
  letter-spacing: .3px;
  line-height: 20px;
  white-space: nowrap;
}
.pill--accent  { background: var(--accent);       color: var(--accent-text); }
.pill--danger  { background: var(--danger);        color: var(--accent-text); }
.pill--danger-tint { background: var(--danger-tint); color: var(--danger); }  /* soft red (owes) */
.pill--success { background: var(--success-tint);  color: var(--success); }
.pill--warning { background: var(--warning-tint);  color: var(--warning-text); }
.pill--info    { background: var(--info-tint);     color: var(--info); }
.pill--muted   { background: var(--surface-2);     color: var(--hint); }
.pill--tint    {
  background: var(--surface-2);                     /* neutral fallback for engines w/o color-mix */
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
}
.pill--outline {
  background: transparent;
  color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 55%, transparent);
}
/* Grey outline variant (e.g. the admin "Сотрудник" badge) — hint text + hint border, so it stays
   grey rather than accent-colored. Border uses --hint (not --surface-2) to match the prior look. */
.pill--outline-muted {
  background: transparent;
  color: var(--hint);
  border: 1px solid var(--hint);
}
/* Lighter weight for dense multi-tag lists (e.g. the Незаполненные field tags) where the .pill
   base 700 reads too heavy. */
.pill--light { font-weight: 500; }
/* Size modifier for the apartment-card status "matched set" (occupied / vacant / в процессе /
   action button) — uniform 28px height + 82px min-width so the pill row stays aligned. Weight 600
   (the status family was 600, overriding the .pill base 700). */
.pill--status {
  height: 28px;
  min-width: 82px;
  justify-content: center;
  padding: 3px 12px;
  font-weight: 600;
}

/* Selectable multi-choice chip (contact-classify roles): tap-friendly pill,
   grey outline inactive → solid accent fill when .active. */
.pill--choice {
  min-height: 36px;
  padding: 3px 14px;
  font-size: 14px;
  font-weight: 600;
  background: transparent;
  color: var(--hint);
  border: 1.5px solid var(--hint);
  cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
  -webkit-tap-highlight-color: transparent;
}
.pill--choice.active {
  background: var(--accent);
  color: var(--accent-text);
  border-color: var(--accent);
}

/* Larger data pill (owner-balance badges): 28px+ height, 14px/600 — .pill--status precedent. */
.pill--big {
  min-height: 28px;
  font-size: 14px;
  font-weight: 600;
  padding: 4px 12px;
}

/* Large tappable pill (Задачи "Срочно N" filter): 34px height, 14px. */
.pill--lg {
  min-height: 34px;
  padding: 0 14px;
  font-size: 14px;
  justify-content: center;
}
/* Button interaction for the action pills (Заселить/Выселить) — scoped to <button> so the
   non-interactive span badges (occupied/vacant/в процессе) are unaffected. Folds the old
   .apt-action-btn tap behavior. */
button.pill--status {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: opacity .15s;
}
button.pill--status:active   { opacity: .75; }
button.pill--status:disabled { opacity: .45; cursor: default; }

/* Tasks-tab title row: "Задачи" heading + right-aligned "Срочно N" filter pill. */
.tasks-title-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 20px;
}
.tasks-title-row .panel-title {
  flex: 1;
  margin-bottom: 0;
}

/* "Срочно N" filter pill — a header toggle brought into the .pill family (radius --pill-radius,
   danger colours). Inactive = danger OUTLINE (transparent bg + 1px --danger border + --danger text);
   active (.is-active) = solid --danger fill. Kept at 14px/700 + a 34px tap-height (it's a header
   control next to the title, not a card badge) but now shares the family's 8px corner. Toggle logic
   is unchanged (id=tasks-urgent-btn + .is-active). */
/* Danger-outline look + toggle behaviour; geometry/typography from .pill.pill--lg. */
.tasks-urgent-pill {
  flex: 0 0 auto;
  border: 1px solid var(--danger);
  background: transparent;
  color: var(--danger);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.tasks-urgent-pill.is-active {
  background: var(--danger);
  color: var(--accent-text);
  border-color: transparent;
}

/* .apt-badge / .urgent-badge / .chain-badge / .sys-badge migrated to .pill + .pill--accent /
   --danger / --muted / --tint (see the canonical pill system above). */

/* Addressee (Жилец/Владелец) pill. Visuals now come from .pill + .pill--outline (tappable link)
   or .pill--muted (inert). This rule keeps ONLY the tap behavior + the ↗ arrow: the delegated
   click handler (app.js:45) selects .party-badge--link, so the tappable variant retains that
   class, and the ↗ is its ::after. */
.party-badge--link {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.party-badge--link::after {
  content: "↗";
  margin-left: 3px;
}

.card-chain {
  margin-left: auto;
  font-size: 12px;
  color: var(--hint);
  font-weight: 500;
  white-space: nowrap;
  padding-top: 2px;
}

.card-text {
  font-size: 15px;
  line-height: 1.5;
  color: var(--text);
  overflow-wrap: break-word;
  white-space: pre-line;   /* multi-line дело texts (e.g. КУ ⚠️ warning lines) keep their \n */
}

.card-date {
  margin-top: 10px;
  font-size: 12px;
  color: var(--hint);
}

/* Card hint line in warning tone (e.g. REP.4 «День прошёл…») — same size/placement
   family as .card-date, color from the semantic warning token. */
.card-hint-warning {
  margin-top: 8px;
  font-size: 12px;
  color: var(--warning-text);
}
/* Neutral sibling (e.g. GEL conversion line on rent cards, 699). */
.card-hint-muted {
  margin-top: 8px;
  font-size: 12px;
  color: var(--hint);
}

/* ── Задачи answer controls ──────────────────────────────────────────────── */

.delo-answer-section {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--hint);
}

.delo-answer-choices {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.delo-answer-row,
.delo-vacancy-row {
  display: flex;
  gap: 8px;
  align-items: center;
}

/* ── Canonical compact-button system ────────────────────────────────────────
   .btn-compact = the shared geometry for small inline action buttons; .btn-compact--X = the color
   role. The дело-answer family is migrated to this; other compact families follow in later steps.
   (.delo-answer-btn stays in the markup as a JS click-hook — see app.js.) */
.btn-compact {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: none;
  cursor: pointer;
  font-family: inherit;
  border-radius: var(--btn-compact-radius, 8px);
  padding: 8px 16px;
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;                     /* answer labels stay on one line (was on .delo-answer-btn) */
  transition: opacity .15s;
  -webkit-tap-highlight-color: transparent;
}
.btn-compact:active   { opacity: .8; }
.btn-compact:disabled { opacity: .45; cursor: default; }
.btn-compact--accent  { background: var(--accent);     color: var(--accent-text); }
.btn-compact--muted   { background: var(--surface-2);  color: var(--text); }
.btn-compact--danger  { background: var(--danger);     color: var(--accent-text); }
.btn-compact--success { background: var(--success);    color: var(--accent-text); }
/* Soft tint variants (e.g. the owner-balance pay/charge toggles) — colored text on a faint fill,
   NOT a solid fill. currentColor (the text color) also drives the .ledger-toggle-btn.is-active ring. */
.btn-compact--success-tint { background: var(--success-tint); color: var(--success); }
.btn-compact--danger-tint  { background: var(--danger-tint);  color: var(--danger); }
.btn-compact--outline {
  background: transparent;
  color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 55%, transparent);
}
/* Grey outline variant (e.g. the дело-answer escape/skip buttons "Пропустить"/"Владелец ничего не
   заплатил") — transparent + hint text + hint border, reproducing the prior --escape outline. */
.btn-compact--outline-muted {
  background: transparent;
  color: var(--hint);
  border: 1px solid var(--hint);
}
/* Square icon button (36×36) — geometry-only modifier (same bespoke-geometry-on-base
   pattern as .term-stepper-btn). Colour comes from a colour modifier / retained class. */
.btn-compact--icon {
  width: 36px;
  height: 36px;
  padding: 0;
  flex: 0 0 auto;
  font-size: 20px;
  line-height: 1;
}

/* Month-count stepper (NC.10_custom contract term): − [big N] + , then a submit button. */
.term-stepper {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
/* +/- stepper buttons: color (solid accent) from .btn-compact.btn-compact--accent; this class is
   RETAINED for the square icon-button geometry that .btn-compact doesn't carry — a fixed 48×48 box
   (padding:0), a larger 12px corner, and the big 26px/700 symbol. The click hook is the
   data-term-dec/data-term-inc attributes, not this class. */
.term-stepper-btn {
  width: 48px;
  height: 48px;
  flex: 0 0 auto;
  padding: 0;
  border-radius: var(--r-sm);
  font-size: 26px;
  font-weight: 700;
  line-height: 1;
}
.term-stepper-btn:active:not(:disabled) { opacity: .7; }
.term-stepper-btn:disabled { opacity: .3; cursor: not-allowed; }
.term-stepper-mid {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 96px;
}
.term-stepper-num {
  font-size: 28px;
  font-weight: 700;
  line-height: 1.1;
  color: var(--text);
}
.term-stepper-label {
  font-size: 16px;
  color: var(--hint);
}
.term-stepper-submit { width: 100%; }

/* Inline escape buttons on a value дело (secondary look, distinct from submit) */
.delo-answer-choices--escape { margin-top: 8px; }
/* .delo-answer-btn--escape migrated to .btn-compact.btn-compact--outline-muted (see the compact
   button system above); the escape click hook is the data-escape attribute, not this class. */

/* Checkbox multi-select (answer_type="multi"): a row per option + a Подтвердить button.
   Rows are separated by the standard --gap token (694 — debt-list options looked stuck
   together) and padded to a ≥36px tap height (s15 tap-target rule). */
.delo-multi-list {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  margin-bottom: 10px;
}
.delo-multi-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  cursor: pointer;
}
.delo-multi-check {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  accent-color: var(--accent);
}
.delo-multi-label { font-size: 14px; }
/* Long multi-card action labels (долг-лист «Владелец ничего не заплатил») may wrap:
   the .btn-compact base is white-space:nowrap, and an unwrappable ~260px button
   overflows narrow cards → the whole card looks «поплывшей» (706). Scoped override. */
.delo-answer-section[data-atype="multi"] .btn-compact {
  white-space: normal;
  text-align: center;
}

/* Numeric multi-field form (answer_type="form"): stacked label-left / input-right rows +
   one submit. Inputs reuse .delo-answer-input (16px font — iOS no-zoom, §12). */
.delo-form-list {
  display: block;
  margin-bottom: 10px;
}
.delo-form-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 0;
}
.delo-form-label {
  flex: 1;
  font-size: 14px;
  min-width: 0;
}
/* Tap-to-copy utility account code: link tint + dotted underline (the .field-val--copyable
   affordance). Plain labels (no code) stay untinted with no handler. */
.delo-form-label--copy {
  color: var(--link);
  text-decoration: underline dotted;
  text-underline-offset: 3px;
  cursor: pointer;
}
.delo-form-input {
  flex: 0 0 110px;
  text-align: right;
}
.delo-form-submit { width: 100%; }

/* КУ per-apartment checklist card (chain=ku, step=ku_apt): month line + one row per
   item with a "✓ оплачено" tick; paid rows dim + strike. Copy-template icon top-right. */
.ku-copy-btn {
  margin-left: auto;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 32px;
  height: 28px;
  padding: 0 6px;
  background: transparent;
  border: none;
  border-radius: var(--btn-compact-radius, 8px);
  color: var(--hint);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.ku-copy-btn:active { opacity: .7; }
/* Tasks chain-filter — search-suggestions dropdown (709, reskin of 708 chips).
   The wrap takes the input's flex role in the search row (flex:1 + min-width:0 —
   s15 grid intact); the list is an absolutely-positioned .cd-apt-list matching the
   input's width; the active filter shows as a quiet in-field prefix. */
.tasks-search-wrap {
  position: relative;
  flex: 1;
  min-width: 0;
}
/* 710 regression fix: inside the wrap the input is NO LONGER a flex item (the wrap
   took that role), and `width: auto` on a REPLACED element collapses to its ~200px
   intrinsic size instead of filling the parent — the field rendered squeezed, and
   with an active prefix the inline padding-left made the intrinsic box overflow the
   wrap and cover the clock button. Fill the wrap explicitly. The triple selector
   out-specifies `.apts-search-row .search-input { width: auto }` (later in file). */
.apts-search-row .tasks-search-wrap .search-input {
  width: 100%;
  min-width: 0;
}
.tasks-filter-list {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 20;
  margin-top: 0;                 /* override .cd-apt-list's flow margin */
}
.tasks-filter-list .cd-apt-item {
  font-family: inherit;          /* labels, not apartment codes */
  border-bottom: 1px solid var(--separator);
}
.tasks-filter-list .cd-apt-item:last-child { border-bottom: none; }
.tasks-filter-list .cd-apt-item.is-active { color: var(--accent); font-weight: 600; }
.tasks-filter-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
}
.tasks-filter-count { color: var(--hint); font-size: 13px; }
.tasks-filter-prefix {
  position: absolute;
  left: 16px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--hint);
  font-size: 16px;
  white-space: nowrap;
  cursor: pointer;
  z-index: 1;
}

/* Currency affix on amount inputs (698): quiet suffix next to the input, visible
   before and during typing. Sits inside the existing flex rows (.delo-answer-row /
   .delo-form-row) or the dedicated .amount-input-row wrapper (ledger form). */
.amount-affix {
  flex: 0 0 auto;
  color: var(--hint);
  font-size: 16px;
  font-weight: 600;
}
.amount-input-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.amount-input-row .ledger-form-input { margin-bottom: 0; }
.amount-input-row { margin-bottom: 8px; }

/* Tiny caption next to the copy icon when one screen carries TWO copy buttons
   (balance statements: УК / Ситиком) — quiet hint-colored text, icon stays primary. */
.ku-copy-cap {
  font-size: 11px;
  font-weight: 600;
  margin-left: 4px;
  color: var(--hint);
}
.ku-copy-flash {
  font-size: var(--fs-pill, 12px);
  font-weight: var(--fw-pill, 700);
  color: var(--success);
  white-space: nowrap;
}
.ku-item-list { margin: 4px 0 2px; }

/* Utility-account tap-to-copy rows (824) on checkin/exit utility cards: quiet info
   lines under the case text; the VALUE carries the copyable affordance (link tint +
   dotted underline — the .field-val--copyable family). Tap copies ONLY the value. */
.util-account-list { margin: 4px 0 2px; }
.util-account-row {
  font-size: 13px;
  color: var(--hint);
  padding: 2px 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.util-account-row:active { opacity: .65; }
.util-account-val {
  color: var(--link);
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}
.ku-item-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 0;
  min-height: 36px;                 /* comfortable mobile tap target */
}
.ku-item-label {
  flex: 1;
  font-size: 14px;
  min-width: 0;
}
.ku-item-amt {
  flex: 0 0 auto;
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.ku-item-tick { flex: 0 0 auto; min-height: 36px; padding: 6px 12px; font-size: 13px; }
.ku-item-done {
  flex: 0 0 auto;
  color: var(--success);
  font-weight: 700;
  padding: 0 12px;
}
.ku-item-row--paid .ku-item-label,
.ku-item-row--paid .ku-item-amt {
  color: var(--hint);
  text-decoration: line-through;
}

.delo-answer-input {
  flex: 1;
  background: var(--bg);
  border: 1px solid var(--hint);
  border-radius: var(--r-sm);
  padding: 7px 10px;
  font-size: 16px;
  color: var(--text);
  outline: none;
  min-width: 0;
}

.delo-answer-input:focus { border-color: var(--accent); }

/* Tappable date display (replaces native date/datetime-local input; opens the wheel) */
.delo-date-display {
  text-align: left;
  cursor: pointer;
  color: var(--hint);
}
.delo-date-display.has-value { color: var(--text); }

/* ── Wheel date-picker ──────────────────────────────────────────────────── */
.dw-overlay {
  position: fixed;
  inset: 0;
  z-index: 10001;               /* above every existing overlay */
  display: flex;
  align-items: center;          /* centered card, not a bottom sheet */
  justify-content: center;
  padding: 20px;
  background: rgba(0, 0, 0, 0.28);   /* soft dim, not opaque black */
}
.dw-card {
  width: 100%;
  max-width: 360px;
  /* Pleasant light-grey surface regardless of theme (reads cleanly in light & dark). */
  background: color-mix(in srgb, var(--card-bg) 88%, #ffffff 12%);
  border: 1px solid rgba(128, 128, 128, 0.18);
  border-radius: var(--r-md);
  padding: 8px 10px 12px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.28);
  animation: dwPop 0.18s ease;
}
@keyframes dwPop { from { opacity: 0; transform: scale(0.94); } to { opacity: 1; transform: scale(1); } }
.dw-title {
  padding: 8px 6px 10px;
  font-size: 15px;
  font-weight: 500;
  color: var(--text);
  text-align: center;
  line-height: 1.35;
}
.dw-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 6px 2px;
  margin-top: 6px;
  border-top: 1px solid rgba(128, 128, 128, 0.18);
}
.dw-cancel, .dw-done {
  background: none;
  border: none;
  font-size: 16px;
  padding: 6px 8px;
  cursor: pointer;
  color: var(--link);
}
.dw-done { font-weight: 600; color: var(--accent); }
.dw-cols {
  position: relative;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 4px;
  height: 222px;                /* 22px label + 200px (5 rows × 40px) */
  padding: 0 6px;
  overflow: hidden;
}
/* One column = muted header label + the scroll wheel below it. */
.dw-cell {
  display: flex;
  flex-direction: column;
  flex: 1;
  max-width: 90px;
}
.dw-col-label {
  height: 22px;
  line-height: 22px;
  text-align: center;
  font-size: 11px;
  font-weight: 500;
  color: var(--hint);
  user-select: none;
}
/* ":" between Час and Мин, vertically centered on the wheel band (below the 22px labels). */
.dw-sep {
  display: flex;
  align-items: center;
  padding-top: 22px;
  font-size: 18px;
  color: var(--hint);
  user-select: none;
}
/* Comfortable gap between the time group and the date group. */
.dw-group-gap { flex: 0 0 auto; width: 10px; }
.dw-band {
  position: absolute;
  left: 4px;
  right: 4px;
  top: 102px;                   /* 22px labels + 2 rows down → centered band */
  height: 40px;
  background: rgba(128, 128, 128, 0.16);
  border-top: 1px solid rgba(128, 128, 128, 0.28);
  border-bottom: 1px solid rgba(128, 128, 128, 0.28);
  border-radius: var(--r-sm);
  pointer-events: none;
}
.dw-col {
  width: 100%;
  height: 200px;
  overflow-y: scroll;
  scroll-snap-type: y mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  touch-action: pan-y;
}
.dw-col::-webkit-scrollbar { display: none; }
.dw-col--drag { scroll-snap-type: none; }   /* avoid snap fighting a mouse drag */
.dw-item {
  height: 40px;
  line-height: 40px;
  text-align: center;
  scroll-snap-align: center;
  font-size: 18px;
  color: var(--hint);
  user-select: none;
  transition: color 0.12s ease, font-weight 0.12s ease;
}
.dw-item--sel { color: var(--text); font-weight: 600; }

.delo-vacancy-input {
  flex: none;
  width: 84px;
}

.delo-answer-error {
  margin-top: 8px;
  font-size: 12px;
  color: var(--danger);
}

.delo-telegram-note {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--hint);
  font-size: 12px;
  color: var(--hint);
  font-style: italic;
}

/* ── Empty / error states inside panel ─────────────────────────────────── */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 52px 0 24px;
  text-align: center;
}

.empty-icon  { font-size: 44px; }
.empty-title { font-size: 16px; font-weight: 500; color: var(--hint); }

.panel-error {
  background: var(--card-bg);
  border-radius: var(--r-md);
  padding: 16px 18px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--text);
}

/* ── Loading state inside tasks panel ──────────────────────────────────── */
.panel-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 60px 0;
}

/* ── Detail view ────────────────────────────────────────────────────────── */
.detail-apt-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}

.detail-meta {
  font-size: 13px;
  color: var(--hint);
  margin-bottom: 22px;
}

.detail-section {
  background: var(--card-bg);
  border-radius: var(--r-md);
  padding: 16px 18px;
  margin-bottom: 14px;
}

.detail-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .5px;
  text-transform: uppercase;
  color: var(--hint);
  margin-bottom: 8px;
}

.detail-body {
  font-size: 16px;
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-word;
}

/* ── Primary button ─────────────────────────────────────────────────────── */
.btn-primary {
  display: block;
  width: 100%;
  padding: 15px 20px;
  background: var(--accent);
  color: var(--accent-text);
  border: none;
  border-radius: var(--r-md);
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  text-align: center;
  transition: opacity .15s;
  -webkit-tap-highlight-color: transparent;
  margin-top: 8px;
}

.btn-primary:active   { opacity: .8; }
.btn-primary:disabled { opacity: .5; cursor: default; }

/* Destructive full-width button (archive confirm) — same shape as btn-primary, red. */
.btn-danger {
  display: block;
  width: 100%;
  padding: 15px 20px;
  background: var(--danger);
  color: var(--accent-text);
  border: none;
  border-radius: var(--r-md);
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  text-align: center;
  transition: opacity .15s;
  -webkit-tap-highlight-color: transparent;
  margin-top: 8px;
}
.btn-danger:active   { opacity: .8; }
.btn-danger:disabled { opacity: .5; cursor: default; }

/* Secondary/destructive action on the apartment card — muted, red text, not competing with
   the primary Заселить/Выселить action. */
/* Full-width soft-danger action on the compact base (radius r-sm / 14px/600 / cursor /
   :active from .btn-compact) — layout + the softened danger outline kept here. */
.apt-archive-btn {
  display: block;
  width: 100%;
  margin-top: 20px;
  padding: 12px 20px;
  background: transparent;
  color: var(--danger);
  border: 1px solid color-mix(in srgb, var(--danger) 40%, transparent);
  white-space: normal;
}

/* Квартиры header row: title left (flex:1), admin icon controls top-right (§12 convention). */
.apts-header-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 20px;
}
.apts-header-row .panel-title {
  margin-bottom: 0;
  flex: 1;
  min-width: 0;
}
.apts-header-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}
/* Header icon buttons (archive 🗄 / add +): colour-only retained class (card-bg on
   panel bg — no .btn-compact modifier matches); geometry from .btn-compact--icon. */
.apts-icon-btn {
  background: var(--card-bg);
  color: var(--text);
}

/* ── Role label (Жилец / Владелец) ─────────────────────────────────────── */
/* .role-label (Общение role word) migrated to .pill.pill--muted — same 12px size in card AND
   detail (the old 14px inline override in the detail was removed). */

/* ── Thread messages (in detail view) ───────────────────────────────────── */
.thread-list {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.thread-msg {
  padding: 10px 0;
  border-bottom: 1px solid var(--bg);
}

.thread-msg:last-child { border-bottom: none; }

.thread-dir {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .3px;
  color: var(--hint);
  margin-bottom: 4px;
  text-transform: uppercase;
}

.thread-msg-text {
  font-size: 15px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
}

.thread-ts {
  font-size: 11px;
  color: var(--hint);
  margin-top: 3px;
}

/* ── Comms: who-label shared (list + detail) ────────────────────────────── */
.comm-who {
  font-size: 12px;
  font-weight: 700;
  flex-shrink: 0;
  letter-spacing: .1px;
}
.comm-who--us   { color: var(--accent); }
.comm-who--them { color: var(--hint); }

/* ── Comms list card: preview lines ─────────────────────────────────────── */
.comm-preview {
  margin-bottom: 4px;
}

.comm-preview-line {
  display: flex;
  align-items: baseline;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  line-height: 1.6;
}

.comm-preview-sep {
  flex-shrink: 0;
  font-size: 12px;
  color: var(--hint);
}

.comm-preview-text {
  flex: 1;
  min-width: 0;
  font-size: 12px;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.comm-preview-empty {
  font-size: 12px;
  color: var(--hint);
  font-style: italic;
  line-height: 1.6;
}

.comm-count-pill {
  font-size: 12px;
  color: var(--hint);
}

/* ── Comms detail: full thread messages ──────────────────────────────────── */
.comm-msg-row {
  padding: 10px 0;
  border-bottom: 1px solid var(--separator);
  font-size: 14px;
  line-height: 1.55;
  word-break: break-word;
}

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

.comm-msg-body {
  white-space: pre-wrap;
}

/* Cached RU translation under a non-Russian incoming message (preview + detail thread).
   Muted/italic secondary line — color from the existing hint token, no new colors. */
.comm-translation {
  font-size: 12px;
  color: var(--hint);
  font-style: italic;
  white-space: pre-wrap;
  word-break: break-word;
}

/* Preview variant: single ellipsized line, same geometry family as .comm-preview-line */
.comm-translation--preview {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.6;
}

/* ── Apartments tab: search + grid ──────────────────────────────────────── */
.search-input {
  display: block;
  width: 100%;
  padding: 12px 16px;
  border: none;
  border-radius: var(--r-sm);
  background: var(--card-bg);
  color: var(--text);
  font-size: 16px;
  font-family: inherit;
  outline: none;
  margin-bottom: 14px;
  -webkit-appearance: none;
}
.search-input::placeholder { color: var(--hint); }

/* ── Apartments tab: search row + free-button ───────────────────────────── */
.apts-search-row {
  display: flex;
  gap: 10px;
  margin-bottom: 14px;
}

.apts-search-row .search-input {
  flex: 1;
  width: auto;
  min-width: 0;   /* kill the input's ~200px intrinsic minimum — the row must never overflow */
  margin-bottom: 0;
}

/* Квартиры variant: the row is a GRID sharing .apt-grid's column geometry (3×1fr, same gap),
   so the input's right edge lands exactly on column 2's right edge and the «Свободные» button
   fills column 3 — aligned with the cubes below at ANY width, by construction. The base flex
   rules above stay live for the Задачи instance (search + two 44px icon squares); flex:1 /
   flex:0 0 auto are simply ignored by grid layout here. */
.apts-search-row--grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--gap);
}
.apts-search-row--grid .search-input { grid-column: 1 / 3; }
.apts-search-row--grid .vacant-filter-btn {
  grid-column: 3;
  min-width: 0;   /* the grid may shrink the button below its intrinsic width → ellipsis */
}

/* Navigation/filter buttons (Свободные·N on Квартиры; 🕐/+ icon buttons on Задачи — the latter
   force a 44px square via inline styles). Base geometry (radius/cursor/font/centering) from
   .btn-compact; this class is RETAINED for its card-bg+accent colour (no .btn-compact modifier
   matches) and the text-button padding + ellipsis. The icon buttons' inline 44px overrides win. */
.vacant-filter-btn {
  flex: 0 0 auto;   /* button holds intrinsic width; the search input is the flexing element */
  padding: 12px 8px;
  background: var(--card-bg);
  color: var(--accent);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.apt-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--gap);
  padding-bottom: 12px;
}

.apt-cube {
  background: var(--card-bg);
  border-radius: var(--r-md);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 16px 6px;
  min-height: 76px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: opacity .12s;
  user-select: none;
}
.apt-cube:active { opacity: .65; }

.apt-cube--vacant {
  border: 1.5px solid var(--accent);
}

.apt-code-label {
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: .3px;
}

.apt-cube--vacant .apt-code-label {
  color: var(--text);
}

.apt-vacant-label {
  font-size: 10px;
  font-weight: 600;
  color: var(--accent);
  letter-spacing: .2px;
  text-transform: uppercase;
}

/* ── Apartments detail: status badge ────────────────────────────────────── */
/* The status "matched set" (occupied / vacant / в процессе / action button) migrated to
   .pill + .pill--status + a color modifier (--muted / --accent / --success / --warning).
   See the canonical pill system above. */

/* ── Apartments detail: field rows ──────────────────────────────────────── */
.field-row {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 9px 0;
  border-bottom: 1px solid var(--separator);
}
.field-row:last-child { border-bottom: none; }

.field-key {
  font-size: 13px;
  color: var(--hint);
  flex-shrink: 0;
  white-space: nowrap;
  line-height: 1.4;
}

.field-val {
  flex: 1;
  font-size: 14px;
  color: var(--text);
  text-align: right;
  word-break: break-word;
  line-height: 1.4;
}

.field-val--empty {
  color: var(--hint);
  font-style: italic;
  font-size: 13px;
}

.field-val--copyable {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  text-decoration-line: underline;
  text-decoration-style: dotted;
  text-decoration-color: var(--hint);
}
.field-val--copyable:active { opacity: .65; }

.field-val--link {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  color: var(--link);
}
.field-val--link:active { opacity: .65; }

.field-row--copy {
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

/* .copy-inline-btn removed — dead code (zero markup references anywhere; the live tap-to-copy is
   .field-val--copyable + data-copy, a span, not this button). Nothing to migrate to .btn-compact. */

/* ── Apartment edit mode ─────────────────────────────────────────────────── */
/* Quiet icon button (pencil / ✕) on the compact base — transparent + hint colour,
   icon-tight padding (radius r-sm, cursor, :active come from .btn-compact). */
.apt-edit-btn {
  margin-left: auto;
  flex-shrink: 0;
  background: none;
  color: var(--hint);
  padding: 6px;
  line-height: 0;
}

/* Apartment chain-start action buttons (Заселить/Выселить) + в-процессе badge migrated to
   .pill.pill--status.pill--success / .pill--warning / .pill--muted; button interaction is in
   button.pill--status (see the pill system above). */
.apt-action-err {
  font-size: 13px;
  color: var(--danger);
  padding: 4px 0 2px;
  margin-bottom: 6px;
}

.edit-field-input,
.edit-field-select {
  flex: 1;
  min-width: 0;
  background: var(--bg);
  border: 1px solid rgba(128,128,128,.3);
  border-radius: var(--r-sm);
  padding: 5px 8px;
  font-size: 16px;
  font-family: inherit;
  color: var(--text);
  text-align: right;
}
.edit-field-input:focus,
.edit-field-select:focus {
  outline: none;
  border-color: var(--accent);
}
/* Hide number spinner arrows */
.edit-field-input[type=number]::-webkit-outer-spin-button,
.edit-field-input[type=number]::-webkit-inner-spin-button { -webkit-appearance: none; }
.edit-field-input[type=number] { -moz-appearance: textfield; }

/* Apartment date field: tappable display (looks like .edit-field-input) + clear "×" */
.date-field-wrap { align-items: center; }
.date-field-display {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.date-field-display:not(.has-value) { color: var(--hint); }
.date-field-clear {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  line-height: 24px;
  text-align: center;
  padding: 0;
  border: none;
  background: none;
  color: var(--hint);
  font-size: 20px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.date-field-clear:active { opacity: .6; }

.edit-actions {
  display: flex;
  gap: 10px;
  margin-top: 24px;
  margin-bottom: 8px;
}
/* Save/cancel row balance (was .btn-save flex:2 / .btn-cancel flex:1) folded into
   btn-primary/btn-secondary, scoped to the .edit-actions wrapper — save stays wider than cancel.
   margin-top:0 cancels the full-width buttons' default 8px top gap inside the flex row. */
.edit-actions .btn-primary,
.edit-actions .btn-secondary { margin-top: 0; }
.edit-actions .btn-primary   { flex: 2; }
.edit-actions .btn-secondary { flex: 1; }

.edit-error {
  min-height: 18px;
  font-size: 13px;
  color: var(--danger);
  text-align: center;
  margin-top: 12px;
  word-break: break-word;
}

/* ── Dashboard tab: command buttons ─────────────────────────────────────── */
.dash-btn-list {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}

.dash-btn {
  background: var(--card-bg);
  border-radius: var(--r-md);
  padding: 20px 18px;
  display: flex;
  align-items: center;
  gap: 14px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: opacity .12s;
  user-select: none;
}
.dash-btn:active   { opacity: .65; }
.dash-btn--busy    { opacity: .5; pointer-events: none; }

/* Two symmetric side-by-side action buttons (e.g. Бэкап): equal width, same height/style. */
.dash-action-row {
  display: flex;
  gap: var(--gap);
}
.dash-btn--action {
  flex: 1;
  justify-content: center;
  text-align: center;
  white-space: nowrap;  /* keep labels on one line so both stay the standard .dash-btn height */
}

.dash-btn-body   { flex: 1; }

.dash-btn-label {
  font-size: 17px;
  font-weight: 600;
  color: var(--text);
}

.dash-btn-desc {
  font-size: 13px;
  color: var(--hint);
}

.dash-arrow {
  width: 18px;
  height: 18px;
  stroke: var(--hint);
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex-shrink: 0;
}

/* ── Free apartments screen: stretched cubes ────────────────────────────── */
.free-cube {
  background: var(--card-bg);
  border-radius: var(--r-md);
  padding: 14px 16px;
  display: flex;
  align-items: center;
  gap: 14px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: opacity .12s;
  user-select: none;
}
.free-cube:active { opacity: .65; }

.free-cube-left {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex-shrink: 0;
}

.free-cube-code {
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: .3px;
  line-height: 1;
}

.free-cube-soon {
  font-size: 11px;
  font-weight: 500;
  color: var(--accent);
  white-space: nowrap;
}

.free-cube-right {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 5px;
  min-width: 0;
}

.free-cube-price {
  font-size: 20px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -.3px;
  line-height: 1;
}

.free-cube-price--dash {
  color: var(--hint);
  font-weight: 400;
  font-size: 18px;
}

.free-cube-specs {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 2px 8px;
}

.free-cube-spec {
  font-size: 12px;
  color: var(--hint);
}

.free-cube-spec--empty {
  font-style: italic;
  font-size: 11px;
  color: var(--hint);
}

.free-section-divider {
  border: none;
  border-top: 1px solid var(--separator);
  margin: 16px 0;
}

.free-section-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .5px;
  text-transform: uppercase;
  color: var(--hint);
  margin-bottom: 10px;
}

/* ── Dashboard finance: balance color coding ────────────────────────────── */
.balance--owes    { color: var(--danger); font-weight: 600; }
.balance--advance { color: var(--success); font-weight: 600; }

/* ── Finance apt rows: tap to drill into ledger history ─────────────────── */
.finance-apt-row { cursor: pointer; }
.finance-apt-row:active { opacity: .7; }

/* ── Finance summary badge: portfolio-wide debt totals ──────────────────── */
.finance-summary-badge {
  display: flex;
  justify-content: space-around;
  background: var(--card-bg);
  border-radius: var(--pill-radius);
  padding: 12px 8px;
  margin-bottom: 16px;
}
.finance-summary-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.finance-summary-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--hint);
}
.finance-summary-item .balance--owes,
.finance-summary-zero { font-size: 15px; font-weight: 600; color: var(--hint); }

/* ── Ledger history detail: header + balance badge ──────────────────────── */
.ledger-history-header {
  display: flex;
  align-items: center;
  gap: 12px 16px;
  flex-wrap: wrap;              /* pills drop under the apt number on narrow screens */
  margin-bottom: 20px;
}
.ledger-history-header .panel-title { margin-bottom: 0; flex: 1 1 auto; }

/* Balance figure ("Должен 55$"/"Аванс 10$"/"0$"): shape+color from .pill + a color modifier
   (--danger-tint/--success/--muted). This class is RETAINED (a live-update querySelector keys off
   it) and now carries ONLY the money-figure size (14px/600 — larger than the .pill base 12px/700
   for readability) + the header optical margin. */
.ledger-balance-badge {
  margin-top: 4px;          /* optical alignment with title baseline; size from .pill--big */
}

.ledger-section-label {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--hint);
  margin: 20px 0 10px;
  padding-top: 16px;
  border-top: 1px solid color-mix(in srgb, var(--text) 8%, transparent);
}

/* Small muted "Авто" badge on system-generated ledger rows (accrual / citycom charge).
   Subordinate INLINE metadata — color+shape from .pill.pill--muted; this class is RETAINED for its
   small inline size/placement (11px/600, an inline gap + baseline nudge) so it stays subordinate
   rather than growing to the .pill base 12px/700. */
.ledger-auto-badge {
  margin-left: 6px;
  padding: 1px 7px;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.5;
  vertical-align: middle;
}

/* Two balance pills (Управление + Ситиком) live in the header, right of the apt number, and are
   now TAP-TO-OPEN buttons (each opens the write form for its ledger). margin-left:auto pushes them
   right when on the title's line; they wrap under the number on narrow screens. */
.ledger-balances-row { display: flex; gap: 10px; margin: 0 0 0 auto; flex-wrap: wrap; }
.ledger-balance-item {
  display: flex;
  align-items: center;
  gap: 8px;
  border: none;
  background: transparent;
  padding: 0;
  margin: 0;
  font: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: opacity .15s;
}
.ledger-balance-item:active { opacity: .7; }
/* Label prefix INSIDE each pill ("Управление · …") — muted relative to the amount. */
.ledger-badge-label { font-weight: 600; opacity: 0.75; }

/* Muted "Управление зачислено до …" line (display only, below the operations list — informational). */
.ledger-paid-until {
  font-size: 13px;
  color: var(--hint);
  line-height: 1.4;
  margin-bottom: 12px;
}

/* ── Ledger detail: pay / charge action buttons ──────────────────────────── */
/* pay/charge toggle at the top of the write form: two buttons, the active one full-opacity with a
   ring (inset currentColor), the other dimmed. Color comes from .btn-compact--success-tint /
   --danger-tint on each button (currentColor = that tint's text color). */
.ledger-toggle-row {
  display: flex;
  gap: 10px;
  margin-bottom: 12px;
}
.ledger-toggle-btn { flex: 1; opacity: .45; }
.ledger-toggle-btn.is-active { opacity: 1; box-shadow: inset 0 0 0 2px currentColor; }
/* Pay/charge colors migrated to .btn-compact.btn-compact--success-tint / --danger-tint; the click
   hook is .ledger-toggle-btn + data-action. This class is RETAINED for the toggle-specific layout
   that differs from the .btn-compact base: a taller pad and wrapping (the long
   "Добавить задолженность" label must wrap in its half-width slot — .btn-compact is nowrap). */
.ledger-action-btn {
  padding: 10px 12px;
  white-space: normal;
}

/* ── Ledger detail: inline write form ───────────────────────────────────── */
.ledger-write-form--hidden { display: none; }
.ledger-write-form {
  background: var(--card-bg);
  border-radius: var(--r-md);
  padding: 16px;
  margin-bottom: 16px;
}
.ledger-write-form-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 12px;
}
.ledger-form-input {
  width: 100%;
  box-sizing: border-box;
  flex: unset;           /* override edit-field-input's flex:1 — needs full-width here */
  margin-bottom: 8px;
}
.ledger-write-preview {
  font-size: 14px;
  color: var(--hint);
  min-height: 20px;
  margin: 2px 0 4px;
}
.ledger-write-error {
  min-height: 18px;
  font-size: 13px;
  color: var(--danger);
  margin-top: 4px;
}

/* ── All-transactions feed: per-row label line ───────────────────────────── */
.txn-label-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 4px;
}
.txn-apt-owner {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  flex: 1;
  min-width: 0;
}

/* ── Admin tab: user list cards ─────────────────────────────────────────── */
.user-card {
  background: var(--card-bg);
  border-radius: var(--r-md);
  padding: 14px 16px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: opacity .12s;
  user-select: none;
}
.user-card:active { opacity: .65; }

.user-card-top {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
}

.user-name {
  flex: 1;
  font-size: 16px;
  font-weight: 600;
  color: var(--text);
}

.user-card-meta {
  font-size: 12px;
  color: var(--hint);
  padding-left: 18px;
  line-height: 1.4;
}

/* .role-badge (admin Владелец/Сотрудник) migrated to .pill.pill--accent (owner) /
   .pill.pill--outline-muted (employee grey outline). */

.active-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.active-dot--on  { background: var(--success); }
.active-dot--off { background: var(--hint); }

/* Admin role selector: markup moved onto .segmented/.segmented-btn (design 666);
   .role-btn stays in markup as the JS click hook only — no visual rules. */

/* ── Admin detail: cap rows ──────────────────────────────────────────────── */
.cap-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--separator);
}
.cap-row:last-child { border-bottom: none; }

.cap-row-label {
  flex: 1;
  font-size: 15px;
  color: var(--text);
}

/* ── Toggle switch ───────────────────────────────────────────────────────── */
.toggle-switch {
  position: relative;
  width: 44px;
  height: 26px;
  flex-shrink: 0;
}

.toggle-switch input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.toggle-track {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background: color-mix(in srgb, var(--text) 18%, transparent);  /* fill (off-track), stronger than --separator */
  cursor: pointer;
  transition: background .2s;
}

.toggle-track::after {
  content: '';
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--accent-text);
  box-shadow: 0 1px 3px rgba(0,0,0,.3);
  transition: transform .2s;
}

.toggle-switch input:checked + .toggle-track          { background: var(--accent); }
.toggle-switch input:checked + .toggle-track::after   { transform: translateX(18px); }
.toggle-switch input:disabled + .toggle-track         { opacity: .35; cursor: not-allowed; }

/* ── Two-tap confirm pill on admin toggles ───────────────────────────────── */
.toggle-confirm-pill {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 36px;   /* tap target ≥36px */
  padding: 5px 10px;
  background: var(--accent);
  color: var(--accent-text);
  border: none;
  border-radius: var(--r-sm);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  -webkit-tap-highlight-color: transparent;
  transition: opacity .15s;
}
.toggle-confirm-pill:active { opacity: .8; }

/* ── Admin feedback bar ──────────────────────────────────────────────────── */
.admin-feedback {
  background: var(--accent);
  color: var(--accent-text);
  font-size: 13px;
  font-weight: 500;
  padding: 8px 14px;
  border-radius: var(--r-sm);
  margin-bottom: 16px;
  text-align: center;
}
.admin-feedback--error { background: var(--danger); color: var(--accent-text); }

/* ── Admin add-user form inputs ──────────────────────────────────────────── */
.admin-input {
  display: block;
  width: 100%;
  padding: 12px 0 6px;
  border: none;
  border-bottom: 1.5px solid var(--separator);
  background: transparent;
  color: var(--text);
  font-size: 16px;
  font-family: inherit;
  outline: none;
  -webkit-appearance: none;
  margin-top: 4px;
}
.admin-input::placeholder { color: var(--hint); }

/* ── Archive дел cards ───────────────────────────────────────────────────── */
.archive-list {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}

.archive-card {
  background: var(--card-bg);
  border-radius: var(--r-md);
  padding: 14px 16px;
}

.archive-card-header {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 6px;
  flex-wrap: wrap;
}

.archive-check {
  font-size: 14px;
  font-weight: 700;
  color: var(--success);   /* green ✓, works on both light and dark */
  flex-shrink: 0;
}

.archive-meta {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  flex: 1;
  min-width: 0;
}

.archive-apt {
  font-size: 13px;
  font-weight: 700;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  padding: 1px 7px;
  border-radius: var(--r-sm);
  margin-left: 4px;
  white-space: nowrap;
}

.archive-date {
  font-size: 12px;
  color: var(--hint);
  white-space: nowrap;
  margin-left: auto;
  flex-shrink: 0;
}

.archive-body {
  font-size: 13px;
  color: var(--hint);
  line-height: 1.45;
  margin-top: 4px;
  word-break: break-word;
}

.archive-answer {
  font-size: 13px;
  color: var(--text);
  font-weight: 500;
  margin-top: 5px;
  word-break: break-word;
}

/* Справочник (reference registry, 779/780) */
/* Section spacing (780): the expanded list was sticking to its header pill — both
   the toggle and the list body get a --gap bottom margin, so collapsed headers
   stack evenly and an expanded body separates from its own header AND the next one. */
.reg-sec-toggle { width: 100%; margin: 0 0 var(--gap); }
.reg-sec-list   { margin-bottom: var(--gap); }
.reg-sec-label  {
  font-size: 13px;
  font-weight: 700;
  color: var(--hint);
  margin: 4px 0 8px;
}
/* Text vs pills (780): the text flex child must shrink/wrap inside its own column
   (min-width:0 + overflow-wrap), and a pill can never overlap neighbours at any
   width — an over-long pill (long step id, the «Скопировано: …» flash) truncates
   with an ellipsis instead of overflowing the card. */
.reg-row .archive-card-header { align-items: center; }
.reg-row .archive-meta { min-width: 0; overflow-wrap: anywhere; }
.reg-row .pill {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  display: inline-block;      /* inline-flex clips descenders when overflow:hidden */
}
.reg-text {
  margin-top: 6px;
  font-size: 13px;
  color: var(--hint);
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow-wrap: anywhere;
}

/* Missing-data tab */
.missing-apt-card { cursor: pointer; }
.missing-group { margin-top: 8px; }
.missing-group-label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--hint);
  display: block;
  margin-bottom: 5px;
}
.missing-tags { display: flex; flex-wrap: wrap; gap: 5px; }
/* .missing-tag (important) / .missing-tag--internet migrated to .pill.pill--danger-tint.pill--light
   / .pill.pill--info.pill--light (see the canonical pill system above). */

.archive-header-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 20px;
}
/* Finance tab only — larger gap between header row and first balance card */
.finance-header-row { margin-bottom: 20px; }
.archive-header-row .panel-title {
  margin-bottom: 0;
  flex: 1;
  min-width: 0;
}

/* Archive-дел filter row (Сводка + date pill + ✕ clear) — this class is now EXCLUSIVE to that row
   (the survey/txn borrowers were migrated to .btn-compact). radius = var(--pill-radius) brings the
   whole row into the standardized pill family (was a r20 full-round chip, the last r20 in the app).
   The date pill opens the shared wheel; the ✕ clears the filter; Сводка opens the stats overlay. */
.archive-filter-pill {
  display: flex;
  align-items: center;
  min-height: 36px;   /* tap target ≥36px (font/visual density unchanged) */
  gap: 5px;
  font-size: 13px;
  font-weight: 500;
  color: var(--hint);
  background: var(--card-bg);
  border: none;
  border-radius: var(--pill-radius);
  padding: 5px 12px;
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
  -webkit-tap-highlight-color: transparent;
  transition: color .15s;
}
.archive-filter-pill.active {
  color: var(--accent);
}
/* The ✕ clear is a subtle affordance for the date filter, NOT a third card-bg pill competing with
   Сводка / the date — transparent, tighter, a slightly larger glyph. Its click clears the filter
   (bound by id, unchanged). */
#archive-date-clear {
  background: transparent;
  color: var(--hint);
  padding: 4px 6px;
  font-size: 15px;
  line-height: 1;
}

/* Date+closed_by column in card header (right side) */
.archive-date-col {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  flex-shrink: 0;
  margin-left: auto;
  gap: 2px;
}

.archive-closed-by {
  font-size: 11px;
  color: var(--hint);
  opacity: 0.65;
  white-space: nowrap;
}

/* ── Rent-history apartment selector ──────────────────────────────────────── */
.rh-apt-select {
  display: block;
  width: 100%;
  padding: 10px 14px;
  margin-bottom: 16px;
  background: var(--card-bg);
  color: var(--text);
  border: none;
  border-radius: var(--r-sm);
  font-size: 15px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* ── Secondary button ───────────────────────────────────────────────────── */
.btn-secondary {
  display: block;
  width: 100%;
  padding: 15px 20px;
  background: var(--card-bg);
  color: var(--text);
  border: none;
  border-radius: var(--r-md);
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  text-align: center;
  transition: opacity .15s;
  -webkit-tap-highlight-color: transparent;
  margin-top: 8px;
}
.btn-secondary:active   { opacity: .8; }
.btn-secondary:disabled { opacity: .5; cursor: default; }

/* ── Nav badge on tab icon ──────────────────────────────────────────────── */
.tab-icon-wrap {
  position: relative;
  display: inline-flex;
}

/* Notification count badge — ONE 16px capsule for both attachment contexts
   (tab bar: absolute at the icon corner; dashboard tile: inline after the label). */
.notif-badge {
  min-width: 16px;
  height: 16px;
  line-height: 16px;
  background: var(--danger);
  color: var(--accent-text);
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  padding: 0 4px;
  text-align: center;
}
.notif-badge--tab {
  position: absolute;
  top: -5px;
  right: -9px;
  pointer-events: none;
}
.notif-badge--inline {
  display: inline-block;
  margin-left: 7px;
  vertical-align: middle;
}

/* ── Comms detail: action buttons row ───────────────────────────────────── */
.comms-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 16px;
}

/* ── Assign form ────────────────────────────────────────────────────────── */
.assign-form {
  background: var(--card-bg);
  border-radius: var(--r-md);
  padding: 16px 18px;
  margin-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.assign-form-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .5px;
  text-transform: uppercase;
  color: var(--hint);
  margin-bottom: 6px;
}

/* ── Segmented control — THE one base for all 2-3-option toggles (restore-choice,
   party pickers, classify RU/EN, admin role selector). Container: inset bg + r-sm;
   buttons: flat ghosts, concentric inner radius, active = accent fill. ── */
.segmented {
  display: flex;
  gap: 2px;
  background: var(--bg);
  border-radius: var(--r-sm);
  padding: 2px;
  overflow: hidden;
}

.segmented--disabled {
  opacity: .45;
}

/* Segmented toggle button: base geometry (font/border/radius/cursor) from .btn-compact; this class
   is RETAINED as the click/active hook AND for the bespoke flat-toggle look — equal-width flex,
   tighter pad, and the borderless transparent+hint "ghost" INACTIVE state (NOT an outline: it sits
   inside the .segmented bg container). The background/color transition animates the active fill. */
.segmented-btn {
  flex: 1;
  min-height: 36px;
  padding: 8px 12px;
  background: none;
  /* Concentric with the container: r-sm minus the 2px container padding. Radius 0 let the
     container's rounded overflow-clip shear the active fill's square corners (the "blue
     block looks misaligned" bug on the Задача|Ремонт toggle). */
  border-radius: calc(var(--r-sm) - 2px);
  color: var(--hint);
  transition: background .15s, color .15s;
}
.segmented-btn:disabled {
  cursor: not-allowed;
}
/* Active segment — solid accent fill (works alongside .btn-compact; segmented-btn class is kept). */
.segmented-btn.active {
  background: var(--accent);
  color: var(--accent-text);
}

/* ── Assign form inputs ─────────────────────────────────────────────────── */
.assign-textarea,
.assign-deadline {
  display: block;
  width: 100%;
  background: var(--bg);
  border: none;
  border-radius: var(--r-sm);
  color: var(--text);
  font-size: 16px;
  font-family: inherit;
  outline: none;
}

.assign-textarea {
  min-height: 90px;
  padding: 10px 12px;
  resize: vertical;
  line-height: 1.5;
}

.assign-deadline {
  padding: 9px 12px;
  -webkit-appearance: none;
}

/* Reminder datetime: full-width tappable display that opens the wheel (Class 2) */
.remind-field-row {
  display: flex;
}
.remind-field-row .assign-deadline {
  width: auto;
  flex: 1;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.remind-field-row .date-field-display:not(.has-value) { color: var(--hint); }

.assign-textarea::placeholder { color: var(--hint); }

/* ── Manual дело: apartment picker dropdown ─────────────────────────────── */
.cd-apt-list {
  background: var(--card-bg);
  border: 1px solid color-mix(in srgb, var(--text) 8%, transparent);
  border-radius: var(--r-sm);
  max-height: 190px;
  overflow-y: auto;
  touch-action: pan-y;   /* vertical pan stays native; taps handled by the slop logic (705) */
  margin-top: 4px;
}

.cd-apt-item {
  padding: 10px 12px;
  font-size: 15px;
  font-family: monospace;
  cursor: pointer;
  border-bottom: 1px solid color-mix(in srgb, var(--text) 4%, transparent);
}

.cd-apt-item:last-child { border-bottom: none; }

/* "не выбрано" (no-apartment) option — muted, non-monospace to read as a label not a code */
.cd-apt-item--none {
  color: var(--hint);
  font-family: inherit;
  font-style: italic;
}

.cd-apt-item:active,
.cd-apt-item:hover { background: color-mix(in srgb, var(--text) 6%, transparent); }

/* ── Inline error ───────────────────────────────────────────────────────── */
.inline-error {
  font-size: 13px;
  color: var(--danger);
  line-height: 1.4;
}

/* ── Classify дело: role/apartment/language pickers ────────────────────── */
.classify-contact {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 10px;
}

.classify-contact--unknown {
  color: var(--hint);
  font-weight: 400;
}

.classify-contact-link {
  color: var(--link);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.classify-contact-name {
  color: var(--text);
}

.classify-roles {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* .classify-role-btn is now a pure JS hook — visuals come from .pill.pill--choice. */

.classify-apt-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
}

/* RU/EN language switch: markup moved onto .segmented base (design 666); this class
   stays layout-only (the switch must not stretch in its flex row). */
.classify-lang-seg {
  flex-shrink: 0;
}

/* .classify-lang-btn is now a pure JS hook — visuals come from .segmented-btn. */

.classify-submit-btn {
  display: block;
  width: 100%;
  margin-top: 10px;
}

/* ── Security alert cards ───────────────────────────────────────────────── */
.security-list {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}

.security-card {
  background: var(--card-bg);
  border-radius: var(--r-md);
  padding: 14px 16px;
}

.security-card-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

/* Security alert type badges migrated to .pill.pill--warning (edit "правка") /
   .pill.pill--tint (iban — routed to the theme accent instead of a hardcoded iOS blue). */

.security-ts {
  font-size: 12px;
  color: var(--hint);
}

.security-text {
  font-size: 14px;
  color: var(--text);
  line-height: 1.5;
  margin-bottom: 12px;
  word-break: break-word;
}


/* ── Цепочки viewer ─────────────────────────────────────────────────────── */

.chain-group-bar {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}

.chain-group-btn {
  padding: 7px 13px;
  border: none;
  border-radius: 20px;
  background: var(--card-bg);
  color: var(--hint);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s, color .15s;
  -webkit-tap-highlight-color: transparent;
  white-space: nowrap;
}

.chain-group-btn.active {
  background: var(--accent);
  color: var(--accent-text);
}

.chain-tab-bar {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}

.chain-tab-btn {
  padding: 6px 12px;
  border: none;
  border-radius: 8px;
  background: var(--card-bg);
  color: var(--hint);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s, color .15s;
  -webkit-tap-highlight-color: transparent;
}

.chain-tab-btn.active {
  background: var(--accent);
  color: var(--accent-text);
}

.chains-content { padding-bottom: 40px; }

/* Flat chain-button list */
.chain-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-bottom: 32px;
}
.chain-list-btn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  border: none;
  border-radius: 12px;
  background: var(--card-bg);
  cursor: pointer;
  text-align: left;
  width: 100%;
  min-height: 52px;
  -webkit-tap-highlight-color: transparent;
  transition: opacity .12s;
}
.chain-list-btn:active { opacity: .65; }
.chain-list-label {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
}
.chain-list-count {
  font-size: 12px;
  color: var(--hint);
  white-space: nowrap;
  margin-left: 8px;
  flex-shrink: 0;
}

/* Recurring reminders ("Напоминания") — read-only card list, no SVG/interactivity. */
.recurring-title {
  font-size: 17px;
  font-weight: 700;
  color: var(--text);
  margin: 8px 0 12px;
}
.recurring-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-bottom: 32px;
}
.recurring-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 14px 16px;
  border-radius: var(--r-md);
  background: var(--card-bg);
  min-height: 52px;
}
.recurring-text {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  flex: 1;  /* absorb slack so the cadence badge + countdown cluster on the right */
}
/* Live "через N дней" — small muted secondary label next to the cadence badge. Reuses the
   chain-badge muted color/size tokens; no new accent. Empty (unknown cadence) → no pill. */
.recurring-countdown {
  flex-shrink: 0;
  color: var(--hint);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .3px;
  line-height: 20px;
  white-space: nowrap;
}
.recurring-countdown:empty { display: none; }

/* Tap-to-detail panel visible on top of fullscreen canvas */
/* (761: the bottom-sheet override is gone — .csvg-det is a centered modal now.) */

.chain-section { margin-bottom: 8px; }

.chain-section-label {
  font-size: 15px;
  font-weight: 700;
  color: var(--hint);
  text-transform: uppercase;
  letter-spacing: .04em;
  margin-bottom: 10px;
  padding-left: 2px;
}

.chain-section-sep {
  height: 1px;
  background: var(--card-bg);
  margin: 20px 0;
}

.chain-tree { display: flex; flex-direction: column; gap: 0; }

/* Node card */
.chain-node {
  background: var(--card-bg);
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 4px;
  border-left: 3px solid transparent;
}

.chain-node--entry    { border-left-color: var(--hint); opacity: .8; }
.chain-node--legacy   { opacity: .45; }
.chain-node--phantom  { border-left-color: #888; opacity: .7; }
.chain-node--phantom .chain-node-id { color: #888; font-style: italic; }
.chain-node--scheduled { border-left-color: #a67c00; }

.chain-node-header {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

.chain-node-id {
  font-size: 13px;
  font-weight: 700;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  color: var(--text);
}

.chain-node-text {
  font-size: 13px;
  color: var(--hint);
  margin-top: 4px;
  line-height: 1.4;
}

/* Answer-type badge */
.chain-atype {
  font-size: 11px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 10px;
  white-space: nowrap;
}

.chain-atype--done     { background: #007aff22; color: #007aff; }
.chain-atype--choice   { background: #34c75922; color: #34c759; }
.chain-atype--value    { background: #ff950022; color: #ff9500; }
.chain-atype--date,
.chain-atype--datetime { background: #af52de22; color: #af52de; }

.chain-entry-badge,
.chain-legacy-badge,
.chain-handler-badge,
.chain-scheduled-badge {
  font-size: 10px;
  font-weight: 600;
  padding: 1px 6px;
  border-radius: 8px;
  background: var(--bg);
  color: var(--hint);
}
.chain-handler-badge  { color: #888; }
.chain-scheduled-badge { color: #a67c00; }

/* Cross-chain handoff node — tappable */
.chain-xref {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: 6px;
  padding: 5px 10px;
  border-radius: 8px;
  background: #ff950018;
  border: 1px solid #ff950060;
  color: #c07000;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: opacity .15s;
}

.chain-xref:active { opacity: .65; }

/* Connector lines */
.chain-edge {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 2px 0 2px 10px;
  font-size: 12px;
  color: var(--hint);
  margin-bottom: 2px;
  position: relative;
}

.chain-edge::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--card-bg);
}

.chain-edge--done::before    { background: #007aff44; }
.chain-edge--choice::before  { background: #34c75944; }
.chain-edge--creates::before { background: #ff950044; }
.chain-edge--creates .chain-edge-arrow { color: #d56a00; }
.chain-edge--creates .chain-edge-target { color: #d56a00; font-style: italic; }

.chain-scheduled-sep {
  text-align: center;
  font-size: 11px;
  color: var(--hint);
  margin: 14px 0 6px;
  opacity: .6;
  letter-spacing: .05em;
}

.chain-edge-kw {
  font-weight: 700;
  color: #34c759;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
}

.chain-edge-arrow { color: var(--hint); }

.chain-edge-target {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  color: var(--text);
  font-size: 11px;
}

.chain-back-ref {
  font-size: 11px;
  color: var(--hint);
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  padding: 2px 0;
  opacity: .6;
}

/* ── Chain Spine Viewer (cs-*) ─────────────────────────────────────────────── */

.cs-section { padding-bottom: 24px; }

.cs-section-title {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--hint);
  opacity: .6;
  margin-bottom: 12px;
}

/* Flow container — the spine line runs through it */
.cs-flow {
  position: relative;
  padding-left: 22px;
}
.cs-flow::before {
  content: '';
  position: absolute;
  left: 8px;
  top: 14px;
  bottom: 14px;
  width: 1.5px;
  background: var(--card-bg);
  border-radius: 1px;
}

/* Node block */
.cs-nb {
  position: relative;
  margin-bottom: 0;
}
.cs-nb::before {
  content: '';
  position: absolute;
  left: -14px;
  top: 14px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--hint);
  opacity: .3;
  z-index: 1;
}
/* Dots colored by answer type */
.cs-nb[data-atype="choice"]::before  { background: #34c759; opacity: .5; }
.cs-nb[data-atype="value"]::before   { background: #ff9500; opacity: .5; }
.cs-nb[data-atype="date"]::before,
.cs-nb[data-atype="dt"]::before      { background: #af52de; opacity: .5; }
.cs-nb[data-atype="handler"]::before { background: #888; opacity: .25; }
.cs-nb[data-atype="sched"]::before   { background: #a67c00; opacity: .5; }
/* No dot inside branch bodies */
.cs-branch .cs-nb::before { display: none; }

/* Card row */
.cs-card {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 10px;
  border-radius: 8px;
  background: var(--card-bg);
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  transition: opacity .1s;
  min-width: 0;
}
.cs-card:active { opacity: .7; }
.cs-card--handler { opacity: .6; }
.cs-card--legacy  { opacity: .4; }

.cs-id {
  font-size: 11px;
  font-weight: 700;
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
  color: var(--hint);
  flex-shrink: 0;
  min-width: 38px;
}

.cs-ttl {
  flex: 1;
  font-size: 13px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

/* Type chip */
.cs-chip {
  font-size: 10px;
  font-weight: 600;
  padding: 1px 6px;
  border-radius: 8px;
  white-space: nowrap;
  flex-shrink: 0;
}
.cs-chip--done    { background: #007aff14; color: #007aff; }
.cs-chip--choice  { background: #34c75914; color: #34c759; }
.cs-chip--value   { background: #ff950014; color: #ff9500; }
.cs-chip--date,
.cs-chip--dt      { background: #af52de14; color: #af52de; }
.cs-chip--handler { background: #88888814; color: #888; }
.cs-chip--sched   { background: #a67c0014; color: #a67c00; }

/* Cross-chain indicator */
.cs-xref-ind { font-size: 11px; color: #ff9500; opacity: .7; flex-shrink: 0; }
.cs-card--xref { border-right: 2px solid #ff950040; }

/* Detail panel (tap to reveal) */
.cs-det {
  display: none;
  padding: 8px 10px 10px;
  margin: 1px 0 2px;
  border-radius: 0 0 8px 8px;
  background: var(--bg);
  border: 1px solid var(--card-bg);
  border-top: none;
}
.cs-det.open { display: block; }

.cs-det-text {
  font-size: 13px;
  color: var(--text);
  line-height: 1.45;
  margin-bottom: 6px;
}
.cs-det-row {
  display: flex;
  align-items: baseline;
  font-size: 12px;
  color: var(--hint);
  margin-top: 2px;
}
.cs-det-kw  { font-weight: 700; color: #34c759; margin-right: 3px; }
.cs-det-arr { margin-right: 3px; }
.cs-det-tgt { font-family: ui-monospace,'SF Mono',Menlo,monospace; font-size: 11px; }

/* The chain-xref pill inside detail panel (reuses existing .chain-xref styles) */
.cs-det .chain-xref { margin-top: 8px; display: inline-flex; }

/* Spine connector between nodes */
.cs-conn {
  height: 14px;
  display: flex;
  align-items: center;
  padding-left: 2px;
}
.cs-conn-kw { font-size: 11px; color: var(--hint); opacity: .6; }

/* Branch pill */
.cs-branch-pill {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  margin: 3px 0;
  border-radius: 10px;
  border: 1px solid var(--card-bg);
  cursor: pointer;
  font-size: 11px;
  color: var(--hint);
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  transition: background .1s, border-color .1s;
}
.cs-branch-pill:active { opacity: .7; }
.cs-branch-pill.open   { background: var(--card-bg); border-color: var(--hint); color: var(--text); }
.cs-bp-kw  { font-weight: 700; color: var(--text); }
.cs-bp-sep { opacity: .4; margin: 0 3px; }
.cs-bp-tgt { font-family: ui-monospace,'SF Mono',Menlo,monospace; }

/* Branch body */
.cs-branch {
  display: none;
  margin: 2px 0 4px 10px;
  padding-left: 10px;
  border-left: 1.5px dashed var(--card-bg);
}
.cs-branch.open { display: block; }

/* Already-visited back-reference */
.cs-back {
  font-size: 11px;
  color: var(--hint);
  opacity: .45;
  padding: 3px 4px;
  font-family: ui-monospace,'SF Mono',Menlo,monospace;
}

/* ── SVG pan/zoom chain canvas ───────────────────────────────────────────── */

.csvg-wrap {
  position: relative;
  overflow: hidden;
  height: 70vh;
  min-height: 300px;
  border-radius: 12px;
  background: var(--card-bg);
  cursor: grab;
  touch-action: none;
  overscroll-behavior: contain;
  -webkit-user-select: none;
  user-select: none;
}
.csvg-wrap:active { cursor: grabbing; }

/* HTML transform target — transform-origin:0 0 is unambiguous on an HTML div (unlike SVG <g>) */
.csvg-pan {
  transform-origin: 0 0;
  will-change: transform;
}

/* Node box (inside foreignObject) */
.chain-box {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  padding: 6px 8px;
  background: var(--bg);
  border-left: 4px solid var(--hint);
  border-radius: 8px;
  cursor: pointer;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 2px;
  touch-action: none;
  -webkit-tap-highlight-color: transparent;
}
.chain-box:active { opacity: .72; }

/* Kind base coloring (phase 2, from the phase-1 node.kind emit): background tint +
   full 1px hairline in the kind color. Declared BEFORE the route-state rules so the
   4px left strip (border-left-color below) always wins on the left edge — the two
   systems compose: kind = card body, route-state = left edge. Raw hexes by decision
   (§8 — the visualizer is excluded from the design tokens; app palette is fixed dark). */
/* 761: staff (operator action) is the EMPHASIZED tint — teal accent (deliberately
   off the entry-strip blue #007aff and all edge hues); system stays the muted one. */
.cbox--k-staff    { background: #0f272e; border: 1px solid #46b8cc66; border-left-width: 4px; }
.cbox--k-system   { background: #15181d; border: 1px solid #262b31; border-left-width: 4px; }
.cbox--k-auto_msg { background: #201430; border: 1px solid #af52de66; border-left-width: 4px; }
.cbox--k-money    { background: #10261a; border: 1px solid #34c75966; border-left-width: 4px; }

/* Routing-state left-border colors */
.cbox--ccentry  { border-left-color: #af52de; }
.cbox--entry    { border-left-color: #007aff; }
.cbox--deadend  { border-left-color: #ff9500; }
.cbox--terminal { border-left-color: #888; }
.cbox--legacy   { opacity: .4; }
/* normal = no route strip: transparent lets the kind tint read cleanly (was
   var(--card-bg), which showed as a stray dark edge on tinted kind cards). */
.cbox--normal   { border-left-color: transparent; }

.cbox-id {
  font-size: 11px;
  font-weight: 700;
  font-family: ui-monospace,'SF Mono',Menlo,monospace;
  color: var(--hint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cbox-txt {
  font-size: 11px;
  color: var(--text);
  flex: 1;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.cbox-chip {
  font-size: 9px;
  font-weight: 600;
  padding: 1px 5px;
  border-radius: 6px;
  white-space: nowrap;
  align-self: flex-start;
  flex-shrink: 0;
}
/* 758: chips are SECONDARY info — one neutral fill for all so they never clash
   with the kind card tints; the hue lives only in the (muted) text color. */
.cbox-chip--done,
.cbox-chip--choice,
.cbox-chip--value,
.cbox-chip--date,
.cbox-chip--dt,
.cbox-chip--handler,
.cbox-chip--sched   { background: #ffffff0d; }
.cbox-chip--done    { color: #6ea3e8cc; }
.cbox-chip--choice  { color: #5cc47ccc; }
.cbox-chip--value   { color: #f0a648cc; }
.cbox-chip--date,
.cbox-chip--dt      { color: #bd7ee6cc; }
.cbox-chip--handler { color: #9aa3adcc; }
.cbox-chip--sched   { color: #c0995ccc; }

/* Floating in-canvas legend (758) — canvas CONTENT above row 0 (inside .csvg-pan,
   pans/zooms with the graph), display-only. Pills speak the phase-2 card language:
   kind pills = the card tints themselves; route pills = the left-strip colors. */
.csvg-canvas-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 5px;
  pointer-events: none;
}
.ckleg {
  font-size: 10px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 8px;
  color: #c8d0d9;
  white-space: nowrap;
}
.ckleg--staff    { background: #0f272e; border: 1px solid #46b8cc66; color: #7fd4e4; }
.ckleg--system   { background: #15181d; border: 1px solid #262b31; color: #9aa3ad; }
.ckleg--auto_msg { background: #201430; border: 1px solid #af52de66; color: #c98af0; }
.ckleg--money    { background: #10261a; border: 1px solid #34c75966; color: #34c759; }
.ckleg-rt {
  font-size: 10px;
  font-weight: 600;
  padding: 2px 8px 2px 6px;
  border-radius: 8px;
  border-left: 3px solid;
  background: #ffffff08;
  white-space: nowrap;
}
.ckleg-rt--entry    { color: #007aff; border-left-color: #007aff; }
.ckleg-rt--ccentry  { color: #af52de; border-left-color: #af52de; }
.ckleg-rt--deadend  { color: #ff9500; border-left-color: #ff9500; }
.ckleg-rt--terminal { color: #888;    border-left-color: #888; }

/* Floating control buttons overlay (inside .csvg-wrap) */
.csvg-controls {
  position: absolute;
  top: 10px;
  right: 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  z-index: 2;
}
.csvg-ctrl-btn {
  width: 36px;
  height: 36px;
  border: none;
  border-radius: 8px;
  background: var(--bg);
  color: var(--text);
  font-size: 16px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: .85;
  box-shadow: 0 1px 3px rgba(0,0,0,.15);
  -webkit-tap-highlight-color: transparent;
}
.csvg-ctrl-btn:active { opacity: .55; }

/* Cross-chain jump button — sits below the node box in the inter-row gap */
.cbox-cc-btn {
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  /* 758: card discipline — tinted box + hairline (orange stays the cross-chain hue) */
  background: #241a10;
  border: 1px solid #ff950055;
  border-radius: 8px;
  font-size: 10px;
  font-weight: 600;
  color: #f0a648;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 0 6px;
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
  font-family: system-ui, -apple-system, sans-serif;
}
.cbox-cc-btn:active { opacity: .65; }

/* Auto-effect annotation pill — descriptive, non-clickable, muted (info, not navigation) */
.cbox-ann-btn {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  /* 758: card discipline — system-tint box, dashed hairline kept (info, not a node) */
  background: #15181d;
  border: 1px dashed #3a424c;
  border-radius: 8px;
  font-size: 9px;
  line-height: 1.25;
  color: #9aa3ad;
  padding: 4px 7px;
  box-sizing: border-box;
  overflow: hidden;
  font-family: system-ui, -apple-system, sans-serif;
}

/* Fullscreen mode: cover entire viewport */
.csvg-wrap--fullscreen {
  position: fixed;
  inset: 0;
  height: 100dvh !important;
  border-radius: 0;
  z-index: 9999;
}

/* Tap-to-detail — CENTERED MODAL (761). Fixed + z-index above the wrap is the
   proven fullscreen pattern; the backdrop swallows taps so pan/zoom never leaks. */
.csvg-det {
  display: none;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(92vw, 420px);
  max-height: 70vh;
  overflow-y: auto;
  overscroll-behavior-y: contain;
  z-index: 10001;
  padding: 14px 16px;
  border-radius: var(--r-md);
  background: var(--card-bg);
  border: 1px solid var(--separator);
}
.csvg-det.open { display: block; }
.csvg-det-backdrop {
  position: fixed;
  inset: 0;
  z-index: 10000;
  background: rgba(0, 0, 0, .45);
}
.csvg-det-head {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}
.csvg-det-head .csvg-det-id { flex: 1; }
.csvg-det-close {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  margin: -4px -6px 0 0;
  border: none;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--hint);
  font-size: 15px;
  cursor: pointer;
}
.csvg-det-langs {
  margin-bottom: 8px;
}
.csvg-det-id {
  font-family: ui-monospace,'SF Mono',Menlo,monospace;
  font-weight: 700;
  font-size: 12px;
  color: var(--hint);
  margin-bottom: 4px;
}
.csvg-det-text {
  font-size: 13px;
  color: var(--text);
  line-height: 1.45;
  margin-bottom: 6px;
}
.csvg-det-row   { display: flex; align-items: baseline; font-size: 12px; color: var(--hint); margin-top: 2px; }
.csvg-det-kw    { font-weight: 700; color: #34c759; margin-right: 4px; }
.csvg-det-arr   { margin-right: 4px; }
.csvg-det-tgt   { font-family: ui-monospace,'SF Mono',Menlo,monospace; font-size: 11px; }

/* Phase-3 detail-panel additions — kind badge (phase-2 palette family), auto-send
   line, collapsed template preview. Raw hexes by decision (§8, visualizer). */
.csvg-det-kind {
  font-size: 10px;
  font-weight: 600;
  padding: 1px 7px;
  border-radius: 7px;
  margin-left: 6px;
  vertical-align: 1px;
}
.csvg-det-kind--staff    { background: #2c364466; color: #c8d0d9; }
.csvg-det-kind--system   { background: #262b3166; color: #9aa3ad; }
.csvg-det-kind--auto_msg { background: #af52de22; color: #c98af0; }
.csvg-det-kind--money    { background: #34c75922; color: #34c759; }
.csvg-det-auto  { color: #c98af0; font-weight: 600; }
.csvg-det-tpl-btn {
  display: block;
  margin-top: 6px;
  padding: 4px 10px;
  font-size: 11px;
  font-weight: 600;
  border: 1px solid #2c3644;
  border-radius: 8px;
  background: transparent;
  color: var(--link);
  cursor: pointer;
}
.csvg-det-tpl-wrap {
  margin-top: 8px;
}
/* Apartment selector for the per-apartment template preview (790) — compact,
   visualizer-palette (raw values by decision, §12 exemption). */
.csvg-apt-sel {
  display: block;
  max-width: 210px;
  margin-bottom: 6px;
  padding: 4px 8px;
  border-radius: 8px;
  border: 1px solid #262b31;
  background: #10141a;
  color: var(--text);
  font-size: 12px;
}
.csvg-det-tpl {
  margin-top: 6px;
  padding: 8px 10px;
  border-radius: 8px;
  background: #10141a;
  font-size: 12px;
  color: var(--text);
  line-height: 1.45;
  white-space: pre-line;
}
