/* =============================================================================
   fin — design-system stylesheet
   iOS / Telegram aesthetic: token layer + migrated components + status map
   Phase 16, Plan 01
   ============================================================================= */

/* === TOKENS ================================================================ */

:root {
  /* ── Accent (dark; folded up from the former [data-theme="dark"] override —
     see quick-260721-114 SUMMARY for the displaced light values: --accent
     #19e64d, --accent-hover #15c140) ───────────────────────────────────── */
  --pico-primary: #51b86e;
  --accent: #51b86e;
  --accent-hover: #6ec487;

  /* ── Font ───────────────────────────────────────────────────────────────── */
  --pico-font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text",
                      "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* ── Radii ──────────────────────────────────────────────────────────────── */
  --radius-button: 12px;
  --radius-card: 16px;
  --radius-modal: 20px;
  --radius-pill: 999px;

  /* Set PicoCSS global border-radius to the button radius */
  --pico-border-radius: var(--radius-button);

  /* ── Chart layout tokens (shared so both surfaces align identically) ──────── */
  /* Bar rows (По месяцам widget + G2 money): fixed label/value columns so the
     track left+right edges line up across EVERY row regardless of label length. */
  --bar-label-col: 135px;
  --bar-value-col: 100px;
  /* Line-chart Y-axis gutter (burn-up + cumulative): narrow, left-hugging labels. */
  --chart-y-gutter: 46px;

  /* ── Motion ─────────────────────────────────────────────────────────────── */
  --transition-fast: 150ms ease-out;

  /* ── Elevation (dark; folded up — light was 0 1px 4px rgba(0,0,0,.08)/0 2px 8px
     rgba(0,0,0,.06) card, 0 8px 32px rgba(0,0,0,.18)/0 2px 8px rgba(0,0,0,.12) modal) ── */
  --shadow-card:  0 1px 4px rgba(0, 0, 0, .30), 0 2px 8px rgba(0, 0, 0, .22);
  --shadow-modal: 0 8px 32px rgba(0, 0, 0, .50), 0 2px 8px rgba(0, 0, 0, .35);

  /* ── Status color tokens (9 real Deal.status codes; dark — folded up. Light was
     pending #8E8E93, awaiting_payment/in_stock #FF9F0A, in_progress #19e64d,
     on_hold #8E8E93, completed #34C759, disputed #FF6B00, refunded/cancelled
     #FF3B30) ────────────────────────────────────────────────────────────── */
  --status-pending:          #98989d;   /* neutral gray   */
  --status-awaiting_payment: #ffb340;   /* warning amber  */
  --status-in_stock:         #ffb340;   /* warning amber  */
  --status-in_progress:      #51b86e;   /* info blue (=accent) */
  --status-on_hold:          #98989d;   /* neutral gray   */
  --status-completed:        #57aa6e;   /* success green  */
  --status-disputed:         #ff8c00;   /* orange         */
  --status-refunded:         #ff453a;   /* danger red     */
  --status-cancelled:        #ff453a;   /* danger red     */

  /* ── quick-260721-114: color-token layer (dark; FULL 1:1 fidelity — each
     distinct literal keeps its own token, no shade merged/shifted). :root
     IS dark (default, no data-theme attr). See SUMMARY for the complete
     value->token map and the two role-divergence exceptions. ────────────── */
  /* -- Surfaces (dark) -- */
  --bg-sidebar: #0e1512;
  --surface-1: #657a70;
  --surface-10: #355144;
  --surface-11: #33473e;
  --surface-12: #2c4338;
  --surface-13: #253930;
  --surface-14: #0e1612;
  --surface-15: #70837a;
  --surface-16: #61716a;
  --surface-17: #4b6458;
  --surface-18: #333333;
  --surface-19: #2e463b;
  --surface-2: #203029;
  --surface-20: #334f42;
  --surface-21: #293f35;
  --surface-22: #212e28;
  --surface-23: #1c1c1e;
  --surface-24: #2b4237;
  --surface-25: #192620;
  --surface-26: #101814;
  --surface-3: #667970;
  --surface-4: #23372e;
  --surface-5: #203129;
  --surface-6: #000000;
  --surface-7: #395246;
  --surface-8: #24382f;
  --surface-9: #21312a;
  --surface-card: #121b17;
  --surface-inset: #0f1713;
  --surface-row: rgba(255,255,255,0.04);
  --surface-tile: #192821;
  /* -- Text -- */
  --text-1: #a2b5ac;
  --text-10: #f3f6f5;
  --text-11: #c8d6cf;
  --text-12: #b5c3bc;
  --text-13: #98989d;
  --text-14: #8e8e93;
  --text-15: #e8e8e8;
  --text-16: #eaf2ee;
  --text-17: #ccd8d2;
  --text-18: #c1d6cc;
  --text-19: #a2b5ac;
  --text-2: #ffffff;
  --text-20: #92a59c;
  --text-21: #8f9f98;
  --text-22: #888888;
  --text-3: #c9d7d0;
  --text-4: #e0e0e0;
  --text-5: #d1e0d9;
  --text-6: #768980;
  --text-7: #f9fbfa;
  --text-8: #d3e0da;
  --text-9: #91a19a;
  --text-muted: #85988f;
  --text-primary: #ecf3f0;
  /* -- Hairline -- */
  --hairline: rgba(255,255,255,0.06);
  /* -- Blue family -- */
  /* Акцент перекрашен в зелёный логотипа froks (решение владельца
     2026-08-03). Имена --c-blue* исторические (каркас fin): менялись
     ЗНАЧЕНИЯ, не имена, чтобы не раздувать дифф; переименование в
     --c-accent* — кандидат на уборку Task 13. */
  --c-blue: #51b86e;
  --c-blue-10: #ddf1e3;
  --c-blue-11: #c2e6cc;
  --c-blue-12: #a4dab4;
  --c-blue-13: #9cd4ac;
  --c-blue-14: #83cb97;
  --c-blue-15: #81cb96;
  --c-blue-16: #80ca95;
  --c-blue-17: #7bc891;
  --c-blue-18: #60be7b;
  --c-blue-19: #3e9858;
  --c-blue-2: #4ab568;
  --c-blue-3: #6ec487;
  --c-blue-4: #8ed0a1;
  --c-blue-5: #6cc284;
  --c-blue-6: #8acf9e;
  --c-blue-7: #69c182;
  --c-blue-8: #f8fcf9;
  --c-blue-9: #a1d8b0;
  --c-blue-a07: rgba(34,231,84,0.07);
  --c-blue-a08: rgba(34,231,84,0.08);
  --c-blue-a09: rgba(68,234,109,0.09);
  --c-blue-a10: rgba(34,231,84,0.1);
  --c-blue-a10-2: rgba(25,230,77,0.1);
  --c-blue-a12: rgba(34,231,84,0.12);
  --c-blue-a14: rgba(34,231,84,0.14);
  --c-blue-a15: rgba(68,234,109,0.15);
  --c-blue-a15-2: rgba(34,231,84,0.15);
  --c-blue-a16: rgba(34,231,84,0.16);
  --c-blue-a18: rgba(34,231,84,0.18);
  --c-blue-a20: rgba(34,231,84,0.2);
  --c-blue-a20-2: rgba(25,230,77,0.2);
  --c-blue-a22: rgba(34,231,84,0.22);
  --c-blue-a25: rgba(34,231,84,0.25);
  --c-blue-a28: rgba(34,231,84,0.28);
  --c-blue-a35: rgba(34,231,84,0.35);
  --c-blue-a40: rgba(107,238,140,0.4);
  --c-blue-a40-2: rgba(68,234,109,0.4);
  --c-blue-a40-3: rgba(34,231,84,0.4);
  --c-blue-a45: rgba(107,238,140,0.45);
  --c-blue-a45-2: rgba(34,231,84,0.45);
  --c-blue-a45-3: rgba(25,230,77,0.45);
  --c-blue-a50: rgba(34,231,84,0.5);
  --c-blue-a55: rgba(107,238,140,0.55);
  --c-blue-a55-2: rgba(68,234,109,0.55);
  --c-blue-a55-3: rgba(34,231,84,0.55);
  --c-blue-a60: rgba(134,242,161,0.6);
  --c-blue-a70: rgba(25,230,77,0.7);
  /* -- Green family -- */
  --c-green: #57aa6e;
  --c-green-2: #7cbc8e;
  --c-green-3: #57a46d;
  --c-green-4: #96caa5;
  --c-green-5: #6eba83;
  --c-green-6: #3d8050;
  --c-green-a08: rgba(48,209,88,0.08);
  --c-green-a10: rgba(48,209,88,0.1);
  --c-green-a14: rgba(48,209,88,0.14);
  --c-green-a15: rgba(48,209,88,0.15);
  --c-green-a16: rgba(48,209,88,0.16);
  --c-green-a18: rgba(48,209,88,0.18);
  --c-green-a20: rgba(48,209,88,0.2);
  --c-green-a24: rgba(48,209,88,0.24);
  --c-green-a35: rgba(48,209,88,0.35);
  --c-green-a45: rgba(48,209,88,0.45);
  --c-green-a55: rgba(48,209,88,0.55);
  /* -- Amber family -- */
  --c-amber: #f0a83c;
  --c-amber-2: #ffb340;
  --c-amber-3: #ff9f0a;
  --c-amber-4: #ffc266;
  --c-amber-5: #ff8c00;
  --c-amber-6: #ff6b00;
  --c-amber-a08: rgba(240,168,60,0.08);
  --c-amber-a14: rgba(240,168,60,0.14);
  --c-amber-a15: rgba(240,168,60,0.15);
  --c-amber-a18: rgba(255,179,64,0.18);
  --c-amber-a18-2: rgba(255,140,0,0.18);
  --c-amber-a18-3: rgba(240,168,60,0.18);
  --c-amber-a35: rgba(255,179,64,0.35);
  --c-amber-a35-2: rgba(255,140,0,0.35);
  --c-amber-a45: rgba(240,168,60,0.45);
  --c-amber-a50: rgba(240,168,60,0.5);
  --c-amber-a65: rgba(240,168,60,0.65);
  /* -- Red family -- */
  --c-red: #ff6b6b;
  --c-red-2: #ff3b30;
  --c-red-3: #ff453a;
  --c-red-4: #dc3545;
  --c-red-5: #ff8a8a;
  --c-red-6: #ff9a9a;
  --c-red-7: #ff8f8f;
  --c-red-8: #ff8585;
  --c-red-9: #ff4d4f;
  --c-red-a07: rgba(255,107,107,0.07);
  --c-red-a08: rgba(255,107,107,0.08);
  --c-red-a10: rgba(255,69,58,0.1);
  --c-red-a10-2: rgba(255,107,107,0.1);
  --c-red-a12: rgba(255,107,107,0.12);
  --c-red-a12-2: rgba(255,69,58,0.12);
  --c-red-a14: rgba(255,138,138,0.14);
  --c-red-a14-2: rgba(255,107,107,0.14);
  --c-red-a15: rgba(255,107,107,0.15);
  --c-red-a18: rgba(255,69,58,0.18);
  --c-red-a20: rgba(255,107,107,0.2);
  --c-red-a30: rgba(255,107,107,0.3);
  --c-red-a30-2: rgba(255,69,58,0.3);
  --c-red-a35: rgba(255,69,58,0.35);
  --c-red-a35-2: rgba(255,107,107,0.35);
  --c-red-a40: rgba(255,69,58,0.4);
  --c-red-a40-2: rgba(255,107,107,0.4);
  --c-red-a45: rgba(255,107,107,0.45);
  --c-red-a50: rgba(255,107,107,0.5);
  --c-red-a60: rgba(255,107,107,0.6);
  --c-red-a70: rgba(255,107,107,0.7);
  /* -- Violet family -- */
  --c-violet: #b48fff;
  --c-violet-2: #bf5af2;
  --c-violet-a14: rgba(140,90,255,0.14);
  /* -- Lightblue family -- */
  --c-lightblue: #97bdab;
  --c-lightblue-a14: rgba(90,200,250,0.14);
  /* -- White-alpha -- */
  --wa-02: rgba(255,255,255,0.02);
  --wa-05: rgba(255,255,255,0.05);
  --wa-07: rgba(255,255,255,0.07);
  --wa-08: rgba(255,255,255,0.08);
  --wa-09: rgba(255,255,255,0.09);
  --wa-10: rgba(255,255,255,0.1);
  --wa-12: rgba(255,255,255,0.12);
  --wa-14: rgba(255,255,255,0.14);
  --wa-16: rgba(255,255,255,0.16);
  --wa-18: rgba(255,255,255,0.18);
  --wa-20: rgba(255,255,255,0.2);
  --wa-28: rgba(255,255,255,0.28);
  --wa-35: rgba(255,255,255,0.35);
  --wa-40: rgba(255,255,255,0.4);
  --wa-45: rgba(255,255,255,0.45);
  /* -- Black-alpha -- */
  --sc-06: rgba(0,0,0,0.06);
  --sc-08: rgba(0,0,0,0.08);
  --sc-12: rgba(0,0,0,0.12);
  --sc-14: rgba(0,0,0,0.14);
  --sc-18: rgba(0,0,0,0.18);
  --sc-22: rgba(0,0,0,0.22);
  --sc-28: rgba(0,0,0,0.28);
  --sc-30: rgba(0,0,0,0.3);
  --sc-35: rgba(0,0,0,0.35);
  --sc-40: rgba(0,0,0,0.4);
  --sc-50: rgba(0,0,0,0.5);
  --sc-55: rgba(0,0,0,0.55);
  /* -- Neutral-alpha (misc muted tints) -- */
  --nx-1-a18: rgba(152,152,157,0.18);
  --nx-10-a30: rgba(128,128,128,0.3);
  --nx-11-a20: rgba(125,138,160,0.2);
  --nx-12-a10: rgba(125,138,160,0.1);
  --nx-2-a35: rgba(152,152,157,0.35);
  --nx-3-a20: rgba(128,128,128,0.2);
  --nx-4-a15: rgba(128,128,128,0.15);
  --nx-5-a12: rgba(125,138,160,0.12);
  --nx-6-a15: rgba(125,138,160,0.15);
  --nx-7-a80: rgba(26,36,56,0.8);
  --nx-8-a45: rgba(195,204,221,0.45);
  --nx-9-a50: rgba(128,128,128,0.5);
  /* -- Role-divergence exception: --bg-page shares --surface-card's dark literal;
     the light-theme task (QUEUED-260721-light-theme.md) gives them different
     light values (bg-page #f6f8fc vs surface-card #fff). No body occurrence to
     match today -- Pico vendor CSS paints the actual page canvas. -- */
  --bg-page: #121b17;
}

/* ── Dark theme overrides ───────────────────────────────────────────────── */
[data-theme="dark"] {
  /* quick-260721-114: all dark values now live in :root directly (folded
     up from here). Kept as a harmless, empty, explicit selector so
     `data-theme="dark"` continues to resolve — anti-FOUC script and the
     sidebar toggle in base.html are untouched. */
}

/* ── Reduced-motion guard ───────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .deals-list tbody tr.deal-row:hover {
    transform: none;
  }

  dialog.modal-form > article,
  dialog.modal-detail > article {
    animation: none !important;
  }
}


/* === COMPONENTS ============================================================ */

/* ── Summary grid ─────────────────────────────────────────────────────────── */
#summary-grid {
  display: grid;
  grid-template-columns: 1fr 1fr; /* Итого + По месяцам, equal width on desktop */
  gap: 16px;
}

@media (max-width: 768px) {
  #summary-grid {
    grid-template-columns: 1fr; /* stack vertically on mobile */
  }
}

/* «По месяцам» — one month per line, never wrapping (month left, ₽ right). */
.monthly-breakdown {
  list-style: none;
  margin: 0;
  padding: 0;
}

.monthly-breakdown li {
  /* Fixed-track 3-col bar row: [label | track | value].
     FIXED label/value columns (not auto) — auto sizes to each row's text, so
     different month-label lengths («Август 2025» vs «Сентябрь 2025») would push
     the track to a different x per row and the bar left-edges would not align.
     Fixed columns guarantee track left+right edges line up across every row.
     Mirrors .bar-chart__row (same tokens) so both surfaces are identical. */
  display: grid;
  grid-template-columns: var(--bar-label-col) minmax(0, 1fr) var(--bar-value-col);
  align-items: center;
  gap: 12px;
  /* No horizontal padding — the label left edge sits at the widget content edge
     (= the .widget-header icon), so months align with the «По месяцам» title.
     The freed horizontal space goes to the track. Vertical 6px for row breathing. */
  padding: 6px 0;
  white-space: nowrap;
}

.monthly-breakdown .mb-amounts {
  /* Grid col 3 (value column) — mirrors .bar-chart__value: right-aligned, tabular. */
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  text-align: right;
  min-width: 0;
}

.monthly-breakdown .mb-prov {
  opacity: 0.75; /* provisional «в работе» reads as secondary */
}

/* ── Monthly breakdown mini-bars (inline data bars, no JS) ──────────────── */
/* .mb-month: label auto-width (CLAUDE.md: auto/max-content + nowrap, NOT min-content)
   Grid item in col 1 — same role as .bar-chart__label in the unified 3-col bar layout. */
.monthly-breakdown .mb-month {
  font-size: 13px;
  color: var(--pico-muted-color);
  white-space: nowrap;          /* never break label */
  min-width: 0;
}
/* .mb-track: grid col 2 — flexible groove between label and value.
   Shares visual token with .bar-chart__track (same border-radius/bg/overflow). */
.monthly-breakdown .mb-track {
  width: 100%;
  height: 11px;
  border-radius: 6px;
  background: color-mix(in srgb, var(--pico-muted-border-color, var(--text-4)) 60%, transparent);
  overflow: hidden;
}
/* .mb-fill: data bar — width set inline as a percentage */
.monthly-breakdown .mb-fill {
  display: block;
  height: 100%;
  border-radius: 6px;
  background: color-mix(in srgb, var(--accent) 30%, transparent);
  transition: width var(--transition-fast, 150ms ease-out);
}
/* Negative months — red-tinted bar */
.monthly-breakdown .mb-fill--negative {
  background: color-mix(in srgb, var(--status-refunded) 25%, transparent);
}

/* ── Amount helpers ──────────────────────────────────────────────────────── */
.amount-negative {
  color: var(--pico-del-color);
}

/* ── Numeric cells ───────────────────────────────────────────────────────── */
td.numeric, th.numeric {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* ── Deals table wrapper (sticky scroll) ────────────────────────────────── */
#deals-table-wrapper {
  max-height: 60vh;
  overflow-y: auto;
  overflow-x: auto;
  border: 1px solid var(--pico-table-border-color, var(--text-4));
  border-radius: 4px;
}

#deals-table-wrapper table {
  border-collapse: collapse;
  width: 100%;
}

/* Single-line rows: headers + cells never wrap */
#deals-table-wrapper th,
#deals-table-wrapper td {
  white-space: nowrap;
}

/* «Объект» + «Покупатель» truncate with ellipsis instead of wrapping; full text on
   hover via the cells' title attr (set in the template). Narrowed so the «Оплата»
   column has room (260621). */
#deals-table-wrapper td.subject-cell,
#deals-table-wrapper td.buyer-cell {
  max-width: 160px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The whole row is clickable — the product link is plain text, not a link */
#deals-table-wrapper td.subject-cell a {
  text-decoration: none;
  color: inherit;
}

/* ── Deal row — clean hover lift (260616-ien: row tint removed; color in pill only) ─── */
/* Status color now lives exclusively in the per-row status pill (.status-chip-select).
   Rows are clean (no permanent tint); only a subtle hover lift signals interactivity. */
.deals-list tbody tr.deal-row {
  cursor: pointer;
  transition: background-color 120ms ease, transform 120ms ease;
}

/* Thin bottom separator on cells — replaces the old border-top row separator */
.deals-list tbody td {
  border-bottom: 1px solid var(--wa-05);
  padding: 14px 18px;
}

/* Hover: subtle lighten + slight lift — compositor-friendly (transform/background only) */
.deals-list tbody tr.deal-row:hover {
  background: var(--surface-row);
  transform: translateY(-1px);
}

/* ── Sticky table header ─────────────────────────────────────────────────── */
#deals-table-wrapper thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--pico-card-background-color, var(--text-7));
  font-weight: 600;
  box-shadow: inset 0 -1px 0 var(--pico-table-border-color, var(--text-4));
}

/* ── Status chips row ────────────────────────────────────────────────────── */
.status-chips {
  display: flex;
  gap: 8px;
  padding: 12px 0;
  margin-bottom: 16px;
  /* Telegram-style category bar: subtle divider from the table below, and a
     single non-wrapping row that scrolls horizontally with a hidden scrollbar. */
  border-bottom: 1px solid var(--pico-muted-border-color);
  overflow-x: auto;
  scrollbar-width: none;          /* Firefox */
}

.status-chips::-webkit-scrollbar {
  display: none;                  /* WebKit/Blink */
}

/* ── Base chip pill ──────────────────────────────────────────────────────── */
.chip {
  display: inline-flex;
  align-items: center;
  padding: 6px 14px;
  font-size: 14px;
  font-weight: 400;
  line-height: 1.4;
  border: 1px solid var(--pico-muted-border-color, var(--text-4));
  border-radius: var(--radius-pill);   /* D-04: pill shape */
  background: var(--pico-card-background-color, var(--text-7));
  color: var(--pico-color, var(--surface-18));
  cursor: pointer;
  white-space: nowrap;
  margin: 0;
  text-decoration: none;   /* for <a> chips (attachment chips) */
  transition: background var(--transition-fast), border-color var(--transition-fast),
              color var(--transition-fast), box-shadow var(--transition-fast);
}

.chip:hover:not(.chip-active) {
  background: var(--pico-muted-color, var(--text-15));
  border-color: var(--pico-primary, var(--c-blue-2));
}

.chip:focus-visible {
  outline: 2px solid var(--pico-primary, var(--c-blue-2));
  outline-offset: 2px;
}

/* Active (selected) chip — filled solid */
.chip-active {
  background: var(--pico-primary, var(--c-blue-2));
  color: var(--text-2);
  border-color: var(--pico-primary, var(--c-blue-2));
  font-weight: 600;
}

/* ── Status-color chip variants (D-04, 9 real codes) ───────────────────── */
/* Tinted: translucent colored bg + solid colored text + colored border */

.chip--pending {
  background: color-mix(in srgb, var(--status-pending) 14%, transparent);
  color: var(--status-pending);
  border-color: color-mix(in srgb, var(--status-pending) 35%, transparent);
}
.chip--pending.chip-active {
  background: var(--status-pending);
  color: var(--text-2);
  border-color: var(--status-pending);
}

.chip--awaiting_payment {
  background: color-mix(in srgb, var(--status-awaiting_payment) 14%, transparent);
  color: var(--status-awaiting_payment);
  border-color: color-mix(in srgb, var(--status-awaiting_payment) 35%, transparent);
}
.chip--awaiting_payment.chip-active {
  background: var(--status-awaiting_payment);
  color: var(--text-2);
  border-color: var(--status-awaiting_payment);
}

.chip--in_stock {
  background: color-mix(in srgb, var(--status-in_stock) 14%, transparent);
  color: var(--status-in_stock);
  border-color: color-mix(in srgb, var(--status-in_stock) 35%, transparent);
}
.chip--in_stock.chip-active {
  background: var(--status-in_stock);
  color: var(--text-2);
  border-color: var(--status-in_stock);
}

.chip--in_progress {
  background: color-mix(in srgb, var(--status-in_progress) 14%, transparent);
  color: var(--status-in_progress);
  border-color: color-mix(in srgb, var(--status-in_progress) 35%, transparent);
}
.chip--in_progress.chip-active {
  background: var(--status-in_progress);
  color: var(--text-2);
  border-color: var(--status-in_progress);
}

.chip--on_hold {
  background: color-mix(in srgb, var(--status-on_hold) 14%, transparent);
  color: var(--status-on_hold);
  border-color: color-mix(in srgb, var(--status-on_hold) 35%, transparent);
}
.chip--on_hold.chip-active {
  background: var(--status-on_hold);
  color: var(--text-2);
  border-color: var(--status-on_hold);
}

.chip--completed {
  background: color-mix(in srgb, var(--status-completed) 14%, transparent);
  color: var(--status-completed);
  border-color: color-mix(in srgb, var(--status-completed) 35%, transparent);
}
.chip--completed.chip-active {
  background: var(--status-completed);
  color: var(--text-2);
  border-color: var(--status-completed);
}

.chip--disputed {
  background: color-mix(in srgb, var(--status-disputed) 14%, transparent);
  color: var(--status-disputed);
  border-color: color-mix(in srgb, var(--status-disputed) 35%, transparent);
}
.chip--disputed.chip-active {
  background: var(--status-disputed);
  color: var(--text-2);
  border-color: var(--status-disputed);
}

.chip--refunded {
  background: color-mix(in srgb, var(--status-refunded) 14%, transparent);
  color: var(--status-refunded);
  border-color: color-mix(in srgb, var(--status-refunded) 35%, transparent);
}
.chip--refunded.chip-active {
  background: var(--status-refunded);
  color: var(--text-2);
  border-color: var(--status-refunded);
}

.chip--cancelled {
  background: color-mix(in srgb, var(--status-cancelled) 14%, transparent);
  color: var(--status-cancelled);
  border-color: color-mix(in srgb, var(--status-cancelled) 35%, transparent);
}
.chip--cancelled.chip-active {
  background: var(--status-cancelled);
  color: var(--text-2);
  border-color: var(--status-cancelled);
}

/* ── Status badge pills (table status cell) ─────────────────────────────── */
.status-badge {
  display: inline-block;
  padding: 3px 8px;
  border-radius: var(--radius-pill);
  font-size: 12px;
  font-weight: 500;
  border: 1px solid transparent;
}

.status-pending {
  background: color-mix(in srgb, var(--status-pending) 28%, transparent);
  color: var(--status-pending);
  border-color: color-mix(in srgb, var(--status-pending) 35%, transparent);
}
.status-awaiting_payment {
  background: color-mix(in srgb, var(--status-awaiting_payment) 28%, transparent);
  color: var(--status-awaiting_payment);
  border-color: color-mix(in srgb, var(--status-awaiting_payment) 35%, transparent);
}
.status-in_stock {
  background: color-mix(in srgb, var(--status-in_stock) 28%, transparent);
  color: var(--status-in_stock);
  border-color: color-mix(in srgb, var(--status-in_stock) 35%, transparent);
}
.status-in_progress {
  background: color-mix(in srgb, var(--status-in_progress) 28%, transparent);
  color: var(--status-in_progress);
  border-color: color-mix(in srgb, var(--status-in_progress) 35%, transparent);
}
.status-on_hold {
  background: color-mix(in srgb, var(--status-on_hold) 28%, transparent);
  color: var(--status-on_hold);
  border-color: color-mix(in srgb, var(--status-on_hold) 35%, transparent);
}
.status-completed {
  background: color-mix(in srgb, var(--status-completed) 28%, transparent);
  color: var(--status-completed);
  border-color: color-mix(in srgb, var(--status-completed) 35%, transparent);
}
.status-disputed {
  background: color-mix(in srgb, var(--status-disputed) 28%, transparent);
  color: var(--status-disputed);
  border-color: color-mix(in srgb, var(--status-disputed) 35%, transparent);
}
.status-refunded {
  background: color-mix(in srgb, var(--status-refunded) 28%, transparent);
  color: var(--status-refunded);
  border-color: color-mix(in srgb, var(--status-refunded) 35%, transparent);
}
.status-cancelled {
  background: color-mix(in srgb, var(--status-cancelled) 28%, transparent);
  color: var(--status-cancelled);
  border-color: color-mix(in srgb, var(--status-cancelled) 35%, transparent);
}

/* ── Inline status editor — always-visible <select> styled as the status pill ──
   Robust replacement for the old badge-reveal/onblur dance (260614-0zk): a native
   <select> with hx-post fires change→POST directly (no focus/blur race). It carries
   the status-{code} class for the tint/colour; the chevron is set here as LONGHAND
   background-image so it survives the status-{code} `background` shorthand above
   (later source order + longhand wins the background-image property; background-color
   stays the status tint). Placed AFTER the status-* colour block deliberately. */
.status-chip-select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  display: inline-block;
  width: auto;                     /* override PicoCSS select width:100% — size to content */
  max-width: 170px;                /* compact pill, not full-cell-width */
  font-size: 12px;
  font-weight: 500;
  line-height: 1.4;
  padding: 3px 22px 3px 8px;       /* right padding leaves room for the chevron */
  border-radius: var(--radius-pill);
  border: 1px solid transparent;   /* status-{code} sets border-color */
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 5px center;
  background-size: 11px;
}
.status-chip-select:focus {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 30%, transparent);
}

/* ── Filter bar ──────────────────────────────────────────────────────────── */
.filter-bar {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: flex-end;
  margin-top: 8px;
}
.filter-bar label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 14px;
}

/* ── Buttons (D-06): filled accent primary, tinted secondary ────────────── */
button,
[role="button"],
input[type="submit"],
input[type="button"] {
  border-radius: var(--radius-button);
  transition: background var(--transition-fast), border-color var(--transition-fast),
              box-shadow var(--transition-fast), opacity var(--transition-fast);
}

button.secondary,
a.secondary,
[role="button"].secondary {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
}

button.secondary:hover,
a.secondary:hover,
[role="button"].secondary:hover {
  background: color-mix(in srgb, var(--accent) 20%, transparent);
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
}

button.secondary:active,
a.secondary:active,
[role="button"].secondary:active {
  background: color-mix(in srgb, var(--accent) 28%, transparent);
}

/* ── Inputs + textarea — rounded radius + accent focus ring ─────────────── */
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
textarea {
  border-radius: var(--radius-button);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

input:focus,
textarea:focus {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}

/* ── Select — unified look: appearance:none, custom chevron, accent focus ── */
select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background-color: var(--pico-card-background-color);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 12px;
  border: 1px solid var(--pico-muted-border-color);
  border-radius: var(--radius-button);
  padding: 8px 32px 8px 12px;
  font-size: 14px;
  color: var(--pico-color);
  cursor: pointer;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

select:focus {
  border-color: var(--accent);
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}

/* ── Number inputs — remove ↑↓ spinner arrows globally ──────────────────── */
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}

/* ── Form: amount + currency row ─────────────────────────────────────────── */
.amount-currency-row {
  display: flex;
  gap: 8px;
  align-items: flex-end;
}
.amount-currency-row input {
  flex: 1;
  margin-bottom: 0;
}
.amount-currency-row select {
  flex: 0 0 auto;
  width: auto;
  min-width: 7rem;   /* room for 3-letter code + Pico chevron */
  margin-bottom: 0;
}

/* ── Inline field error ───────────────────────────────────────────────────── */
.form-error {
  color: var(--pico-del-color);
  font-size: 14px;
  display: block;
  margin-top: 4px;
}

/* ── Пароль — показать/копировать (Task 8a, часть 3, Global Constraint
   проекта) ── общий компонент для drops/_email_form.html (форма) и
   drops/_card_emails.html (строка таблицы, .password-field--row). Тот же
   приём, что .amount-currency-row выше: input внутри флекс-ряда не может
   нести вертикальный margin-bottom инпута целиком, иначе кнопки съезжают
   относительно поля. */
.password-field {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 10px;
}
.password-field input {
  flex: 1;
  min-width: 0;
  margin-bottom: 0;
}
.password-field__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid var(--wa-08);
  border-radius: var(--radius-button);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.password-field__btn:hover { background: var(--surface-row); color: var(--text-primary); }
.password-field__btn:focus:not(:focus-visible) { outline: none; }
.password-field__btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--c-blue-a35);
}

/* .password-field--row (drops/_card_emails.html) — компактный вид в контексте
   СТРОКИ ТАБЛИЦЫ, а не формы: без этого правила input наследует полноразмерные
   Pico-паддинги/высоту формы (padding ~15px 20px, ~62.5px высотой — измерено
   живым осмотром карточки дропа), вдвое выше соседних 28-32px кнопок строки,
   и вся строка с паролем становится заметно выше строк без него. Раньше
   класс был заявлен комментарием как «только для адресации, не для стилей» —
   ложное обещание (IMP-3-класс дефекта, см. отчёт Task 8a часть 3): модификатор
   для ВТОРОГО визуального контекста без единого собственного правила получает
   дефолты фреймворка, а не предполагаемый компактный вид.
   .password-field.password-field--row (оба класса) — специфичность (0,2,1),
   заведомо выше голого .password-field input (0,1,1): порядок правил в файле
   не должен решать исход. */
.password-field.password-field--row input {
  height: 30px;
  padding: 0 8px;
  font-size: 13px;
}

/* Review Task 8a, I-1: модификатор выше переопределил высоту/паддинги/кегль
   у ИНПУТА, но не отступ у самого флекс-контейнера — `.password-field`
   несёт `margin-bottom: 10px` (ритм формы, где строка одна на весь блок), а
   внутри `<td>` этот нижний внешний отступ не схлопывается (у ячейки есть
   собственный padding — margin соседа с padding родителя не схлопывается),
   поэтому строка с паролем оставалась примерно на 10px выше соседних строк
   даже после того, как компактный вид самого инпута уже был исправлен.
   Тот же приём специфичности (0,2,1), что у правила выше. */
.password-field.password-field--row {
  margin-bottom: 0;
}

/* ── Form actions row ────────────────────────────────────────────────────── */
.form-actions {
  display: flex;
  gap: 12px;
  align-items: stretch;
  margin-top: 24px;
}
.form-actions > * {
  margin-bottom: 0;
}
.form-actions .secondary {
  flex: 1;
}
.form-actions button[type="submit"] {
  flex: 2;
}

/* ── Modal: frosted-glass backdrop (D-05) ────────────────────────────────── */
dialog.modal::backdrop {
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  background: var(--sc-35);
}

/* ── Modal: suppress the focus outline on the <dialog> ITSELF ──────────────
   .showModal() moves initial focus to the full-viewport `<dialog.modal
   tabindex="-1">` when no child autofocuses; :focus-visible then drew a 1px
   auto outline tracing the whole screen edge (a side-effect of the modal-×
   focus rework). Scoped to the dialog element only — interactive controls
   INSIDE the modal (button/input/select/textarea) keep their own
   :focus-visible rings, so keyboard a11y is unaffected. */
dialog.modal:focus,
dialog.modal:focus-visible {
  outline: none;
}

/* ── Modal dialog — add/edit form (modal-form): compact 560px ───────────── */
/* Modifier class on <dialog> avoids the descendant-leak bug where the old
   generic `dialog.modal article` selector clamped nested <article> cards in
   the detail modal to 560px (260613-ppn Fix C). */
dialog.modal-form > article {
  width: min(560px, 92vw);
  max-height: 90vh;
  overflow-y: auto;
  /* padding-top 0 — the sticky <header> owns its top padding so it pins flush (260618-u67). */
  padding: 0 24px 24px;
  border-radius: var(--radius-modal);
  box-shadow: var(--shadow-modal);
  animation: modal-slide-up 220ms cubic-bezier(0.32, 0, 0.21, 1) both;
}

/* ── Modal dialog — detail view (modal-detail): compact 720px (260617-1tj) ─ */
dialog.modal-detail > article {
  width: min(720px, 94vw);
  max-width: 720px;
  max-height: 92vh;
  overflow-x: hidden;
  overflow-y: auto;
  /* No bottom padding: the footer (last child) is flush to the bottom so its dark strip reaches
     the modal edge with no gap; the footer adds its own balanced inner padding (260617-2ey).
     No TOP padding either: the sticky #deal-header owns its top padding so it pins flush with no
     gap above (260618-u67). */
  padding: 0 32px 0;
  border-radius: var(--radius-modal);
  box-shadow: var(--shadow-modal);
  animation: modal-slide-up 220ms cubic-bezier(0.32, 0, 0.21, 1) both;
}

/* Tighter padding on phones (detail only — form already uses 24px) */
@media (max-width: 768px) {
  dialog.modal-detail > article { padding: 0 24px 0; }
}

/* Nested section cards align flush within the detail modal card */
dialog.modal-detail > article > section { margin-left: 0; margin-right: 0; }

/* Inner detail cards fill the full modal width (no descendant-leak since the
   generic 560px rule is removed; explicit 100% for clarity). */
dialog.modal-detail > article > section,
dialog.modal-detail > article > section > article {
  width: 100%;
  max-width: 100%;
}

/* Long titles / values never overflow the detail modal bounds */
dialog.modal-detail > article :is(h1, h2, h3, p, dt, dd) { overflow-wrap: anywhere; }

/* Modal header carries only the × close button — strip PicoCSS's sectioning
   divider + shaded background so no horizontal line sits under/behind the
   button (both light and dark themes). Button position is unchanged. */
dialog.modal-detail > article > header {
  border-bottom: none;
  background: transparent;
}

/* ── Edit modal sticky header (260618-u67) ──────────────────────────────── */
/* Pinned «Редактировать сделку #N» + × row inside the form modal.
   article already scrolls (overflow-y:auto + max-height:90vh). Negative
   horizontal margins cancel the article's 24px padding so the opaque bg
   reaches edge-to-edge (no content peeks at the sides when scrolling). */
dialog.modal-form > article > header {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--pico-card-background-color);
  /* article padding-top moved onto the header + zeroed on the article → sticky top:0 pins flush,
     no padding band above for content to peek through (260618-u67). */
  margin-left: -24px;
  margin-right: -24px;
  padding-top: 24px;
  padding-left: 24px;
  padding-right: 24px;
  padding-bottom: 8px;
  box-shadow: none;
}

/* ── Compact form internals — modal-form (add/edit deal + widget settings) ── */
dialog.modal-form :is(input, select, textarea) {
  padding: 8px 12px;
  font-size: 14px;
  height: auto;            /* defeat PicoCSS computed min-height — size to padding */
  margin-bottom: 10px;     /* tighter vertical rhythm than PicoCSS --pico-spacing */
}
/* Keep the amount+currency row flush — re-assert zero margin at modal-form
   specificity (the broad rule above outranks the base .amount-currency-row rule). */
dialog.modal-form .amount-currency-row :is(input, select) {
  margin-bottom: 0;
}

/* То же самое для .password-field (Task 8a, часть 3): без переассерта
   dialog.modal-form :is(input, ...) { margin-bottom: 10px } (специфичность
   0,1,2) перебивает .password-field input { margin-bottom: 0 } (0,1,1). */
dialog.modal-form .password-field input {
  margin-bottom: 0;
}

/* Datepicker display: zero the modal-form input margin-bottom so the .datepicker wrapper
   hugs the input — otherwise the 10px margin inflates the wrapper and the absolutely-
   centered (top:50%) calendar icon sits ~5px below the input's centre. Row rhythm is kept
   by the sibling field + grid gap (same approach as the amount-currency-row carve-out). */
dialog.modal-form .datepicker__display {
  margin-bottom: 0;
}

/* Подписи полей — тот же голос, что .bank-kpi__label и подписи логина:
   капс, мелко, muted (унификация окон занесения, 2026-08-04).
   #wal-op-form — единственная форма занесения ВНЕ dialog.modal-form
   (инлайн в детальной модалке платёжки), включена адресно. */
dialog.modal-form label,
#wal-op-form label {
  font-size: 11px;
  font-weight: 650;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 6px;
}
/* Подпись-предложение у чекбокса/свитча — обычный регистр: капс для
   целой фразы («дошло сразу — подтвердить…») кричит и хуже читается. */
dialog.modal-form label:has(input[type="checkbox"]) {
  text-transform: none;
  letter-spacing: normal;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-primary);
}

dialog.modal-form fieldset { margin-bottom: 12px; }

dialog.modal-form legend { font-size: 13px; }

/* Footer: compact, right-aligned — NOT full-width flex:1/flex:2 */
dialog.modal-form .form-actions {
  justify-content: flex-end;
  gap: 8px;
  margin-top: 16px;
}

/* Сабмит — градиентный зелёный, как login-btn--primary (один визуальный
   язык у всех окон занесения; плоский --pico-primary-background остаётся
   для сабмитов вне модалок). */
dialog.modal-form .form-actions button[type="submit"],
#wal-op-form .form-actions button[type="submit"] {
  color: #fff;
  border: 0;
  font-weight: 600;
  background: linear-gradient(180deg, var(--accent-hover), var(--accent));
  box-shadow:
    0 2px 8px rgba(0, 0, 0, .22),
    0 4px 14px rgba(81, 184, 110, .22),
    inset 0 1px 0 rgba(255, 255, 255, .16);
}
dialog.modal-form .form-actions button[type="submit"]:hover,
#wal-op-form .form-actions button[type="submit"]:hover {
  background: linear-gradient(180deg, #7fd29a, var(--accent-hover));
}

/* width:auto is REQUIRED — PicoCSS defaults buttons to width:100%; with flex-basis
   auto + flex-shrink:0 both buttons would resolve to 100% and overflow the modal
   (the secondary spills off the LEFT edge under justify-content:flex-end). The
   codebase convention (.add-deal-btn / .plan-fact-save / .widget-edit-actions)
   always sets width:auto to defeat this — the prior 260613-ppn footer rule omitted it. */
dialog.modal-form .form-actions .secondary,
dialog.modal-form .form-actions button[type="submit"] {
  flex: 0 0 auto;
  width: auto;
  padding: 8px 20px;
}

/* ── `.modal-form--canon` opt-in canon (quick 260721-k7s) ───────────────────
   Modifier class added to the bug-report + event dialogs ONLY (alongside the
   shared `modal modal-form`). Deal form + subscription form do NOT carry
   this class, so their 52px fields / pill-radius footer / Pico-huge title
   stay exactly as before. Every rule below is additive/scoped — never edit
   the base .deal-form-* / .form-actions / .deal-*-pill declarations above. */

/* Title: 19px/500 (base <h2> is Pico-huge). Broadened (quick 260722-j5g) from
   `.modal-form--canon > article > header h2` to `dialog.modal-form > article
   > header h2` — one DRY source for ALL modal-form titles, incl. the bell
   («Обновления») dialog which is `modal modal-form releases-modal` with no
   canon class. Specificity (0,1,4) still beats Pico's bare `h2` (0,0,1). */
dialog.modal-form > article > header h2 {
  font-size: 19px;
  font-weight: 500;
  margin: 0;
  line-height: 1.3;
}

/* Fields: 38px (base 52px). Input + select are SEPARATE rules so the
   select's chevron padding-right survives — a combined `padding:8px 12px`
   shorthand would reset padding-right back to 12px and collapse the
   chevron's reserved space regardless of source order. */
.modal-form--canon .deal-form-input {
  height: 38px;
  padding: 8px 12px;
}
.modal-form--canon .deal-form-select {
  height: 38px;
  padding: 8px 12px;
  padding-right: 32px;
}

/* Textarea: sized 56–84px (not the fixed 52px input height), resizable */
.modal-form--canon textarea.deal-form-input {
  height: auto;
  min-height: 56px;
  max-height: 84px;
  padding: 8px 12px;
  resize: vertical;
}

/* Footer: hairline divider + r11 pills (base footer has no divider; base
   pills are full-pill r999 — cancel stays ghost, submit stays solid blue). */
.modal-form--canon .form-actions {
  border-top: 1px solid var(--hairline);
  padding-top: 14px;
}
.modal-form--canon .deal-cancel-pill,
.modal-form--canon .deal-submit-pill {
  border-radius: 11px;
}

/* ── Global: remove Pico's valid-state green ✓ on our text inputs/textareas
   (CONTEXT item 4, quick 260721-k7s — user explicitly asked for this ONE
   rule to apply everywhere, unlike the rest of the canon above). Scoped to
   `.deal-form-input` only — `.deal-form-select`'s chevron background-image
   and the readonly `.datepicker__display` are untouched. Pico's own valid-
   icon rule is `:where(input,select,textarea):not([type=...])[aria-invalid=
   false]:not(select)` — specificity (0,2,1), tied with the selector below;
   theme.css loads after vendor pico-2.min.css so source order breaks the
   tie in our favor. The aria-invalid="true" icon is already suppressed
   separately at .deal-form-input[aria-invalid="true"] above. */
input.deal-form-input:not([aria-invalid="true"]),
textarea.deal-form-input:not([aria-invalid="true"]) {
  background-image: none;
}

/* ── `.modal-form--canon` deal-form overrides (quick 260721-wd2) ────────────
   Deal new/edit modals now carry `.modal-form--canon` (mirroring bug/event).
   Every rule below is additive/scoped under `.modal-form--canon` — the base
   `.deal-form-*` block (~5556-5913) and the k7s canon block above are left
   untouched, so no other `.deal-form-*` consumer (e.g. subscriptions modal)
   is affected.

   Specificity note: base `input.deal-form-input`/`select.deal-form-select`
   pin `height:52px; min-height:52px` at (0,1,1), and
   `.deal-form-amount-row .deal-form-input`/`.deal-form-currency` pin 52px at
   (0,2,0). The k7s canon `.deal-form-input{height:38}` above is (0,2,0) and
   sets height but NOT min-height, so the base min-height:52 would still win
   and clamp fields back to 52px. The element-qualified, min-height-inclusive
   selectors below are (0,2,1)/(0,3,0) — they outrank both base rules. */

/* Fields to 38px (beats the (0,1,1) element rule + resets min-height). */
.modal-form--canon input.deal-form-input,
.modal-form--canon select.deal-form-select {
  height: 38px;
  min-height: 38px;
}

/* Price amount-row children to 38px (beats the (0,2,0) amount-row rule). */
.modal-form--canon .deal-form-amount-row .deal-form-input,
.modal-form--canon .deal-form-amount-row .deal-form-currency {
  height: 38px;
  min-height: 38px;
}

/* Currency box narrowed to 64px (mock) — base is 84px. */
.modal-form--canon .deal-form-amount-row .deal-form-currency {
  width: 64px;
}

/* Маржа: thin 32px inset strip (mock) — overrides the base 52px/--surface-row
   strip. Live-state classes (--positive/--negative) are separate classes and
   stay equally/more specific, so a working pre-calc still tints the strip. */
.modal-form--canon .deal-margin-preview {
  min-height: 32px;
  height: 32px;
  padding: 0 12px;
  background: var(--surface-inset);
  border-radius: 10px;
  font-size: 12px;
}

/* Модель row: compact 28×16 switch toggles (mock; global .settings-switch on
   /settings stays 34×18 — scoped under .deal-form-mode-toggles only). The
   flex wrapper for each switch+label pair is new markup (260721-wd2), not
   part of the legacy .deal-form-own-stock-toggle system, so it needs its own
   minimal layout rule. Gap tightened for one-line fit. */
.modal-form--canon .deal-form-mode-toggles {
  gap: 14px;
}
.modal-form--canon .deal-form-switch-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--text-3);
}
/* Generalized (quick 260722-j5g) from `.deal-form-mode-toggles`-scoped rules to
   ALL canon form toggles — event «Весь день» (base .settings-switch, 34×18)
   now inherits the same 28×16/12 geometry. Root cause of the "ползунок смещён
   вниз" misalignment: .settings-switch is a <label>, and `dialog.modal-form
   label { margin-bottom: 8px }` gives it an asymmetric bottom margin that
   rides the track off the label's midline under align-items:center — the
   margin-bottom:0 reset below kills that Pico-label-default leak. */
.modal-form--canon .settings-switch {
  margin-bottom: 0;
}
.modal-form--canon .settings-switch__track {
  width: 28px;
  height: 16px;
}
.modal-form--canon .settings-switch__knob {
  width: 12px;
  height: 12px;
}
.modal-form--canon .settings-switch input:checked + .settings-switch__track .settings-switch__knob {
  transform: translateX(12px);
}

/* Modal open animation — sheet feel (slight translateY + opacity) */
@keyframes modal-slide-up {
  from {
    opacity: 0;
    transform: translateY(12px) scale(0.97);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* ── Typography: 2-weight system ─────────────────────────────────────────── */
h2, h3 {
  font-weight: 700;
}

/* ── Deal detail header row ──────────────────────────────────────────────── */
.deal-header-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
  align-items: end;
  margin-bottom: 8px;
}
.deal-header-row label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 14px;
  margin-bottom: 0;
}

/* ── Computed header values (margin, cycle) ──────────────────────────────── */
.deal-header-computed {
  display: flex;
  gap: 24px;
  flex-wrap: wrap;
  margin-top: 8px;
}
.deal-header-computed dt {
  font-size: 14px;
  color: var(--pico-muted-color);
  margin-bottom: 0;
}
.deal-header-computed dd {
  font-weight: 700;
  margin-bottom: 0;
  margin-left: 0;
}

/* ── Facts definition list ───────────────────────────────────────────────── */
.deal-facts-dl {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 12px;
  row-gap: 4px;
  margin-bottom: 0;
}
.deal-facts-dl dt {
  color: var(--pico-muted-color);
  font-size: 14px;
  margin-bottom: 0;
  /* auto label column + nowrap: keep 'Дата начала' horizontal — never let the
     inherited overflow-wrap:anywhere collapse the label to one char per line */
  white-space: nowrap;
}
.deal-facts-dl dd {
  margin: 0;
  /* long values (e.g. '10.0000 USD (Курс неизвестен — ₽ недоступно)') wrap cleanly */
  overflow-wrap: anywhere;
}
@media (min-width: 768px) {
  .deal-facts-dl {
    grid-template-columns: auto minmax(0, 1fr) auto minmax(0, 1fr);
    column-gap: 24px;
  }
}

/* ── Comments timeline ────────────────────────────────────────────────────── */
.comment-list {
  list-style: none;
  padding: 0;
  margin: 0 0 16px 0;
}
.comment-entry {
  border-bottom: 1px solid var(--pico-table-border-color, var(--text-4));
  padding: 8px 0;
}
.comment-entry:last-child {
  border-bottom: none;
}
.comment-timestamp {
  display: block;
  font-size: 14px;
  color: var(--pico-muted-color);
  margin-bottom: 4px;
}

/* ── Attachment chips row ─────────────────────────────────────────────────── */
.attachment-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 16px;
}
.attachment-chips .chip {
  text-decoration: none;
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── HTMX loading — disable double-submit ────────────────────────────────── */
#deal-header.htmx-request select,
#comments-section.htmx-request button,
#attachments-section.htmx-request button {
  opacity: 0.6;
  pointer-events: none;
}

/* ── Deal action footer (Edit + Delete) ──────────────────────────────────── */
.deal-actions {
  display: flex;
  justify-content: space-between;
  padding: 24px 32px;
  border-top: 1px solid var(--pico-muted-border-color);
  gap: 16px;
}

/* Destructive (delete) button — red outline, transparent bg */
.destructive {
  color: var(--pico-del-color, var(--c-red-4));
  border-color: currentColor;
  background: transparent;
}

.destructive:hover {
  background: color-mix(in srgb, var(--pico-del-color, var(--c-red-4)) 12%, transparent);
}

@media (max-width: 640px) {
  .deal-actions {
    flex-direction: column-reverse;
  }
  .deal-actions button {
    width: 100%;
  }
}

/* ── Deals list table (dashboard) ─────────────────────────────────────────── */
/* All rules scoped under .deals-list — no leaks to nested tables (CONVENTIONS) */
.deals-list {
  width: 100%;
  table-layout: fixed;
}

.deals-list th,
.deals-list td {
  padding: 6px 10px;
  font-size: 13px;
  line-height: 1.3;
  white-space: nowrap;
  /* Subtle vertical separator so adjacent money columns never read as merged. */
  border-right: 1px solid color-mix(in srgb, var(--pico-muted-border-color) 50%, transparent);
}

/* All column headers centered — uniform header row regardless of each column's
   cell alignment (cells keep their own align: text left, numbers/status center). */
.deals-list thead th {
  text-align: center;
}

/* Columns (10): 1 № · 2 Дата · 3 Объект · 4 Кол-во · 5 Закуп · 6 Реализация
   · 7 Маржа · 8 Покупатель · 9 Оплата · 10 Статус. */

/* Last column (Статус) — no trailing separator. */
.deals-list th:nth-child(10),
.deals-list td:nth-child(10) {
  border-right: none;
}

/* Ellipsis truncation applies ONLY to the two flexible text columns' data
   cells (Объект col 3, Покупатель col 8) — never to headers (always full),
   money/qty/date/№ cells (always full), or status-chip badges (semantic).
   Each truncating cell carries title="full". */
.deals-list td:nth-child(3),
.deals-list td:nth-child(8) {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* col 1: № — deal id; 70px, centered, muted, tabular digits for a clean column */
.deals-list th:nth-child(1),
.deals-list td:nth-child(1) {
  width: 70px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  color: var(--pico-muted-color);
}

/* col 2: Дата — 130px so the DD.MM.YYYY value ('11.06.2026') fully clears Объект
   (narrows to 100px on mobile, below). */
.deals-list th:nth-child(2),
.deals-list td:nth-child(2) {
  width: 130px;
}

/* col 3: Объект — flexible ellipsis column */
.deals-list th:nth-child(3),
.deals-list td:nth-child(3) {
  width: auto;
}

/* col 4: Кол-во — centered */
.deals-list th:nth-child(4),
.deals-list td:nth-child(4) {
  width: 90px;
  text-align: center;
}

/* col 5: Закуп — money, centered */
.deals-list th:nth-child(5),
.deals-list td:nth-child(5) {
  width: 140px;
  text-align: center;
}

/* col 6: Реализация */
.deals-list th:nth-child(6),
.deals-list td:nth-child(6) {
  width: 140px;
  text-align: center;
}

/* col 7: Маржа */
.deals-list th:nth-child(7),
.deals-list td:nth-child(7) {
  width: 140px;
  text-align: center;
}

/* col 8: Покупатель — flexible ellipsis column */
.deals-list th:nth-child(8),
.deals-list td:nth-child(8) {
  width: auto;
}

/* col 9: Оплата — payment-progress mini bar; compact fixed width (260621). */
.deals-list th:nth-child(9),
.deals-list td:nth-child(9) {
  width: 96px;
  text-align: center;
}

/* col 10: Статус — 180px so the inline <select> fits the longest label
   ('Ждёт оплаты') without truncation; centered, no ellipsis. */
.deals-list th:nth-child(10),
.deals-list td:nth-child(10) {
  width: 180px;
  text-align: center;
}

/* Inline status editor (col 10): centre the status pill in the column — pills form a
   tidy vertical column, not pinned left/right (260614-1mf). */
.status-cell {
  text-align: center;
  vertical-align: middle;
}
.status-chip-select {
  margin: 0 auto;   /* belt-and-suspenders centring alongside the cell text-align */
}
.status-cell .status-badge {
  cursor: pointer;
}

.status-inline-select {
  font-size: 13px;
  padding: 4px 28px 4px 8px; /* right padding clears unified chevron; left/vertical kept compact */
  width: 100%;               /* fill the 180px cell so the label isn't truncated */
  border-radius: var(--radius-button);
  border: 1px solid var(--pico-muted-border-color);
  background: var(--pico-card-background-color);
  color: var(--pico-color);
}

@media (max-width: 1024px) {
  .deals-list th,
  .deals-list td {
    padding: 5px 6px;
    font-size: 12px;
  }
}

@media (max-width: 768px) {
  /* Hide Объект (col 3) and Покупатель (col 8) on narrow screens */
  .deals-list th:nth-child(3),
  .deals-list td:nth-child(3),
  .deals-list th:nth-child(8),
  .deals-list td:nth-child(8) {
    display: none;
  }

  /* Дата (col 2) back to 100px on mobile — smaller font still fits '10.06.2026'. */
  .deals-list th:nth-child(2),
  .deals-list td:nth-child(2) {
    width: 100px;
  }
}

/* ── «Оплата» payment-progress column (260621) ───────────────────────────── */
/* Header reads white like every other column header — no accent override. The
   column is monochrome white; the bar alone carries the threshold colour. The
   .pay-col-head class is kept as a hook but sets no colour. */

/* Bar + percent label sit on one baseline. The track is a fixed-width rounded
   pill; the fill width is data-driven (the one allowed inline style="width:N%").
   Fill colour is a SOLID band by threshold — NOT a gradient. */
.pay-cell {
  text-align: center;
  vertical-align: middle;
}
.pay-wrap {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.pay-track {
  display: inline-block;
  width: 46px;
  height: 6px;
  border-radius: 999px;
  background: var(--wa-07);
  overflow: hidden;
  vertical-align: middle;
}
.pay-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
}
.pay-fill--red {
  background: var(--c-red);
}
.pay-fill--amber {
  background: var(--c-amber);
}
.pay-fill--green {
  background: var(--c-green);
}
.pay-label {
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  /* White percent text — only the BAR carries the threshold colour (260621). */
  color: var(--text-2);
}
.pay-label--muted {
  color: var(--wa-40);
}
.pay-dash {
  color: var(--wa-40);
}

/* ── Bar chart (D-3: server-rendered, no JS/canvas) ──────────────────────── */
/* Pure CSS flex bars. Width is data-driven via inline style="width: N%"      */
/* (the ONE allowed inline style — data percentage cannot be expressed in      */
/* a static CSS class). All tokens reuse the existing accent / status system. */

.bar-chart {
  width: 100%;
}

.bar-chart__title {
  font-size: 14px;
  font-weight: 600;
  color: var(--pico-muted-color);
  margin-bottom: 8px;
  margin-top: 0;
}

.bar-chart__empty {
  color: var(--pico-muted-color);
  font-size: 14px;
  padding: 8px 0;
  margin: 0;
}

.bar-chart__row {
  display: grid;
  /* FIXED label/value columns (shared tokens with .monthly-breakdown li) so the
     track left+right edges align across every row regardless of label length —
     auto would size to each row's text and break cross-row alignment. */
  grid-template-columns: var(--bar-label-col) minmax(0, 1fr) var(--bar-value-col);
  align-items: center;
  gap: 10px;
  padding: 5px 0;
  white-space: nowrap;
}

.bar-chart__label {
  font-size: 13px;
  color: var(--pico-muted-color);
  white-space: nowrap;   /* see CLAUDE.md CSS convention: label column = auto + nowrap */
  min-width: 0;
}

.bar-chart__track {
  background: color-mix(in srgb, var(--pico-muted-border-color, var(--text-4)) 60%, transparent);
  border-radius: 4px;
  height: 10px;
  overflow: hidden;
  width: 100%;
}

.bar-chart__fill {
  display: block;
  height: 100%;
  border-radius: 4px;
  background: var(--accent, var(--c-blue-2));
  /* No transition: prefers-reduced-motion respected by omitting animation entirely */
}

.bar-chart__fill--negative {
  background: var(--status-refunded, var(--c-red-2));  /* reuse the danger-red status token */
}

.bar-chart__value {
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  text-align: right;
  min-width: 0;
}

/* Dark theme — track color is naturally adaptive via pico-muted-border-color;
   fill colors use the design-system tokens which already have dark overrides. */

@media (max-width: 480px) {
  /* Collapse label column on very narrow screens — bars still read correctly */
  .bar-chart__row {
    grid-template-columns: minmax(0, 1fr) auto;
  }
  .bar-chart__label {
    display: none;
  }
}

/* Hover brighten on bar row */
.bar-chart__row:hover .bar-chart__fill {
  filter: brightness(1.12);
  transition: filter var(--transition-fast);
}

@media (prefers-reduced-motion: reduce) {
  .bar-chart__row:hover .bar-chart__fill {
    transition: none;
  }
}


/* =============================================================================
   ANALYTICS PAGE
   Cards, period tabs, channel progress, responsive grid
   ============================================================================= */

/* ── Analytics responsive card grid ─────────────────────────────────────────── */
.analytics-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}

@media (max-width: 768px) {
  .analytics-grid {
    grid-template-columns: 1fr;
  }
}

/* ── Metric card surface ─────────────────────────────────────────────────────── */
.metric-card {
  background: var(--pico-card-background-color);
  border-radius: var(--radius-card);
  padding: 20px;
  border-left: 3px solid transparent;
  transition: box-shadow var(--transition-fast), transform var(--transition-fast);
}

.metric-card:hover {
  box-shadow: var(--shadow-card);
  transform: translateY(-1px);
}

@media (prefers-reduced-motion: reduce) {
  .metric-card:hover {
    transform: none;
  }
}

/* Per-group left accent modifiers.
   NOTE: --pipeline and --cycle classes are legacy (templates removed them in 260616-1et);
   their colored left stripes are neutralized here to uniform border (260618-0q8 audit). */
.metric-card--pipeline {
  border: 1px solid var(--wa-08);  /* neutralized from status-awaiting_payment accent */
  border-radius: 16px;
}
.metric-card--money    {
  /* No status left-accent — uniform card border on all sides, like the other blocks.
     The `border` shorthand resets the base .metric-card `border-left:3px solid transparent`. */
  border: 1px solid var(--wa-08);
  border-radius: 16px;
}
.metric-card--channels {
  border: 1px solid var(--wa-08);
  border-radius: 16px;
  background: var(--surface-card);
}
.metric-card--cycle    {
  border: 1px solid var(--wa-08);  /* neutralized from status-pending accent */
  border-radius: 16px;
}

/* ── «Скорость капитала» card — mirrors .metric-card--money / --operations uniform border ── */
.metric-card--velocity {
  background: var(--surface-card);
  border: 1px solid var(--wa-08);
  border-left: 1px solid var(--wa-08);  /* override base 3px left-accent */
  border-radius: 16px;
  padding: 20px 22px;
}

/* No-data muted note */
.velocity-no-data {
  font-size: 14px;
  color: var(--text-muted);
  margin: 0;
}

/* Trend chart section */
.velocity-trend-section {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--wa-07);
}

.velocity-trend-title {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
  margin: 0 0 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Bar chart row: columns flex-equal, bars aligned to bottom */
.velocity-trend {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 48px;
}

.velocity-trend__col {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  height: 100%;
  gap: 4px;
}

/* Bar wraps the full available height so height% on bar works correctly */
.velocity-trend__bar-wrap {
  flex: 1;
  width: 100%;
  display: flex;
  align-items: flex-end;
}

.velocity-trend__bar {
  width: 100%;
  background: var(--c-blue);
  border-radius: 3px 3px 0 0;
  min-height: 2px;
  transition: height 0.2s ease;
}

.velocity-trend__bar--empty {
  width: 100%;
  height: 2px;
  background: var(--wa-08);
  border-radius: 1px;
}

.velocity-trend__label {
  font-size: 10px;
  color: var(--text-muted);
  white-space: nowrap;
  line-height: 1;
}

/* ── Compact «Операции» card — exact approved mockup (4+2 tiles + scrollable footer) ──
   Fixed dark palette per the approved design — intentionally NOT theme-adaptive: this is
   the owner's signed-off look. The card is neutral (no status left-accent), tiles carry
   their own surface, and the longest-open rows are plain text (no Pico role=button blue). */

/* Neutral card — overrides the base .metric-card left-accent for the operations block. */
.metric-card--operations {
  background: var(--surface-card);
  border: 1px solid var(--wa-08);
  border-left: 1px solid var(--wa-08);  /* kill the 3px status accent */
  border-radius: 16px;
  padding: 20px 22px;
}

/* Objects analytics card — mirrors .metric-card--operations */
.metric-card--objects {
  background: var(--surface-card);
  border: 1px solid var(--wa-08);
  border-left: 1px solid var(--wa-08);  /* kill base 3px accent */
  border-radius: 16px;
  padding: 20px 22px;
}

/* ── «Прогноз» forecast block (ОБЗОР, 260627) — run-rate projection ──────────── */
.metric-card--forecast {
  background: var(--surface-card);
  border: 1px solid var(--wa-08);
  border-radius: 16px;
  padding: 20px 22px;
  /* Narrow + left-aligned — ~half-width, flush to the left of its section (under «Операции»). */
  max-width: 720px;
  margin: 14px auto 0 0;       /* below the top grid; left-flush (right margin auto) */
  -webkit-user-select: none;
  user-select: none;
}
.forecast-hero {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 10px 14px;
  margin: 14px 0 12px;
}
.forecast-hero__value {
  font-size: 26px;
  font-weight: 600;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.forecast-pill {
  font-size: 12px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 999px;
  white-space: nowrap;
}
.forecast-pill--green {
  color: var(--c-green);
  background: color-mix(in srgb, var(--c-green) 14%, transparent);
}
.forecast-pill--amber {
  color: var(--c-amber);
  background: color-mix(in srgb, var(--c-amber) 14%, transparent);
}
/* Projection bar: muted track, solid-green факт + striped-green remainder + white goal tick. */
.forecast-bar {
  position: relative;
  height: 12px;
  border-radius: 999px;
  background: var(--hairline);
  overflow: visible;            /* goal marker sticks out */
  margin: 4px 0 16px;
}
.forecast-bar__fact,
.forecast-bar__proj {
  position: absolute;
  top: 0;
  height: 100%;
  background-clip: padding-box;
}
.forecast-bar__fact {
  left: 0;
  border-radius: 999px 0 0 999px;
  background: var(--c-green);
}
.forecast-bar__proj {
  border-radius: 0 999px 999px 0;
  background: repeating-linear-gradient(
    45deg,
    color-mix(in srgb, var(--c-green) 55%, transparent) 0,
    color-mix(in srgb, var(--c-green) 55%, transparent) 5px,
    color-mix(in srgb, var(--c-green) 22%, transparent) 5px,
    color-mix(in srgb, var(--c-green) 22%, transparent) 10px
  );
}
.forecast-bar__goal {
  position: absolute;
  top: -3px;
  width: 2px;
  height: 18px;
  background: var(--text-2);
  border-radius: 1px;
  transform: translateX(-1px);
}
.forecast-rows {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.forecast-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.forecast-row dt {
  font-size: 13px;
  color: var(--text-1);
}
.forecast-row dd {
  margin: 0;
  font-size: 14px;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.forecast-row__hint {
  font-size: 11px;
  color: var(--text-muted);
}
.forecast-row--total dt,
.forecast-row--total dd {
  font-weight: 600;
  color: var(--text-primary);
  padding-top: 7px;
  border-top: 1px solid var(--wa-07);
}
.forecast-context {
  margin: 14px 0 0;
  font-size: 12px;
  color: var(--text-muted);
}
.forecast-note {
  margin: 14px 0 0;
  font-size: 13px;
  color: var(--text-1);
}

/* ── «Свои vs Брокер» earning-model block (ОБЗОР, 260627) ────────────────────── */
.metric-card--models {
  background: var(--surface-card);
  border: 1px solid var(--wa-08);
  border-radius: 16px;
  padding: 20px 22px;
  /* Same narrow + left-aligned shell as «Прогноз». */
  max-width: 720px;
  margin: 14px auto 0 0;
  -webkit-user-select: none;
  user-select: none;
}
/* Stacked profit-share bar */
.models-bar {
  display: flex;
  height: 12px;
  border-radius: 999px;
  overflow: hidden;
  margin: 14px 0 8px;
  background: var(--hairline);
}
.models-bar__seg {
  height: 100%;
}
.models-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin-bottom: 12px;
}
.models-legend__item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--text-1);
}
.models-dot {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex-shrink: 0;
}
/* Compact table */
.models-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.models-table th,
.models-table td {
  padding: 6px 4px;
  text-align: left;
}
.models-table th.num,
.models-table td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.models-table thead th {
  font-size: 11px;
  font-weight: 500;
  color: var(--text-muted);
  border-bottom: 1px solid var(--wa-07);
}
.models-table td {
  color: var(--text-primary);
  border-bottom: 1px solid var(--surface-row);
}
.models-table td .models-dot {
  margin-right: 7px;
}
.models-table__total td {
  font-weight: 600;
  border-top: 1px solid var(--wa-10);
  border-bottom: none;
  padding-top: 8px;
}
.models-caption {
  margin: 12px 0 0;
  font-size: 12px;
  line-height: 1.4;
  color: var(--text-muted);
}

/* ── «Воронка сделок» deal-funnel block (ОБЗОР, 260627) ──────────────────────── */
.metric-card--funnel {
  background: var(--surface-card);
  border: 1px solid var(--wa-08);
  border-radius: 16px;
  padding: 20px 22px;
  /* Same narrow + left-aligned shell as «Прогноз». */
  max-width: 720px;
  margin: 14px auto 0 0;
  -webkit-user-select: none;
  user-select: none;
}
.funnel-stages {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: 14px 0 4px;
}
.funnel-row {
  display: grid;
  grid-template-columns: 120px 1fr auto;
  align-items: center;
  gap: 10px 12px;
}
.funnel-row__label {
  font-size: 13px;
  color: var(--text-1);
}
.funnel-row__bar {
  height: 12px;
  border-radius: 999px;
  background: var(--surface-tile);
  overflow: hidden;
}
.funnel-row__fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background-clip: padding-box;
}
.funnel-row__count {
  font-size: 13px;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* Drop-off note sits under the bar (spans the bar + count columns). */
.funnel-row__drop {
  grid-column: 2 / -1;
  font-size: 11px;
  margin-top: -4px;
}
.funnel-row__drop--cancelled {
  color: var(--c-red-8);
}
.funnel-row__drop--awaiting {
  color: var(--c-amber);
}
.funnel-divider {
  height: 1px;
  background: var(--wa-07);
  margin: 14px 0;
}
.funnel-rates {
  display: flex;
  gap: 28px;
}
.funnel-rate {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.funnel-rate__value {
  font-size: 22px;
  font-weight: 600;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.funnel-rate__label {
  font-size: 12px;
  color: var(--text-1);
}
.funnel-rate__sub {
  font-size: 11px;
  color: var(--text-muted);
}
.funnel-caption {
  margin: 12px 0 0;
  font-size: 12px;
  line-height: 1.4;
  color: var(--text-muted);
}

/* No text-selection highlight on the non-interactive analytics cards (260627):
   clicking the «Операции» / «Деньги» / «Объекты» card chrome (titles, labels, stat
   tiles, chart text, button-rows) no longer blue-highlights the text. This is purely
   the selection highlight — keyboard focus (:focus-visible rings), the clickable
   «Дольше всего открыты» rows, the intentional chart current-month ring and the
   segmented toggles are unaffected (user-select never touches focus/click). */
.metric-card--operations,
.metric-card--money,
.metric-card--objects {
  -webkit-user-select: none;
  user-select: none;
}

/* Keep the real DATA selectable/copyable: the «Объекты» search field and the
   analytics table values. (The stat tiles and headers stay non-selectable above.) */
.metric-card--objects .obj-analytics-search,
.metric-card--objects .obj-analytics-table {
  -webkit-user-select: text;
  user-select: text;
}

/* Card header: icon + title on one line */
.operations-header {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 16px;
}

/* «?» help badge → top-right corner of the block, vertically centered on the title line
   (flex header pushes it to the far right). Applies to every analytics block. (260619-v7n) */
.operations-header .help-badge-wrap {
  margin-left: auto;
}

.operations-header__icon {
  color: var(--c-blue);
  display: flex;
  align-items: center;
}

.operations-header__title {
  margin: 0;
  font-size: 14px;
  font-weight: 500;
  color: var(--text-1);
}

/* Tile grid rows — the card is a HALF-width widget, so tiles flow 2-up (2×3 total):
   row 1 (4 tiles) wraps to [В работе | Капитал] / [Ждут оплаты | Под риском >30д];
   row 2 (2 tiles) = [Средний цикл | Завершено за месяц]. */
.operations-tiles {
  display: grid;
  gap: 10px;
}

.operations-tiles--four {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.operations-tiles--two {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-top: 10px;
}

/* 6 tiles, 2 columns × 3 rows — ½-width Операции card (quick 260617-an-top) */
.operations-tiles--2x3 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* Individual tile — always a surface, never flat/transparent. */
.operations-tile {
  background: var(--surface-tile);
  border-radius: 12px;
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.operations-tile__label {
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.25;
}

/* Long label (e.g. «Нереализованная прибыль») — slightly smaller so it wraps to two
   lines cleanly inside the tile instead of overflowing (260616-wdn). */
.operations-tile__label--tight {
  font-size: 11px;
}

.operations-tile__value {
  font-size: 22px;
  font-weight: 500;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}

.operations-tile__sub {
  font-size: 13px;
  font-weight: 400;
  color: var(--text-muted);
}

/* Inline formula caption — shown under complex metric values only (HHI, CRn, Pareto,
   turnover, ROIC, CCC). Muted, thin top border to separate from the value. */
.metric-caption {
  font-size: 11px;
  color: var(--text-muted);
  border-top: 1px solid var(--hairline);
  margin-top: 6px;
  padding-top: 5px;
  line-height: 1.3;
}

/* Amber accent — at-risk tile value */
.operations-tile--amber .operations-tile__value {
  color: var(--c-amber);
}

/* Green accent — завершено tile value */
.operations-tile--green .operations-tile__value {
  color: var(--c-green);
}

/* Footer section: divider + label above the scrollable list */
/* ── «Дольше всего открыты» full-width deal table (260616-wnp) ────────────────
   Standalone table (NOT .deals-list — that class carries 10-column nth-child widths
   tuned for the deals-list column order, which differs here). Dark card, horizontal
   scroll on narrow so columns never squish. */
/* «Дольше всего открыты» now lives INSIDE the Операции card, below the tiles (260617-19z):
   a top divider + a muted sub-header, then the table. */
.operations-longest-block {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--wa-07);
}
.operations-longest-subheader {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-3);
}
.operations-longest-subheader__icon {
  display: inline-flex;
  color: var(--text-muted);
}

/* «Дольше всего открыты» — COMPACT LIST (quick 260617-an-top): one row per deal,
   «#id · object» left + days-open right (risk-colored). Scrollable when long. */
.longest-open-list {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  max-height: 232px;            /* ~6 rows; scroll beyond */
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--wa-12) transparent;
}

.longest-open-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 4px;
  cursor: pointer;
  /* Fully defeat Pico's [role="button"] styling (blue fill/border/shadow) in EVERY state —
   * this is a plain list row, not a button. Only a thin bottom separator + hover lighten. */
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--wa-05);
  border-radius: 0;
  box-shadow: none;
  color: inherit;
  font: inherit;
  transition: background-color 120ms ease;
}
.longest-open-row:last-child {
  border-bottom: none;
}
.longest-open-row:hover,
.longest-open-row:focus,
.longest-open-row:focus-visible,
.longest-open-row:active {
  background: var(--surface-row);  /* subtle lighten only — NO blue fill */
  outline: none;
  box-shadow: none;
}

.longest-open-row__label {
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  color: var(--text-6);            /* the «·» separator + fallback */
}
.longest-open-row__id {
  color: var(--text-6);            /* muted «#id» */
}
.longest-open-row__obj {
  color: var(--text-primary);            /* object name */
}

.longest-open-row__days {
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  flex: 0 0 auto;
}
.longest-open-row__days--red {
  color: var(--c-red);
  font-weight: 600;
}
.longest-open-row__days--amber {
  color: var(--c-amber);
  font-weight: 600;
}
.longest-open-row__days--muted {
  color: var(--text-muted);
}

.operations-longest__empty {
  font-size: 13px;
  color: var(--text-muted);
  margin: 6px 0 0;
}

/* ── Key-number typography helpers ───────────────────────────────────────────── */
.metric-card__label {
  font-size: 13px;
  color: var(--pico-muted-color);
  margin: 0 0 2px;
}

.metric-card__value {
  font-size: clamp(28px, 5vw, 38px);
  font-weight: 700;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  margin: 0;
}

/* .metric-card__value.amount-negative inherits global .amount-negative color — no extra rule needed */

.metric-card__sub {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px 16px;
  margin-top: 16px;
}

.metric-card__sub dt,
.submetric-label {
  font-size: 12px;
  color: var(--pico-muted-color);
  margin: 0;
}

.submetric-value {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* ── Period toggle (sticky tab strip) ────────────────────────────────────────── */
/* Re-uses existing .chip / .chip-active styles for the pills themselves.
   Only the container rule lives here. */
.period-toggle {
  display: flex;
  gap: 6px;
  position: sticky;
  top: 0;
  z-index: 5;
  padding: 10px 0;
  background: var(--pico-background-color, var(--text-2));
  margin-bottom: 16px;
}

/* ── Channel progress rows (Spotify "top artists" style) ─────────────────────── */
/* label column: max-content + nowrap per CLAUDE.md CSS convention */
.channel-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.channel-row {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr) max-content;
  align-items: center;
  gap: 12px;
}

.channel-row__name {
  font-size: 14px;
  white-space: nowrap;
}

.channel-row__track {
  background: color-mix(in srgb, var(--pico-muted-border-color) 60%, transparent);
  border-radius: var(--radius-pill);
  height: 10px;
  overflow: hidden;
}

.channel-row__fill {
  height: 100%;
  border-radius: var(--radius-pill);
  background: var(--accent);
}

.channel-row__fill--negative {
  background: var(--status-refunded);
}

.channel-row__value {
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  text-align: right;
}

/* ═══════════════════════════════════════════════════════════════════════════════
   SIDEBAR NAVIGATION LAYOUT (260612-t7p)
   Appended after existing rules — DO NOT modify rules above this block.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* ── Sidebar shell ───────────────────────────────────────────────────────────── */
.sidebar {
  position: fixed;
  inset: 0 auto 0 0;
  width: 232px;
  padding: 16px 14px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--bg-sidebar);
  border-right: 1px solid var(--wa-07);
  z-index: 900;
}

/* ── Header: «f» mark + «fin» wordmark + collapse toggle (260617-0jg) ───────── */
.sidebar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 10px;
}
.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.sidebar-logo-mark {
  position: relative;        /* anchors the hover chevron overlay + tooltip (260617-16i) */
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  padding: 0;
  margin: 0;
  border: none;
  border-radius: 9px;
  /* Dark navy square (matches favicon.svg's bg rect) so the atom's blue orbits read. */
  background: var(--surface-26);
  color: var(--text-2);
  font-weight: 700;
  font-size: 18px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: box-shadow var(--transition-fast);
}
/* Atom mark + hover «›» overlay share the centre; only one is visible at a time.
   The mark fills the button with a small inset so the orbits clear the corners. */
.sidebar-logo-mark__f {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  padding: 3px;
  box-sizing: border-box;
  transition: opacity var(--transition-fast);
}
.sidebar-logo-mark__f svg {
  display: block;
  width: 100%;
  height: 100%;
}
.sidebar-logo-mark__chevron {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;                /* hidden until collapsed + hover/focus */
  transition: opacity var(--transition-fast);
}
.sidebar-logo-mark__chevron svg {
  transform: rotate(180deg); /* chevron-left → chevron-right «›» */
}
.sidebar-logo-word {
  font-size: 20px;
  font-weight: 700;
  color: var(--text-primary);
  letter-spacing: 0.01em;
}
.sidebar-collapse-btn {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  margin: 0;
  border-radius: 9px;
  background: var(--surface-tile);
  border: 1px solid var(--wa-08);
  color: var(--text-1);
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.sidebar-collapse-btn:hover {
  background: var(--surface-8);
  color: var(--text-primary);
}

/* ── Nav items ───────────────────────────────────────────────────────────────── */
/* Label width: auto/max-content + white-space:nowrap per CLAUDE.md CSS convention #1 */
.nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 12px;
  border-radius: 11px;
  color: var(--text-1);
  text-decoration: none;
  white-space: nowrap;
  /* Compositor-friendly transition (no 'all' — web perf rule) */
  transition: background var(--transition-fast), color var(--transition-fast);
}

.nav-item:hover {
  background: var(--surface-row);
  color: var(--text-primary);
}

.nav-item.active {
  background: var(--c-blue-a14);
  color: var(--c-blue-4);
  font-weight: 600;
}
.nav-item.active .nav-icon {
  color: var(--c-blue-4);
}
/* 3px rounded blue accent bar on the LEFT edge of the active item (both states). */
.nav-item.active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 20px;
  border-radius: 0 3px 3px 0;
  background: var(--c-blue);
}

/* ── Disabled nav item (Анализ — coming soon) ───────────────────────────────── */
.nav-item-disabled {
  opacity: .55;
  pointer-events: none;
  cursor: default;
}

/* ── «soon» badge (expanded) ────────────────────────────────────────────────── */
.nav-badge {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.03em;
  padding: 2px 7px;
  border-radius: var(--radius-pill);
  background: var(--wa-08);
  color: var(--text-1);
  margin-left: auto;
}

/* ── «soon» dot (collapsed only) — top-right of the icon ─────────────────────── */
.nav-dot {
  display: none;
  position: absolute;
  top: -2px;
  right: -3px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--c-blue);
}

/* ── Bell unseen-dot («Колокольчик обновлений») — shows in the EXPANDED
   sidebar too, unlike the base .nav-dot above (collapsed-only). Server
   controls visibility via the `is-unseen` class (GET /releases/unseen). ── */
.nav-dot--bell {
  display: none;
}
.nav-dot--bell.is-unseen {
  display: block;
}

/* ── Footer: theme toggle + logout (separated by a top border) ──────────────── */
.sidebar-footer {
  margin-top: auto;
  padding-top: 10px;
  border-top: 1px solid var(--wa-07);
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.sidebar-logout-form {
  margin: 0;
}
/* Theme + logout reuse .nav-item layout but are <button> — reset native button chrome. */
.sidebar-action {
  width: 100%;
  font: inherit;
  text-align: left;
  background: none;
  border: none;
  cursor: pointer;
}
.sidebar-action--danger,
.sidebar-action--danger .nav-icon {
  color: var(--c-red);
}
.sidebar-action--danger:hover {
  background: var(--c-red-a10-2);
  color: var(--c-red);
}
/* Compact footer utility rows (Тема/Выйти) — expanded only; collapsed tiles + nav above unchanged. */
.sidebar:not(.collapsed) .sidebar-footer { gap: 2px; }
.sidebar:not(.collapsed) .sidebar-action { padding: 7px 12px; }
.sidebar:not(.collapsed) .sidebar-action .nav-icon svg { width: 16px; height: 16px; }
.sidebar:not(.collapsed) .sidebar-action .nav-label { font-size: 13px; }

/* ── Language toggle (RU/EN) — sidebar footer segmented pill, same rhythm as
   .seg-pills (transparent track, solid-blue active pill). The row reuses
   .nav-item's flex layout for footer alignment; the two buttons are native
   <button>s, so Pico's default margin-bottom must be zeroed or the flex row
   inflates ~16px (CLAUDE.md CSS convention). ── */
.lang-switch {
  gap: 6px;
}
.lang-switch__btn {
  flex: 1;
  margin: 0; /* Pico default margin-bottom guard — native <button> in a custom row */
  min-height: 26px;
  padding: 0 10px;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .02em;
  border: 1px solid var(--wa-08);
  border-radius: 999px;
  background: var(--surface-tile);
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast),
              border-color var(--transition-fast);
}
.lang-switch__btn:hover:not(.is-active) {
  background: var(--c-blue-a10);
  border-color: var(--c-blue-a35);
}
.lang-switch__btn.is-active {
  background: var(--c-blue);
  border-color: var(--c-blue);
  color: var(--text-2);
}
/* Focus ring only for keyboard nav (:focus-visible) — no ring on a mouse click. */
.lang-switch__btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--c-blue-a35);
}
.lang-switch__btn:focus:not(:focus-visible) {
  outline: none;
  box-shadow: none;
}
.sidebar:not(.collapsed) .lang-switch__btn { min-height: 22px; font-size: 11px; }

/* ── Main content area: offset by sidebar width ─────────────────────────────── */
.main-content {
  margin-left: 232px;
  padding: 32px 40px;
}
/* Редизайн (вариант B, решение владельца 2026-08-04): контент не размазывается
   на всю ширину монитора — внутренний контейнер по центру. */
.main-content > * {
  max-width: 1280px;
  margin-left: auto;
  margin-right: auto;
}
/* Фон и на html, не только на body: Pico задаёт html'у собственный
   background-color (#13171f), поэтому фон body НЕ распространяется на канвас —
   на коротких страницах под концом body просвечивал навы-синий дефолт Pico
   (шов на «Дропах»). Красим оба слоя нашим зелёно-чёрным. */
html,
body {
  background: #0e1512;
}

/* ── Mobile hamburger button (hidden ≥768px) ─────────────────────────────────── */
.sidebar-toggle {
  display: none;
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 1001;
}

/* ── Responsive: <768px — sidebar off-canvas, hamburger visible ─────────────── */
@media (max-width: 767px) {
  .sidebar {
    transform: translateX(-100%);
    transition: transform var(--transition-fast);
    z-index: 1000;
    box-shadow: var(--shadow-modal);
  }

  .sidebar.open {
    transform: translateX(0);
  }

  .main-content {
    margin-left: 0;
    padding: 16px;
  }

  .sidebar-toggle {
    display: inline-flex;
  }
}

/* =============================================================================
   SIDEBAR COLLAPSE + TOOLTIPS + LOGO-TOGGLE (260612-v3z)
   Appended after existing rules — DO NOT modify rules above this block.
   ============================================================================= */

/* ── Sidebar width transition ───────────────────────────────────────────────── */
.sidebar {
  transition: width 200ms ease, padding 200ms ease;
}

/* ── Nav icon ───────────────────────────────────────────────────────────────── */
.nav-icon {
  position: relative;            /* anchor for the «soon» .nav-dot */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: inherit;
}
.sidebar-collapse-icon {
  display: inline-flex;
  align-items: center;
  transition: transform 200ms ease;
}
/* chevron-left → chevron-right (collapsed) via rotation */
.sidebar.collapsed .sidebar-collapse-icon svg {
  transform: rotate(180deg);
}

/* ════════════════════ COLLAPSED STATE (72px icon rail) ════════════════════ */
.sidebar.collapsed {
  width: 72px;
  padding: 16px 14px;
}
.sidebar.collapsed + .main-content,
body:has(.sidebar.collapsed) .main-content {
  margin-left: 72px;
}

/* Hide all text/label elements (CRITICAL: «Выйти» label gone → no two-line wrap) */
.sidebar.collapsed .nav-label,
.sidebar.collapsed .nav-badge,
.sidebar.collapsed .sidebar-logo-word {
  display: none;
}

/* Header → centred column (mark on top, toggle below) */
.sidebar.collapsed .sidebar-header {
  flex-direction: column;
  justify-content: center;
  gap: 10px;
}

/* Collapsed: the «f» mark IS the expand control; the standalone chevron tile is removed (260617-16i). */
.sidebar.collapsed .sidebar-collapse-btn {
  display: none;
}
.sidebar.collapsed .sidebar-logo-mark {
  width: 40px;
  height: 40px;
  border-radius: 11px;
  font-size: 22px;
}
/* Hover/focus → swap «f» for «›» + blue focus ring → signals «click to expand». */
.sidebar.collapsed .sidebar-logo-mark:hover,
.sidebar.collapsed .sidebar-logo-mark:focus-visible {
  box-shadow: 0 0 0 3px var(--c-blue-a25);
  outline: none;
}
.sidebar.collapsed .sidebar-logo-mark:hover .sidebar-logo-mark__f,
.sidebar.collapsed .sidebar-logo-mark:focus-visible .sidebar-logo-mark__f {
  opacity: 0;
}
.sidebar.collapsed .sidebar-logo-mark:hover .sidebar-logo-mark__chevron,
.sidebar.collapsed .sidebar-logo-mark:focus-visible .sidebar-logo-mark__chevron {
  opacity: 1;
}

/* Every actionable item → 44×44 centred icon tile, radius 12 */
.sidebar.collapsed .nav-item {
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  margin: 0 auto;
  border-radius: 12px;
}
/* Active item keeps the blue tint; the left accent bar stays pinned to the tile's left edge */
.sidebar.collapsed .nav-item.active::before {
  left: -14px;                   /* reach to the rail edge (cancels the 14px padding) */
}

/* .lang-switch holds TWO buttons, not one icon — the blanket 44×44 icon-tile rule above
   doesn't fit it. Let it size to content instead (same source-order position so it wins
   the equal-specificity cascade over the rule immediately above). */
.sidebar.collapsed .lang-switch {
  width: auto;
  height: auto;
  padding: 3px;
  gap: 3px;
  border-radius: 10px;
}
.sidebar.collapsed .lang-switch__btn {
  padding: 4px 5px;
  font-size: 9px;
}

/* «soon» dot visible only when collapsed (the pill is hidden) */
.sidebar.collapsed .nav-dot {
  display: block;
}

/* Bell dot stays state-driven even when collapsed — override the blanket
   "show any .nav-dot when collapsed" rule above (same specificity, later
   wins) so the unseen-releases indicator doesn't always show collapsed. */
.sidebar.collapsed .nav-dot--bell {
  display: none;
}
.sidebar.collapsed .nav-dot--bell.is-unseen {
  display: block;
}

/* ── Collapsed tooltip (CSS ::after + data-label) — every .nav-item incl. footer + logo mark ── */
.sidebar.collapsed .nav-item:hover::after,
.sidebar.collapsed .sidebar-logo-mark:hover::after,
.sidebar.collapsed .sidebar-logo-mark:focus-visible::after {
  content: attr(data-label);
  position: absolute;
  left: calc(100% + 12px);
  top: 50%;
  transform: translateY(-50%);
  white-space: nowrap;
  background: var(--surface-8);
  color: var(--text-primary);
  border: 1px solid var(--wa-10);
  padding: 5px 10px;
  border-radius: 8px;
  box-shadow: var(--shadow-modal);
  z-index: 1100;
  pointer-events: none;
  font-weight: 400;
  font-size: 13px;
}

/* =============================================================================
   Period picker — unified Год + Месяц two-dropdown period selector
   260612-vtg: replaces the month select (dashboard) and period chip toggle (/analytics)
   Selects inherit the unified select rule from theme.css; only layout added here.
   ============================================================================= */

.period-picker {
  display: inline-flex;
  gap: 8px;
  align-items: center;
}

.period-picker select {
  min-width: 130px;
}

.period-picker select:disabled {
  opacity: .5;
  cursor: not-allowed;
}

/* ── G2 cumulative profit line (analytics, Task 4) ─────────────────────── */
/* Pure Jinja transform of g2_monthly_usd — no router change; theme-aware via var(). */
.g2-cumline-title {
  margin-top: 1rem;
  margin-bottom: .25rem;
  font-size: .85em;
  opacity: .7;
}

.g2-cumline {
  display: block;
  width: 100%;
  height: 120px;
  overflow: visible;
  margin-bottom: .25rem;
}

.g2-cumline__line {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Per-point dot rule is now unused (replaced by single endpoint dot) — kept for safety */
.g2-cumline__dot {
  fill: var(--accent);
}

/* Single endpoint dot at last cumulative point */
.g2-cumline__endpoint-dot {
  fill: var(--accent);
  stroke: none;
}

/* Subtle area fill under the cumulative line */
.g2-cumline__area {
  stroke: none;
}

.g2-cumline-labels {
  display: flex;
  justify-content: space-between;
  font-size: .7em;
  opacity: .6;
  margin-bottom: .125rem;
}

.g2-cumline-label {
  flex: 1;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
}

.g2-cumline-endpoint {
  font-size: .85em;
  text-align: right;
  margin: 0;
}

/* ── Burn-up sparkline (plan/fact widget, Task 3) ──────────────────────── */
/* No <script>/<canvas>. Theme-aware via CSS var(). vector-effect="non-scaling-stroke"
   on polylines/lines in SVG ensures 2px stays 2px regardless of preserveAspectRatio=none. */
.burnup-spark {
  display: block;
  width: 100%;
  height: 48px;
  overflow: visible;
  margin-top: .5rem;
  /* color: drives the fill gradient stop-color via currentColor */
  color: var(--status-completed);
}

/* Actual cumulative line — green (at/above pace) */
/* Actual (Факт) line — fixed orange, stroke-only (260613-* legend scheme).
   fill:none with !important so an open <polyline> never fills its implied
   closed region — and so no modifier can re-introduce a fill (the prior
   --behind rule set fill:amber here, which CSS applied over the inline
   fill="none" and produced the persistent orange band). */
.burnup-spark .spark-actual {
  fill: none !important;
  stroke: var(--status-awaiting_payment);  /* orange = Факт */
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Pace reference line (Темп к цели) — green dashed, stroke-only */
.burnup-spark .spark-pace {
  fill: none !important;
  stroke: var(--status-completed);  /* green = темп к цели */
  stroke-width: 1.5;
  stroke-dasharray: 3 3;
  opacity: .7;
}

/* Today vertical marker — dashed */
.burnup-spark .spark-today {
  stroke: var(--muted, currentColor);
  stroke-width: 1;
  stroke-dasharray: 3 3;
  opacity: .6;
}

/* Today marker label — small muted, under the marker on the x-axis row */
.burnup-today-label {
  position: absolute;
  transform: translateX(-50%);
  bottom: -2px;
  font-size: 10px;
  color: var(--pico-muted-color);
  white-space: nowrap;
}

/* Burn-up legend — orange solid = Факт, green dashed = Темп к цели */
.burnup-legend {
  display: flex;
  gap: 16px;
  align-items: center;
  margin-top: 8px;
  font-size: 11px;
  color: var(--pico-muted-color);
}
.burnup-legend__item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.burnup-legend__swatch { flex-shrink: 0; overflow: visible; }
.burnup-legend__line--actual {
  stroke: var(--status-awaiting_payment);
  stroke-width: 2;
  stroke-linecap: round;
}
.burnup-legend__line--pace {
  stroke: var(--status-completed);
  stroke-width: 1.5;
  stroke-linecap: round;
}

/* ── Chart axis + gridline helpers (cumulative widget) ───────────────────────
   Used by templates/widgets/_cumulative.html.
   .chart-with-axis: flex row (Y-axis gutter | SVG).
   .chart-y-axis: left gutter with positioned tick labels.
   .chart-y-tick: individual label, absolutely positioned by top%.
   .chart-gridline: horizontal 1px gridline inside SVG (rendered before data).
   .chart-axis-line: 1px x-axis baseline inside SVG at the zero tick.
   ─────────────────────────────────────────────────────────────────────────── */

.chart-with-axis {
  display: flex;
  align-items: stretch;
  gap: 0;
}

.chart-y-axis {
  position: relative;
  width: var(--chart-y-gutter);
  flex-shrink: 0;
  /* ticks are absolutely positioned inside this gutter */
}

.chart-y-tick {
  position: absolute;
  left: 0;
  right: auto;   /* left-hugging — labels next to the card edge, not mid-gutter */
  font-size: 11px;
  color: var(--pico-muted-color);
  white-space: nowrap;
  transform: translateY(-50%);
  line-height: 1;
}

.chart-gridline {
  stroke: color-mix(in srgb, var(--pico-muted-border-color) 40%, transparent);
  stroke-width: 1;
  fill: none;
}

.chart-axis-line {
  stroke: var(--pico-muted-border-color, var(--nx-10-a30));
  stroke-width: 1;
  fill: none;
}

/* G2 cumulative line fills the remaining width after the Y-axis gutter */
.g2-cumline {
  flex: 1;
  width: 100%;
}

/* ── Sparkline reference gridlines (plan-fact widget) ────────────────────── */
/* Horizontal 1px gridlines at each Y tick, rendered behind data lines. */

.burnup-spark .spark-gridline {
  stroke: color-mix(in srgb, var(--pico-muted-border-color) 35%, transparent);
  stroke-width: 1px;
  fill: none;
}

/* ── Burn-up chart layout: Y-axis column + SVG (260613-mpw) ─────────────── */

/* Outer container: flex row, position:relative so absolute fact-label works */
.burnup-chart {
  position: relative;
  display: flex;
  align-items: stretch;
  margin-top: .5rem;
  max-height: 140px;
}

/* Y-axis label column — sits LEFT of the SVG. Narrow gutter so the SVG uses
   the full remaining card width (no big empty band on the left). */
.burnup-yaxis {
  position: relative;
  width: var(--chart-y-gutter);
  flex: 0 0 auto;
}

/* Individual Y-axis tick label: positioned by top% of chart height.
   Left-hugging (left:0, not right:4px) so labels sit next to the card edge
   instead of floating mid-gutter with a wide empty band to their left. */
.burnup-ytick {
  position: absolute;
  left: 0;
  right: auto;
  transform: translateY(-50%);
  font-size: 11px;
  color: var(--pico-muted-color);
  white-space: nowrap;
  line-height: 1;
}

/* SVG fills the remaining width after Y-axis gutter */
.burnup-chart .burnup-spark {
  flex: 1;
  width: 100%;
  height: 100%;
  min-height: 80px;
  max-height: 140px;
  margin-top: 0;  /* override the default .burnup-spark margin-top: .5rem */
}

/* X-axis day labels row below the chart area */
.burnup-xaxis {
  position: relative;
  height: 1.2em;
  margin-left: var(--chart-y-gutter);  /* align with the SVG area (skip Y-axis gutter) */
  margin-top: 2px;
}

/* Individual X-axis day label: centered on its x_coord% */
.burnup-xtick {
  position: absolute;
  transform: translateX(-50%);
  font-size: 11px;
  color: var(--pico-muted-color);
  white-space: nowrap;
  line-height: 1;
}

/* Fact end-label: muted value near the actual line end */
.burnup-fact-label {
  position: absolute;
  /* left/top set inline via style= in template */
  transform: translate(-105%, -130%);
  font-size: 11px;
  color: var(--pico-muted-color);
  white-space: nowrap;
  pointer-events: none;
  /* Offset to land ABOVE and LEFT of the actual line endpoint */
  margin-left: var(--chart-y-gutter);  /* account for Y-axis gutter so % is relative to SVG area */
}

/* «настроить цель» button — right-aligned in .widget-header flex row (260613-ppn Fix A) */
.plan-fact-edit-btn {
  padding: 4px 10px;
  font-size: 12px;
  border-radius: var(--radius-pill, 999px);
  margin: 0;
  margin-left: auto;
  flex-shrink: 0;
  white-space: nowrap;
}

/* ── Add-deal button — compact, size-to-content (260613-ppn Fix B) ─────────── */
/* ── Header actions row: Refresh (LEFT) + Add-deal (RIGHT) ──────────────────
   justify-content:space-between places refresh on the left, add-deal on the right.
   align-items:stretch → refresh square auto-matches the add button's native height.
   margin:0 reset kills PicoCSS's default button margin-bottom offset.
   260616-kb1: add-deal moved to RIGHT; refresh stays LEFT. */
.header-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.header-actions > * {
  margin: 0;
}
.header-actions__right {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* ── Add-deal button — blue #22e754 pill (260616-kb1) ──────────────────────
   Blue fill, white text, radius 10, ~40px height, soft shadow, hover lighter/raised.
   Compositor-safe transitions (background, transform, box-shadow — no layout props). */
/* `a.add-deal-btn` (0,1,1) ties + beats Pico `a[role=button]{display:inline-block}` (0,1,1) by
   load order — a bare `.add-deal-btn` (0,1,0) LOST, so the button stayed inline-block and the
   block-level '+' SVG wrapped onto its own line (icon stacked above text). 260616-w96. */
a.add-deal-btn {
  display: inline-flex;
  flex-direction: row;  /* icon + label are inline siblings on ONE row, never stacked */
  align-items: center;
  justify-content: center;
  text-align: center;   /* defeat Pico [role=button] text-align:left so content is truly centered */
  gap: 7px;
  background: var(--c-blue);
  color: var(--text-2);
  border: none;
  border-radius: 10px;
  min-height: 44px;
  height: 44px;
  padding: 0 18px;      /* symmetric — no vertical bias */
  font-size: 14px;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  box-shadow: 0 4px 14px var(--c-blue-a35);
  text-decoration: none;
  cursor: pointer;
  transition: background var(--transition-fast),
              transform var(--transition-fast),
              box-shadow var(--transition-fast);
  box-sizing: border-box;
  width: auto;
}
/* '+' icon is a flex child: blockified, no inline descender gap, no baseline push (260616-vr3) */
.add-deal-btn svg {
  display: block;
  flex-shrink: 0;
}
.add-deal-btn:hover {
  background: var(--c-blue-18);
  transform: translateY(-1px);
  box-shadow: 0 6px 20px var(--c-blue-a45-2);
  color: var(--text-2);
  text-decoration: none;
}
.add-deal-btn:active {
  transform: translateY(0);
  box-shadow: 0 4px 14px var(--c-blue-a35);
}

/* ── Refresh button — 44×44 icon tile matching the gear (260616-uyn) ──────── */
.refresh-btn {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;          /* icon centered */
  justify-content: center;
  padding: 0;                   /* icon-only — size from width/height, not padding */
  margin: 0;
  box-sizing: border-box;
  border-radius: 10px;
  background: var(--surface-tile);
  border: 1px solid var(--wa-08);
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast),
              border-color var(--transition-fast);
}
.refresh-btn:hover {
  background: var(--surface-2);
  border-color: var(--wa-16);
  color: var(--text-primary);
}
.refresh-btn svg { display: block; }

/* Spin while the request is in flight — htmx adds .htmx-request to the button. */
.refresh-btn.htmx-request {
  pointer-events: none;         /* disable repeat-click during the request */
  color: var(--accent);
}
.refresh-btn.htmx-request svg {
  animation: refresh-spin 0.8s linear infinite;
}
@keyframes refresh-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* ── Compact inline goal-edit form (260613-*) ─────────────────────────────── */
/* Goal-edit panel sizes to the button row's natural width (260616-ni1): the form is a
   max-content wrapper, the actions grid (auto 1fr columns) defines that width, and the
   input stretches to 100% of it → input width == button-row width. Not full-widget, not centered. */
.plan-fact-form {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
  margin-top: 10px;
  width: max-content;
  max-width: 100%;   /* never overflow on narrow screens */
}
.plan-fact-label {
  display: block;
  width: 100%;
  font-size: 13px;
  color: var(--pico-muted-color);
  margin: 0;
}
/* input.plan-fact-input (0,1,1) ties + beats Pico's tall
   `input:not([type=checkbox],[type=radio],[type=range]){height:calc(...)}` (also 0,1,1) by load
   order — without this, Pico's ~50px+ height + 0.75rem vertical padding override a plain
   `.plan-fact-input` (0,1,0) and the input renders double-height (260616-q8x). */
input.plan-fact-input {
  width: 100%;
  box-sizing: border-box;
  height: 46px;            /* compact single line, matches the 46px buttons */
  min-height: 0;           /* defeat any inherited min-height */
  padding: 0 14px;         /* explicit height owns the box; trim Pico's vertical padding */
  line-height: normal;
  font-size: 16px;
  margin: 4px 0 0;
  border-radius: 11px;
}
.plan-fact-form-actions {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;  /* equal columns, each sized to the widest button (Сбросить (авто)) */
  gap: 12px;
}
/* Equal-width, equal-height (46px), centered action buttons (260616-ni1). */
.plan-fact-save,
.plan-fact-reset,
.plan-fact-cancel {
  min-width: 0;
  height: 46px;
  margin: 0;
  padding: 0 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: 14px;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  border-radius: 10px;
  border: 1px solid transparent;
  cursor: pointer;
}
/* Primary — Сохранить */
.plan-fact-save {
  background: var(--c-blue);
  border-color: var(--c-blue);
  color: var(--text-2);
}
.plan-fact-save:hover { background: var(--c-blue-7); border-color: var(--c-blue-7); }
/* Secondary — Сбросить (авто) + Отмена */
.plan-fact-reset,
.plan-fact-cancel {
  background: var(--surface-tile);
  border-color: var(--wa-12);
  color: var(--text-3);
}
.plan-fact-reset:hover,
.plan-fact-cancel:hover {
  background: var(--surface-2);
  border-color: var(--wa-20);
}

/* Widget-settings modal footer — compact row, primary+secondary right-aligned */
.widget-edit-actions {
  display: flex;
  flex-direction: row;
  gap: 8px;
  justify-content: flex-end;
}
.widget-edit-actions button {
  width: auto;
  margin: 0;
  font-size: 14px;
  padding: 8px 20px;
}

/* ── Widget card system ───────────────────────────────────────────────────── */

.widget-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));
  gap: 16px;
  margin-top: 16px;
}

@media (max-width: 768px) {
  .widget-grid {
    grid-template-columns: 1fr;
  }
}

/* Wide analytics blocks (money, monthly, objects) span the full grid row.
   On mobile the grid is already 1-col so no extra rule needed there. */
.widget-grid__wide {
  grid-column: 1 / -1;
}

/* Analytics grid — EXACTLY 2 equal columns (50/50), scoped so the shared dashboard
   .widget-grid (auto-fill) is untouched. Non-wide blocks fill exactly one 50% column;
   widget-grid__wide + widget-grid__group blocks span both via grid-column: 1/-1.
   align-items:stretch keeps paired half-width blocks even height. (260616-38f, 260618-0q8) */
.widget-grid--analytics {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  align-items: stretch;
}

@media (max-width: 900px) {
  .widget-grid--analytics {
    grid-template-columns: 1fr;
  }
}

/* Full-width cells inside the analytics grid */
.widget-grid__wide,
.widget-grid__group {
  grid-column: 1 / -1;
}

/* Section group labels inside the analytics widget grid */
.widget-grid__group {
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  /* Explicit section divider: a visible rule + generous space above each band (260619-v7n). */
  margin-top: 28px;
  padding-top: 16px;
  border-top: 1px solid var(--wa-10);
}

/* «ОБЗОР» label above the .analytics-top pinned section */
.analytics-group-label {
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-top: 28px;
  padding-top: 16px;
  border-top: 1px solid var(--wa-10);
  margin-bottom: 8px;
}

/* Top section (quick 260617-an-top): 2 equal columns — LEFT = Операции (tiles + longest-open
   list), RIGHT = reserved/empty. Single column below 900px (matches analytics grid breakpoint). */
.analytics-top {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  align-items: start;
  margin-bottom: 14px;
}
@media (max-width: 900px) {
  .analytics-top {
    grid-template-columns: 1fr;
  }
}

/* Reserved right column — subtle empty-state card awaiting a future widget. */
.analytics-reserved {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 160px;
  padding: 24px;
  background: var(--surface-card);
  border: 1px dashed var(--wa-12);
  border-radius: 16px;
}
.analytics-reserved__hint {
  margin: 0;
  max-width: 240px;
  text-align: center;
  font-size: 13px;
  color: var(--text-muted);
}
/* Hide the reserved placeholder on mobile (single column) — no value stacked alone. */
@media (max-width: 900px) {
  .analytics-top__right {
    display: none;
  }
}

.widget {
  border-radius: var(--radius-card, 16px);
  padding: 20px 24px;
  background: var(--pico-card-background-color, var(--text-2));
  border: 1px solid var(--pico-muted-border-color, var(--nx-4-a15));
  box-shadow: var(--shadow-card, 0 1px 4px var(--sc-08));
  overflow: hidden;
}

.widget-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}

.widget-header svg {
  color: var(--pico-muted-color);
  flex-shrink: 0;
}

.widget-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--pico-muted-color);
  margin: 0;
}

.widget-hero-number {
  font-size: 28px;
  font-weight: 700;
  line-height: 1.1;
}

.widget-footnote {
  font-size: 13px;
  color: var(--pico-muted-color);
  margin-top: 8px;
}

.widget-line {
  display: flex;
  flex-wrap: nowrap;
  align-items: baseline;
  gap: 6px;
  white-space: nowrap;
  margin: 4px 0;
  font-size: 14px;
}

.widget-line-label {
  color: var(--pico-muted-color);
  flex-shrink: 0;
  white-space: nowrap;
}

/* ── Widget subtitle — muted period label below the title ───────────────── */
.widget-subtitle {
  display: block;
  font-size: 12px;
  color: var(--pico-muted-color);
  font-weight: 400;
  margin-top: 1px;
}

/* ── Totals widget — vertical column layout (260613-ort) ─────────────────
   3 groups (Реализовано / В работе / Убытки) each with 3 stacked value rows.
   label column: auto + nowrap (CLAUDE.md); value column: flex-end right-aligned.
   ─────────────────────────────────────────────────────────────────────────── */
.totals-group-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 8px 0;
  padding: 0;
}

.totals-group {
  border-left: 2px solid var(--pico-muted-border-color, var(--nx-3-a20));
  padding-left: 10px;
}

.totals-group__label {
  font-size: 13px;
  color: var(--pico-muted-color);
  font-weight: 600;
  margin-bottom: 4px;
  white-space: nowrap;
}

.totals-group__rows {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
}

/* Each row: label (auto, nowrap) | right-aligned value */
.totals-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
}

.totals-row__key {
  font-size: 13px;
  color: var(--pico-muted-color);
  white-space: nowrap;   /* CLAUDE.md: label uses nowrap, NOT min-content */
  flex-shrink: 0;
}

.totals-row__val {
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

/* Monthly breakdown bars inside widget card — same tokens, 8px radius */
.widget .monthly-breakdown .mb-track {
  border-radius: 8px;
}

.widget .monthly-breakdown .mb-fill {
  border-radius: 8px;
}

/* ── Widget settings (gear) button — now in top bar (260616-uyn) ────────── */
.widget-edit-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 44px;
  padding: 0 16px;
  font-size: 14px;
  border-radius: 10px;
  border: 1px solid var(--wa-08);
  background: var(--surface-tile);
  color: var(--text-muted);
  cursor: pointer;
  box-sizing: border-box;
  white-space: nowrap;
  transition: background var(--transition-fast), border-color var(--transition-fast),
              color var(--transition-fast);
  margin-bottom: 0;             /* was 12px when in widget grid — not needed in top bar */
}

.widget-edit-btn svg {
  display: block;               /* no baseline offset from inline SVG */
}

.widget-edit-btn:hover {
  background: var(--surface-2);
  border-color: var(--wa-16);
  color: var(--text-primary);
}

/* ── Widget edit modal rows ──────────────────────────────────────────────── */
.widget-edit-list {
  list-style: none;
  padding: 0;
  margin: 0 0 16px 0;
}

.widget-edit-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 0;
  border-bottom: 1px solid var(--pico-muted-border-color);
}

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

.widget-edit-row label {
  flex: 1;
  margin-bottom: 0;
  cursor: pointer;
}

.widget-reorder-btn {
  background: none;
  border: none;
  padding: 4px 6px;
  cursor: pointer;
  color: var(--pico-muted-color);
  border-radius: 6px;
}

.widget-reorder-btn:hover {
  background: var(--pico-muted-border-color);
  color: var(--pico-color);
}

/* ── Pipeline widget ─────────────────────────────────────────────────────── */
.pipeline-stat-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 6px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--pico-muted-border-color) 50%, transparent);
  font-size: 14px;
}

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

.pipeline-stat-label {
  color: var(--pico-muted-color);
}

/* ── Top channels widget ─────────────────────────────────────────────────── */
.top-channel-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
  font-size: 14px;
}

.top-channel-label {
  min-width: 80px;
  white-space: nowrap;
  color: var(--pico-muted-color);
}

.top-channel-bar-track {
  flex: 1;
  height: 6px;
  border-radius: 3px;
  background: var(--pico-muted-border-color, var(--nx-4-a15));
  overflow: hidden;
}

.top-channel-bar-fill {
  height: 100%;
  border-radius: 3px;
  background: color-mix(in srgb, var(--accent) 40%, transparent);
}

.top-channel-value {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ── Interactive chart hover overlay (260613-nsm) ───────────────────────── */
/* Progressive enhancement: these rules are additive. Static charts read
   fine without JS. All overlay elements carry aria-hidden="true".         */

/* Vertical crosshair line inside SVG (rendered inside the overlay <g>) */
.chart-crosshair {
  stroke: var(--pico-muted-border-color, var(--nx-9-a50));
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}

/* Tooltip card — floats above everything, theme-aware via Pico card vars */
.chart-tooltip {
  position: absolute;
  z-index: 1000;
  display: none;                /* shown by JS via style.display = 'block' */
  padding: 8px 12px;
  border-radius: 10px;
  background: var(--pico-card-background-color, var(--text-2));
  border: 1px solid var(--pico-card-border-color, var(--nx-3-a20));
  box-shadow: 0 4px 16px var(--sc-14), 0 1px 4px var(--sc-08);
  font-size: 13px;
  line-height: 1.5;
  pointer-events: none;
  white-space: nowrap;
  min-width: 140px;
}

/* Tooltip title (point label: date or month) */
.chart-tooltip__label {
  font-weight: 600;
  margin-bottom: 4px;
  color: var(--pico-color, inherit);
}

/* One row per series */
.chart-tooltip__row {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--pico-color, inherit);
}

/* Colour swatch — 10px square, rounded */
.chart-tooltip__swatch {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  flex-shrink: 0;
}

/* Delta row (Отставание / Опережение) — colour set inline by JS */
.chart-tooltip__delta {
  margin-top: 4px;
  font-size: 12px;
  font-weight: 600;
}

/* =============================================================================
   DEAL SEARCH BAR (260613-qki)
   Compact search bar below status chips; focus-preserving sub-region targeting.
   ============================================================================= */

/* ── Search bar container ──────────────────────────────────────────────────── */
.deal-search {
  position: relative;
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 8px 0 12px;
  /* Defeat Pico's [role=search] input-GROUP focus ring: it sets box-shadow via these vars
     and the form is width:100%, so the ring spans the full row (reads as a long line on the
     right). Overriding the vars to transparent beats Pico's high-specificity :has() rule
     without !important; the focus ring then belongs to the input only (global input:focus). */
  --pico-group-box-shadow: 0 0 0 transparent;
  --pico-group-box-shadow-focus-with-input: 0 0 0 transparent;
  --pico-group-box-shadow-focus-with-button: 0 0 0 transparent;
}

/* Magnifier icon — inset left, muted, non-interactive */
.deal-search > svg {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--pico-muted-color);
  pointer-events: none;
  flex-shrink: 0;
  width: 16px;
  height: 16px;
}

/* Search input: left padding makes room for the inset icon; right padding
   leaves space for the ✕ flex sibling (clear button is NOT overlaid, so
   padding-right does not need to match its width — just a comfortable gap). */
.deal-search input[type="search"] {
  /* icon at left:14px + 16px wide ends ~30px; 48px padding → ~18px clear gap before text */
  padding-left: 48px;
  padding-right: 10px;
  padding-top: 8px;
  padding-bottom: 8px;
  font-size: 14px;
  width: 100%;
  max-width: 420px;
  margin-bottom: 0;
  height: auto;
  appearance: none;
  -webkit-appearance: none;
}

/* Hide the native WebKit search chrome — redundant with the custom .deal-search__clear ✕. */
.deal-search input[type="search"]::-webkit-search-cancel-button,
.deal-search input[type="search"]::-webkit-search-decoration,
.deal-search input[type="search"]::-webkit-search-results-button,
.deal-search input[type="search"]::-webkit-search-results-decoration {
  -webkit-appearance: none;
  appearance: none;
  display: none;
}

/* Clear ✕ button — small, muted, width:auto defeats PicoCSS full-width default */
.deal-search__clear {
  width: auto;
  padding: 5px 10px;
  font-size: 13px;
  background: transparent;
  border: 1px solid var(--pico-muted-border-color);
  border-radius: var(--radius-button);
  color: var(--pico-muted-color);
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
  margin: 0;
  flex-shrink: 0;
}

.deal-search__clear:hover {
  background: color-mix(in srgb, var(--pico-muted-color) 12%, transparent);
  color: var(--pico-color);
}

/* ── Pagination ────────────────────────────────────────────────────────────── */

/* Count / info line above the table */
.pagination__info {
  font-size: 13px;
  color: var(--pico-muted-color);
  margin: 0 0 6px;
}

/* Pagination nav row */
.pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 4px;
  margin-top: 12px;
}

/* Shared base for all pagination buttons */
.pagination__page,
.pagination__prev,
.pagination__next {
  width: auto;            /* defeat PicoCSS full-width button default */
  min-width: 32px;
  padding: 4px 8px;
  font-size: 13px;
  line-height: 1.4;
  background: transparent;
  border: 1px solid var(--pico-muted-border-color);
  border-radius: var(--radius-button);
  color: var(--pico-color);
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast),
              border-color var(--transition-fast);
  margin: 0;
}

.pagination__page:hover:not(:disabled),
.pagination__prev:hover:not(:disabled),
.pagination__next:hover:not(:disabled) {
  background: color-mix(in srgb, var(--pico-muted-color) 10%, transparent);
  border-color: var(--pico-muted-color);
}

/* Active page — filled accent */
.pagination__page--active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--text-2);
  font-weight: 600;
  cursor: default;
  pointer-events: none;
}

/* Disabled prev/next */
.pagination__prev:disabled,
.pagination__next:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Ellipsis gap */
.pagination__gap {
  font-size: 13px;
  color: var(--pico-muted-color);
  padding: 4px 2px;
  user-select: none;
}

/* =============================================================================
   OBJECTS STATS TABLE — «Статистика по объектам» (260613-w4n)
   Full-width section below the analytics grid; sticky header; compact rows.
   ============================================================================= */

/* Section wrapper — full width outside the analytics grid */
.obj-stats-section {
  margin-top: 24px;
}

.obj-stats-section > article {
  padding: var(--pico-card-sectioning-block-padding, 16px);
}

.obj-stats-subtitle {
  font-size: 13px;
  color: var(--pico-muted-color);
  margin-top: 4px;
  margin-bottom: 12px;
}

.obj-stats-empty {
  font-size: 14px;
  color: var(--pico-muted-color);
  margin: 8px 0;
}

/* Scrollable wrapper with sticky header — mirrors #deals-table-wrapper */
.obj-stats-wrapper {
  max-height: 60vh;
  overflow-y: auto;
  overflow-x: auto;
  border: 1px solid var(--pico-table-border-color, var(--text-4));
  border-radius: 4px;
}

/* Compact table */
.obj-stats-table {
  border-collapse: collapse;
  width: 100%;
  font-size: 13px;
}

/* Sticky header — mirrors #deals-table-wrapper thead th */
.obj-stats-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--pico-card-background-color, var(--text-7));
  font-weight: 600;
  white-space: nowrap;
  padding: 8px 10px;
  box-shadow: inset 0 -1px 0 var(--pico-table-border-color, var(--text-4));
}

/* Body cells: compact + no wrapping */
.obj-stats-table tbody td {
  padding: 6px 10px;
  white-space: nowrap;
  border-top: 1px solid var(--pico-table-border-color, var(--text-4));
}

/* Subject column — allow long names to truncate */
.obj-stats-subject {
  max-width: 280px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Rank column — muted */
.obj-stats-rank {
  color: var(--pico-muted-color);
  font-size: 12px;
}

/* ── Tier cell tints (avg_profit cell bg) ────────────────────────────────── */
/* Relative-scale tiers: top third green, middle amber, bottom/negative red  */

.obj-tier--high {
  background: color-mix(in srgb, var(--status-completed, var(--c-green-3)) 10%, transparent);
}

.obj-tier--mid {
  background: color-mix(in srgb, var(--status-awaiting_payment, var(--c-amber-3)) 10%, transparent);
}

.obj-tier--low {
  background: color-mix(in srgb, var(--status-cancelled, var(--c-red-2)) 10%, transparent);
}

/* ── Totals row ──────────────────────────────────────────────────────────── */
.obj-stats-total td {
  padding: 8px 10px;
  border-top: 2px solid var(--pico-table-border-color, var(--text-4));
  background: color-mix(in srgb, var(--pico-muted-color, var(--text-22)) 6%, transparent);
  white-space: nowrap;
  font-size: 13px;
}

/* =============================================================================
   Login page — «Аврора» (260723, редизайн)
   Атмосферный фон (дрейфующие блобы + сетка + зерно), стеклянная карточка,
   сегмент-переключатель Войти|Регистрация. Страница вне app-shell — тёмные
   значения локальные, не зависят от data-theme. Кнопки element-qualified
   (button.login-btn), чтобы бить Pico-дефолты [type=submit] по source order.
   ============================================================================= */

.login-viewport {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100dvh;
  padding: 24px 16px;
  overflow-x: hidden;
  background: #0a120d;
  color: #ecf3f0;
  -webkit-font-smoothing: antialiased;
}

/* ── атмосферный фон ── */
.login-aurora {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}
.login-aurora .blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(44px);
  will-change: transform;
}
.login-aurora .blob--1 {
  width: 60vmax; height: 60vmax;
  left: -18vmax; top: -22vmax;
  background: radial-gradient(circle at 40% 40%, rgba(81,184,110,.22), rgba(81,184,110,0) 62%);
  animation: login-drift-a 26s ease-in-out infinite alternate;
}
.login-aurora .blob--2 {
  width: 52vmax; height: 52vmax;
  right: -20vmax; bottom: -18vmax;
  background: radial-gradient(circle at 55% 55%, rgba(52,142,96,.20), rgba(52,142,96,0) 60%);
  animation: login-drift-b 32s ease-in-out infinite alternate;
}
.login-aurora .blob--3 {
  width: 38vmax; height: 38vmax;
  left: 42%; top: 8%;
  background: radial-gradient(circle at 50% 50%, rgba(150,224,178,.10), rgba(150,224,178,0) 65%);
  animation: login-drift-c 22s ease-in-out infinite alternate;
}
@keyframes login-drift-a {
  from { transform: translate3d(0,0,0) scale(1); }
  to   { transform: translate3d(7vmax, 5vmax, 0) scale(1.12); }
}
@keyframes login-drift-b {
  from { transform: translate3d(0,0,0) scale(1.08); }
  to   { transform: translate3d(-6vmax, -4vmax, 0) scale(.96); }
}
@keyframes login-drift-c {
  from { transform: translate3d(0,0,0); opacity: .8; }
  to   { transform: translate3d(-4vmax, 6vmax, 0); opacity: 1; }
}
/* едва заметная сетка под радиальной маской */
.login-aurora::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(146,168,155,.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(146,168,155,.045) 1px, transparent 1px);
  background-size: 44px 44px;
  mask-image: radial-gradient(ellipse 90% 70% at 50% 42%, #000 30%, transparent 78%);
  -webkit-mask-image: radial-gradient(ellipse 90% 70% at 50% 42%, #000 30%, transparent 78%);
}
/* зерно */
.login-aurora::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: .05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

@media (prefers-reduced-motion: reduce) {
  .login-aurora .blob { animation: none; }
  .login-pane { animation: none !important; }
}

/* ── layout ── */
.login-shell {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 400px;
}

/* ── словомарка ── */
.login-brand {
  text-align: center;
  margin-bottom: 28px;
}
.login-wordmark {
  display: inline-block;
  font-size: 52px;
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1;
  background: linear-gradient(120deg, #8fe0ae 0%, #62c983 45%, #45a862 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 6px 24px rgba(81,184,110,.28));
}
.login-tagline {
  margin: 10px 0 0;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #85988f;
}

/* ── стеклянная карточка ── */
.login-glass {
  position: relative;
  border-radius: var(--radius-modal, 20px);
  background: linear-gradient(180deg, rgba(23,37,29,.72), rgba(10,16,12,.66));
  -webkit-backdrop-filter: blur(22px) saturate(140%);
  backdrop-filter: blur(22px) saturate(140%);
  border: 1px solid rgba(146,168,155,.14);
  box-shadow:
    var(--shadow-modal),
    0 1px 4px rgba(0,0,0,.30),
    inset 0 1px 0 rgba(255,255,255,.06);
  padding: 24px 24px 28px;
  overflow: hidden;
}
/* светящаяся кромка сверху + внутренний отсвет */
.login-glass::before {
  content: "";
  position: absolute;
  top: 0; left: 12%; right: 12%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(150,224,178,.55), rgba(81,184,110,.55), transparent);
}
.login-glass::after {
  content: "";
  position: absolute;
  top: -40px; left: 20%; right: 20%;
  height: 80px;
  background: radial-gradient(ellipse at 50% 0%, rgba(81,184,110,.14), transparent 70%);
  pointer-events: none;
}

/* ── сегмент-переключатель ── */
.login-seg {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: rgba(10,18,13,.55);
  border: 1px solid rgba(146,168,155,.10);
  border-radius: var(--radius-pill, 999px);
  padding: 3px;
  margin-bottom: 24px;
}
.login-seg__thumb {
  position: absolute;
  top: 3px; bottom: 3px;
  left: 3px;
  width: calc(50% - 3px);
  border-radius: var(--radius-pill, 999px);
  background: linear-gradient(180deg, #1d3226, #16241c);
  border: 0;
  box-shadow: 0 1px 4px rgba(0,0,0,.30), inset 0 1px 0 rgba(255,255,255,.07);
  transition: transform .28s cubic-bezier(.32,.72,.28,1);
  will-change: transform;
}
.login-seg[data-active="register"] .login-seg__thumb { transform: translateX(100%); }
.login-seg button {
  position: relative;
  z-index: 1;
  appearance: none;
  width: auto;
  margin: 0; /* Pico default margin-bottom guard */
  background: none;
  border: 0;
  border-radius: var(--radius-pill, 999px);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  padding: 9px 0;
  color: #85988f;
  cursor: pointer;
  transition: color .2s ease;
}
.login-seg button[aria-selected="true"],
.login-seg button:hover { color: #ecf3f0; }
.login-seg button:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(81,184,110,.35);
}
.login-seg button:focus:not(:focus-visible) { outline: none; box-shadow: none; }

/* ── RU/EN pre-auth language toggle (login header) — Task 8. Same dark-glass
   palette as .login-seg above (raw rgba/hex — this screen doesn't use the
   app-wide --c-* custom properties), scaled down to a compact pill pair. ── */
.login-lang {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin-top: 12px;
}
.login-lang__btn {
  padding: 4px 11px;
  border-radius: var(--radius-pill, 999px);
  border: 1px solid rgba(146,168,155,.10);
  background: rgba(10,18,13,.55);
  color: #85988f;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .02em;
  text-decoration: none;
  transition: color .2s ease, background .2s ease, border-color .2s ease;
}
.login-lang__btn:hover { color: #ecf3f0; }
.login-lang__btn.is-active {
  background: linear-gradient(180deg, #1d3226, #16241c);
  border-color: rgba(146,168,155,.10);
  color: #ecf3f0;
}
.login-lang__btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(81,184,110,.35);
}
.login-lang__btn:focus:not(:focus-visible) { outline: none; box-shadow: none; }

/* ── панели форм ── */
.login-pane { animation: login-pane-in .32s cubic-bezier(.32,.72,.28,1) both; }
.login-pane[hidden] { display: none; }
@keyframes login-pane-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

.login-field { margin-bottom: 16px; }
.login-field label {
  display: block;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #85988f;
  margin-bottom: 7px;
}
.login-field input {
  width: 100%;
  margin: 0; /* Pico default margin-bottom guard */
  appearance: none;
  font-family: inherit;
  font-size: 16px;
  color: #ecf3f0;
  background: rgba(10,18,13,.60);
  border: 1px solid rgba(146,168,155,.16);
  border-radius: var(--radius-button, 12px);
  padding: 13px 14px;
  transition: border-color .18s ease, box-shadow .18s ease, background-color .18s ease;
}
.login-field input::placeholder { color: rgba(146,168,155,.55); }
.login-field input:hover { border-color: rgba(146,168,155,.30); }
.login-field input:focus {
  outline: none;
  border-color: var(--accent);
  background: rgba(10,18,13,.80);
  box-shadow:
    0 0 0 3px rgba(81,184,110,.22),
    0 0 18px rgba(81,184,110,.18);
}
.login-field .hint {
  margin: 6px 0 0;
  font-size: 12px;
  color: #85988f;
}
.login-field.is-invalid input {
  border-color: #FF453A;
  box-shadow: 0 0 0 3px rgba(255,69,58,.18);
}

/* ── слот ошибки ── */
.login-form-error {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background: rgba(255,69,58,.10);
  border: 1px solid rgba(255,69,58,.35);
  border-radius: var(--radius-button, 12px);
  padding: 11px 13px;
  margin: 0 0 16px;
  font-size: 13.5px;
  line-height: 1.45;
  color: #ffb3ae;
  animation: login-pane-in .28s ease both;
}
.login-form-error[hidden] { display: none; }
.login-form-error svg { flex: none; margin-top: 1px; color: #FF453A; }
.login-form-error strong { color: #ffd2cf; font-weight: 600; }

/* ── кнопки ── */
button.login-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  width: 100%;
  margin: 0; /* Pico default margin-bottom guard */
  appearance: none;
  border: 0;
  border-radius: var(--radius-button, 12px);
  font-family: inherit;
  font-size: 16px;
  font-weight: 600;
  padding: 14px 16px;
  cursor: pointer;
  transition: transform .15s ease, box-shadow .2s ease, background-color .2s ease, border-color .2s ease;
  will-change: transform;
}
button.login-btn:active { transform: scale(.98); }
button.login-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(81,184,110,.40);
}
button.login-btn:focus:not(:focus-visible) { outline: none; }

button.login-btn--primary {
  color: #fff;
  background: linear-gradient(180deg, var(--accent-hover), var(--accent));
  box-shadow:
    0 2px 8px rgba(0,0,0,.22),
    0 4px 18px rgba(81,184,110,.35),
    inset 0 1px 0 rgba(255,255,255,.18);
}
button.login-btn--primary:hover {
  background: linear-gradient(180deg, #7fd29a, var(--accent-hover));
  box-shadow:
    0 2px 8px rgba(0,0,0,.22),
    0 6px 24px rgba(81,184,110,.48),
    inset 0 1px 0 rgba(255,255,255,.20);
}

/* ghost-кнопка биометрии */
button.login-passkey-btn {
  color: #ecf3f0;
  background: rgba(29,50,38,.45);
  border: 1px solid rgba(146,168,155,.16);
}
button.login-passkey-btn:hover {
  background: rgba(29,50,38,.70);
  border-color: rgba(81,184,110,.45);
}
button.login-passkey-btn svg { flex-shrink: 0; color: #8fe0ae; }
button.login-passkey-btn[disabled] { opacity: .6; cursor: default; }

/* разделитель «или» */
.login-divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 18px 0;
  color: #85988f;
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.login-divider::before, .login-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(146,168,155,.22), transparent);
}

/* подвал карточки и страницы */
.login-card-foot {
  margin: 20px 0 0;
  text-align: center;
  font-size: 13px;
  color: #85988f;
}
.login-card-foot .dot {
  display: inline-block;
  width: 6px; height: 6px;
  border-radius: var(--radius-pill, 999px);
  background: #30D158;
  margin-right: 7px;
  vertical-align: 1px;
  box-shadow: 0 0 8px rgba(48,209,88,.6);
}
.login-page-foot {
  margin: 22px 0 0;
  text-align: center;
  font-size: 12px;
  color: rgba(146,168,155,.55);
}

/* ── шаг 2FA (260723) ── */
.login-2fa-lead {
  margin: 0 0 18px;
  font-size: 14px;
  line-height: 1.5;
  color: #85988f;
  text-align: center;
}
.login-code-input {
  text-align: center;
  font-size: 22px;
  font-weight: 600;
  letter-spacing: .30em;
  font-variant-numeric: tabular-nums;
}
.login-code-input::placeholder { letter-spacing: .12em; font-weight: 400; }
.login-back-link {
  color: #85988f;
  text-decoration: none;
  transition: color .15s ease;
}
.login-back-link:hover { color: #ecf3f0; }

/* ── мобильная версия ── */
@media (max-width: 480px) {
  .login-viewport { padding: 20px 14px; align-items: flex-start; }
  .login-shell { max-width: 100%; padding-top: 6vh; }
  .login-wordmark { font-size: 44px; }
  .login-brand { margin-bottom: 22px; }
  .login-glass { padding: 20px 18px 24px; border-radius: var(--radius-card, 16px); }
  /* три блоба с blur — джанк на телефонах; статичный фон достаточен */
  .login-aurora .blob { animation: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   260616-3iw: 4-block analytics redesign
   Money block, Tops block, Objects block
   ═══════════════════════════════════════════════════════════════════ */

/* ── Money block: monthly list ────────────────────────────────────── */

.money-monthly-divider {
  border-top: 1px solid color-mix(in srgb, var(--pico-muted-border-color) 40%, transparent);
  margin: 12px 0 8px;
}

.money-monthly-label {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--pico-muted-color);
  margin: 0 0 8px;
}

.money-monthly-list {
  list-style: none;
  padding: 0;
  margin: 0;
  max-height: 180px;
  overflow-y: auto;
  scrollbar-width: none;
}

.money-monthly-list::-webkit-scrollbar { display: none; }

.money-monthly-row {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr) max-content;
  align-items: center;
  gap: 10px;
  padding: 3px 0;
}

.money-monthly-row__month {
  font-size: 13px;
  white-space: nowrap;
  color: var(--pico-muted-color);
  min-width: 7em;
}

.money-monthly-row__track {
  background: color-mix(in srgb, var(--pico-muted-border-color) 60%, transparent);
  border-radius: var(--radius-pill);
  height: 8px;
  overflow: hidden;
}

.money-monthly-row__fill {
  height: 100%;
  border-radius: var(--radius-pill);
  background: var(--c-blue);
}

.money-monthly-row__fill--negative {
  background: var(--status-refunded, var(--c-red-2));
}

.money-monthly-row__value {
  font-size: 13px;
  white-space: nowrap;
  text-align: right;
}

/* ── Деньги period-adaptive STACKED bar chart (phase 22) ──────────────────────
   Reuses the .plan-fact-chart scaffold (axis | plot | gridlines | bars) + chart-hover.js
   tooltip overlay. Each .money-bar (a .plan-fact-bar, height=revenue%) holds a column-reverse
   stack: Затраты (bottom, dark) + Прибыль (top, green). Loss → dark bar + red top marker. */

/* Bars track — explicit 108px height (matches .plan-fact-axis / .plan-fact-gridlines) so each
   .money-bar's inline height:% (revenue) resolves. Unlike План/Факт (bars wrap a fixed-height
   __track), money bars set height directly, so the FLEX ROW itself must carry the track height. */
.plan-fact-bars.money-bars {
  height: 108px;
  flex: none;                       /* beat .plan-fact-bars{flex:1} so the 108px height holds */
}
/* Each bar: bottom-anchored column whose inline height:% is revenue; stack fills it. */
.money-bar {
  align-self: flex-end;
}
.money-bar__stack {
  width: 62%;                       /* leaves breathing room between buckets (mock spacing) */
  height: 100%;
  display: flex;
  flex-direction: column-reverse;   /* first child (cost) at the bottom, profit above */
  border-radius: 4px 4px 0 0;
  overflow: hidden;
}
.money-bar__seg {
  display: block;
  width: 100%;
  flex-shrink: 0;
}
.money-bar__seg--cost {
  background: var(--surface-7);
}
.money-bar__seg--profit {
  background: var(--c-green);
}
/* Loss bucket: thin red marker pinned to the top of the dark (revenue) bar. */
.money-bar--loss .money-bar__stack {
  position: relative;
  background: var(--surface-7);               /* whole bar dark = revenue */
}
.money-bar__loss-marker {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--c-red);
}
/* Current bucket: subtle ring so it reads as "now". */
.money-bar.is-current .money-bar__stack {
  outline: 1px solid var(--c-blue-a55-3);
  outline-offset: 0;
}

/* Bucket labels — axis-offset flex row mirrors .plan-fact-bars distribution. */
.money-bar-labels {
  display: flex;
  gap: 2px;
  padding-left: 46px;               /* == .plan-fact-axis width, so labels sit under bars */
  margin-top: 6px;
}
.money-bar-label {
  flex: 1;
  min-width: 0;
  text-align: center;
  font-size: 10px;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.money-bar-label.is-current {
  color: var(--text-primary);
  font-weight: 600;
}

/* Legend */
.money-legend {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 12px;
  font-size: 12px;
  color: var(--text-muted);
}
.money-legend__item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.money-legend__swatch {
  width: 11px;
  height: 11px;
  border-radius: 3px;
  flex-shrink: 0;
}
.money-legend__swatch--profit { background: var(--c-green); }
.money-legend__swatch--cost { background: var(--surface-7); }
.money-legend__item--muted { color: var(--surface-1); }

/* ── Tops block: segmented toggle ─────────────────────────────────── */

/* .tops-toggle keeps only layout — the pill look comes from the shared .seg-pills / .seg-pills__btn
   class (260618-vys). The old .tops-segment / --active look rules were removed (now shared). */
.tops-toggle { margin-bottom: 14px; width: fit-content; }

/* ── Tops views: only active one shown ────────────────────────────── */

.tops-view {
  display: none;
}

.tops-view--active {
  display: block;
}

/* ── Tops rows — stacked head + bar ──────────────────────────────── */

.tops-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 14px; }
.tops-row { display: flex; flex-direction: column; gap: 6px; }
.tops-row__head { display: flex; align-items: center; gap: 8px; }
.tops-row__rank { flex-shrink: 0; width: 22px; height: 22px; border-radius: 7px; display: inline-flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 600; background: var(--surface-8); color: var(--text-1); }
.tops-row__rank--first { background: var(--c-green-a16); color: var(--c-green-2); }
.tops-row__label { display: flex; align-items: baseline; gap: 6px; min-width: 0; flex: 1; }
.tops-row__name { font-size: 14px; font-weight: 500; color: var(--text-primary); white-space: nowrap; flex-shrink: 0; }
.tops-row__meta { font-size: 12px; color: var(--text-1); white-space: nowrap; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.tops-row__value { flex-shrink: 0; margin-left: 8px; font-size: 15px; font-weight: 600; color: var(--text-primary); text-align: right; white-space: nowrap; }
.tops-row__value--first { color: var(--c-green); }
.tops-row__value--loss { color: var(--c-red); }
.tops-row__track { width: 100%; height: 6px; border-radius: 999px; background: var(--surface-tile); overflow: hidden; }
.tops-row__fill { height: 100%; border-radius: 999px; background: var(--c-blue); }
.tops-row__fill--first { background: linear-gradient(90deg, var(--c-blue), var(--c-green)); }
.tops-row__fill--negative { background: var(--status-refunded, var(--c-red-2)); }

.tops-empty {
  color: var(--pico-muted-color);
  font-size: 14px;
}

.tops-repeat-footer {
  margin-top: 12px;
  font-size: 13px;
  color: var(--pico-muted-color);
  border-top: 1px solid color-mix(in srgb, var(--pico-muted-border-color) 40%, transparent);
  padding-top: 8px;
}

.tops-repeat-footer strong {
  color: var(--pico-color);
  margin-left: 4px;
}

/* ── Objects analytics block ──────────────────────────────────────── */

.obj-analytics-section { container-type: inline-size; }

.obj-analytics-controls {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}

.obj-analytics-search {
  font-size: 13px;
  padding: 6px 10px;
  border-radius: 8px;
  border: 1px solid var(--pico-muted-border-color);
  background: var(--pico-card-background-color);
  color: var(--pico-color);
  min-width: 180px;
}

/* .obj-analytics-sort-group layout supplied by .seg-pills (shared class added in markup).
   .obj-analytics-sort-btn and --active look supplied by .seg-pills__btn (260618-vms). */

.obj-analytics-wrapper {
  overflow-x: auto;
  scrollbar-width: thin;
  max-height: 480px;
  overflow-y: auto;
}

.obj-analytics-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.obj-analytics-table thead th {
  position: sticky;
  top: 0;
  background: var(--pico-card-background-color, var(--surface-25));
  padding: 6px 8px;
  text-align: left;
  font-weight: 600;
  font-size: 12px;
  color: var(--pico-muted-color);
  border-bottom: 1px solid var(--pico-muted-border-color);
  white-space: nowrap;
  cursor: default;
}

.obj-analytics-table thead th.numeric { text-align: right; }

.obj-analytics-table tbody tr {
  border-bottom: 1px solid color-mix(in srgb, var(--pico-muted-border-color) 40%, transparent);
  transition: background 120ms;
}

.obj-analytics-table tbody tr:nth-child(even) {
  background: color-mix(in srgb, var(--pico-muted-border-color) 15%, transparent);
}

.obj-analytics-table tbody tr:hover {
  background: color-mix(in srgb, var(--pico-muted-border-color) 30%, transparent);
}

.obj-analytics-table td {
  padding: 6px 8px;
  vertical-align: middle;
}

.obj-analytics-table td.numeric { text-align: right; }

.obj-analytics-subject {
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.obj-analytics-total {
  font-size: 13px;
  border-top: 2px solid var(--pico-muted-border-color);
  background: color-mix(in srgb, var(--pico-muted-border-color) 20%, transparent) !important;
}

.obj-analytics-total td {
  padding: 8px;
}

.obj-analytics-empty {
  color: var(--pico-muted-color);
  font-size: 14px;
}

/* Trend arrows */
.trend--up   { color: var(--c-green); font-size: 12px; }
.trend--down { color: var(--c-red-2); font-size: 12px; }
.trend--flat { color: var(--pico-muted-color); font-size: 12px; }

/* Margin % coloring */
.margin--high { color: var(--c-green); }
.margin--low  { color: var(--c-amber); }

/* ── Plan/Fact hybrid widget (260616-4yl) ─────────────────────────────────
   Layout: 3-column body row.
     Left  (.plan-fact-gauge-col): radial SVG ring gauge
     Center (.plan-fact-middle): remaining / needed-per-day text
     Right  (.plan-fact-bars): 6-month column bars
   No client charting library. Bars sized by CSS height% set at render time.
   Compositor-safe: only height% is set (not animated after paint).
   ─────────────────────────────────────────────────────────────────────────── */

/* Header title + subtitle stacked */
.plan-fact-header-title {
  display: flex;
  flex-direction: column;
  gap: 0;
  flex: 1;
  min-width: 0;
}

/* 'auto' source badge — small muted pill beside the widget title */
.plan-fact-source-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  color: var(--pico-muted-color);
  border: 1px solid var(--pico-muted-border-color);
  vertical-align: middle;
  white-space: nowrap;
}

/* Full-width: the widget spans the whole dashboard widget-grid row (260616-gor). */
.plan-fact-widget {
  grid-column: 1 / -1;
  box-sizing: border-box;
}

/* Body: horizontal row — gauge (fixed) + stat tiles (fixed) + trend (fills). */
.plan-fact-body {
  display: flex;
  align-items: center;
  gap: 26px;
  margin-top: 8px;
}

@media (max-width: 720px) {
  .plan-fact-body {
    flex-wrap: wrap;
  }
  .plan-fact-chart {
    flex-basis: 100%;
    order: 3;
  }
}

/* ── Gauge column ─────────────────────────────────────────────────────────── */

.plan-fact-gauge-col {
  flex-shrink: 0;
}

/* Gauge SVG itself — size comes from gauge_size (124px) */
.plan-fact-gauge {
  display: block;
  overflow: visible;
}

/* Large percent text inside gauge */
.plan-fact-gauge__pct {
  font-size: 17px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Small fact / goal sub-line inside gauge */
.plan-fact-gauge__sub {
  font-size: 9.5px;
  font-variant-numeric: tabular-nums;
}

/* ── Middle: 2×2 stat tiles (fixed width, never collapse) ───────────────────── */

.plan-fact-tiles {
  flex-shrink: 0;
  width: 280px;
  display: grid;
  grid-template-columns: repeat(2, minmax(120px, 1fr));
  gap: 10px;
}

.plan-fact-tile {
  background: var(--surface-tile);
  border-radius: 11px;
  padding: 11px 13px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

/* CRITICAL: nowrap + normal overflow-wrap defeats the global overflow-wrap:anywhere
   that otherwise collapses these to one-character width (letter-by-letter vertical
   wrap) — same min-content-collapse class documented in CLAUDE.md. */
.plan-fact-tile__label {
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
  overflow-wrap: normal;
  overflow: hidden;
  text-overflow: ellipsis;
}

.plan-fact-tile__value {
  font-size: 18px;
  font-weight: 500;
  color: var(--text-primary);
  white-space: nowrap;
  overflow-wrap: normal;
  font-variant-numeric: tabular-nums;
}

.plan-fact-tile__value--green { color: var(--c-green); }
.plan-fact-tile__value--amber { color: var(--c-amber); }

/* ── 6-month bar chart column ─────────────────────────────────────────────── */

.plan-fact-bars {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 2px;                /* slim gap — spacing now comes from the 30% intra-slot margin (260617-110) */
  flex: 1;
  min-width: 0;
}

/* Single month column — each grows equally to spread across the available width */
.plan-fact-bar {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  flex: 1;
  min-width: 0;
}

/* Bar track — fixed-height column; the bar occupies ~70% of its month slot, centred (260617-110).
   Transparent background: empty months show only the baseline gridline (a thin baseline sliver),
   not a full-width grey block; the .plan-fact-gridlines behind provide the visual reference. */
.plan-fact-bar__track {
  position: relative;
  width: 70%;
  max-width: none;
  height: 108px;
  background: transparent;
  border-radius: 5px 5px 0 0;
  overflow: visible;
}

/* Fact fill — height% set inline by server; compositor-safe */
.plan-fact-bar__fill {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  min-height: 2px;         /* empty/near-zero months still show a thin baseline sliver (260617-110) */
  border-radius: 5px 5px 0 0;
  /* height set inline: style="height: X%; background: #color" */
}

/* Plan (goal) tick line — spans the full width of the (now wider) bar (260617-110) */
.plan-fact-bar__tick {
  position: absolute;
  left: 0;
  right: 0;
  height: 2px;
  background: color-mix(in srgb, var(--pico-muted-color) 60%, transparent);
  border-radius: 1px;
  /* bottom set inline: style="bottom: X%" */
}

/* Month label below each bar */
.plan-fact-bar__label {
  font-size: 10px;
  color: var(--pico-muted-color);
  white-space: nowrap;
  line-height: 1;
}

/* Current month label — brighter */
.plan-fact-bar__label.is-current {
  color: var(--c-blue);
  font-weight: 600;
}

/* ── Per-bar hover/focus tooltip (260616-kb1) ─────────────────────────────── */

/* position:relative on bar so absolute tip is relative to the bar column,
   NOT to __track (which has overflow:hidden). */
.plan-fact-bar {
  position: relative;
}

/* Hovered/focused bar — outline on the track (compositor-safe: outline, not border) */
.plan-fact-bar:hover .plan-fact-bar__track,
.plan-fact-bar:focus-within .plan-fact-bar__track {
  outline: 2px solid var(--wa-45);
  outline-offset: 2px;
}

/* Popover card — shown above the bar, centered horizontally.
   --tip-shift is set by clampPlanFactTips() JS to nudge edge bars inward.
   Default hidden: opacity:0 + visibility:hidden (no layout shift). */
.plan-fact-bar__tip {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(calc(-50% + var(--tip-shift, 0px))) translateY(-10px);
  width: 194px;
  background: var(--surface-2);
  border: 1px solid var(--wa-14);
  border-radius: 12px;
  padding: 11px 13px;
  box-shadow: 0 12px 30px var(--sc-50);
  pointer-events: none;    /* no layout influence, no mouse interaction */
  opacity: 0;
  visibility: hidden;
  z-index: 30;
  transition: opacity var(--transition-fast, 150ms);
  /* No width/height/margin animation — compositor-friendly */
}

/* Down-caret (triangle pointing at the bar) */
.plan-fact-bar__tip::after {
  content: '';
  position: absolute;
  top: 100%;
  left: calc(50% - var(--tip-shift, 0px));   /* mirrors translateX offset */
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: var(--surface-2);
}

/* Reveal on hover or keyboard focus */
.plan-fact-bar:hover .plan-fact-bar__tip,
.plan-fact-bar:focus-within .plan-fact-bar__tip {
  opacity: 1;
  visibility: visible;
}

/* Tooltip title */
.plan-fact-bar__tip-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
  padding-bottom: 8px;
  border-bottom: 1px solid var(--wa-10);
  margin-bottom: 8px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Each label:value row */
.plan-fact-bar__tip-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 6px;
  margin-bottom: 4px;
}
.plan-fact-bar__tip-row:last-child {
  margin-bottom: 0;
}
.plan-fact-bar__tip-label {
  color: var(--text-muted);
  font-size: 12px;
  white-space: nowrap;
  flex-shrink: 0;
}
.plan-fact-bar__tip-value {
  color: var(--text-primary);
  font-size: 13px;
  font-weight: 500;
  text-align: right;
}
.plan-fact-bar__tip-value--cost   { color: var(--text-3); }
.plan-fact-bar__tip-value--green  { color: var(--c-green); }
.plan-fact-bar__tip-value--margin { color: var(--c-green-2); }
.plan-fact-bar__tip-value--loss   { color: var(--c-red); }
.plan-fact-bar__tip-value--amber  { color: var(--c-amber); }

/* ── Y-axis + gridlines + chart layout (260616-lji) ──────────────────────────
   .plan-fact-chart wraps (.plan-fact-axis | .plan-fact-plot) with flex layout.
   Track height (108px) shared between axis, gridlines, and bars so bottom:pct%
   positions align correctly across all three.
   ─────────────────────────────────────────────────────────────────────────── */

/* Chart = axis column + plot area (gridlines behind bars) */
.plan-fact-chart {
  display: flex;
  align-items: flex-end;
  flex: 1;
  min-width: 0;
}

/* Left axis column — fixed width, same height as bar tracks */
.plan-fact-axis {
  flex: 0 0 46px;
  width: 46px;
  position: relative;
  height: 108px;    /* must match .plan-fact-bar__track height */
  flex-shrink: 0;
}

/* Individual axis tick label — absolute, bottom matches gridline */
.plan-fact-axis__tick {
  position: absolute;
  right: 6px;
  transform: translateY(50%);
  color: var(--surface-1);
  font-size: 11px;
  text-align: right;
  white-space: nowrap;
  line-height: 1;
  /* bottom set inline */
}

/* Plot area — fills remaining width, position:relative for gridlines overlay */
.plan-fact-plot {
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: stretch;
}

/* Gridlines container — absolute over the full plot area */
.plan-fact-gridlines {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 108px;   /* same as bar track height */
  bottom: auto;
  z-index: 0;
  pointer-events: none;
}

/* Individual gridline — thin horizontal rule */
.plan-fact-gridline {
  position: absolute;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--wa-05);
  /* bottom set inline */
}

/* Baseline (value=0) slightly brighter */
.plan-fact-gridline.is-baseline {
  background: var(--wa-10);
}

/* Bars layer sits above gridlines */
.plan-fact-bars {
  position: relative;
  z-index: 1;
}

/* ── Hide the old per-bar CSS popover (replaced by JS overlay) ────────────── */

/* The .plan-fact-bar__tip nodes stay in the DOM (JS clones them for the overlay)
   but are NEVER shown via CSS hover — the JS overlay handles display entirely.
   Drop the :hover / :focus-within reveal rules that were the old mechanism. */
.plan-fact-bar__tip {
  display: none !important;
}

/* ── Cursor-following tooltip overlay (260616-lji) ──────────────────────────
   Single fixed-position body overlay. Content is cloned from .plan-fact-bar__tip.
   position:fixed → no scroll-offset math, no layout shift.
   ─────────────────────────────────────────────────────────────────────────── */

.plan-fact-tip-overlay {
  position: fixed;
  pointer-events: none;
  z-index: 60;
  background: var(--surface-2);
  border: 1px solid var(--wa-14);
  border-radius: 12px;
  padding: 11px 13px;
  box-shadow: 0 12px 30px var(--sc-50);
  min-width: 194px;
  /* display:none / block toggled by JS */
}

/* Caret — small triangle pointing LEFT toward cursor (default: tooltip right of cursor) */
.plan-fact-tip-overlay__caret {
  position: absolute;
  top: 50%;
  left: -7px;
  transform: translateY(-50%);
  width: 0;
  height: 0;
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  border-right: 7px solid var(--surface-2);
}

/* Flipped state: tooltip is LEFT of cursor — caret points RIGHT */
.plan-fact-tip-overlay.is-flipped .plan-fact-tip-overlay__caret {
  left: auto;
  right: -7px;
  border-right: none;
  border-left: 7px solid var(--surface-2);
}

/* Content wrapper inside the overlay (mirrors .plan-fact-bar__tip styles) */
.plan-fact-tip-overlay__content .plan-fact-bar__tip-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
  padding-bottom: 8px;
  border-bottom: 1px solid var(--wa-10);
  margin-bottom: 8px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.plan-fact-tip-overlay__content .plan-fact-bar__tip-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 6px;
  margin-bottom: 4px;
}

.plan-fact-tip-overlay__content .plan-fact-bar__tip-row:last-child {
  margin-bottom: 0;
}

.plan-fact-tip-overlay__content .plan-fact-bar__tip-label {
  color: var(--text-muted);
  font-size: 12px;
  white-space: nowrap;
  flex-shrink: 0;
}

.plan-fact-tip-overlay__content .plan-fact-bar__tip-value {
  color: var(--text-primary);
  font-size: 13px;
  font-weight: 500;
  text-align: right;
}

.plan-fact-tip-overlay__content .plan-fact-bar__tip-value--cost   { color: var(--text-3); }
.plan-fact-tip-overlay__content .plan-fact-bar__tip-value--green  { color: var(--c-green); }
.plan-fact-tip-overlay__content .plan-fact-bar__tip-value--margin { color: var(--c-green-2); }
.plan-fact-tip-overlay__content .plan-fact-bar__tip-value--loss   { color: var(--c-red); }
.plan-fact-tip-overlay__content .plan-fact-bar__tip-value--amber  { color: var(--c-amber); }

/* ── Legend ───────────────────────────────────────────────────────────────── */

.plan-fact-legend {
  display: flex;
  gap: 14px;
  align-items: center;
  margin-top: 10px;
  font-size: 11px;
  color: var(--pico-muted-color);
  flex-wrap: wrap;
}

.plan-fact-legend__item {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

/* Color swatch — green or amber square */
.plan-fact-legend__swatch {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  flex-shrink: 0;
}

/* Plan tick swatch — dashed horizontal line */
.plan-fact-legend__tick-swatch {
  width: 14px;
  height: 2px;
  background: color-mix(in srgb, var(--pico-muted-color) 60%, transparent);
  border-radius: 1px;
  flex-shrink: 0;
}

/* ── Plan/Fact form (goal input) — reused from Phase-17 ─────────────────── */
/* .plan-fact-form, .plan-fact-label, .plan-fact-input, etc. already defined above */

/* Error message paragraph */
.plan-fact-error {
  color: var(--pico-del-color, var(--c-red-9));
  font-size: 13px;
  margin: 4px 0 0;
}


/* =============================================================================
   Deal window dark-tile redesign — Phase 260616-gxa
   Fixed dark palette: card #0d1320, tile #131c2e (matches Операции / plan-fact).
   Intentionally NOT theme-adaptive: same signed-off look as the operations card.
   Modal sizing uses direct-child selectors (CLAUDE.md convention — no descendant leak).
   Compositor-friendly properties only (transform/opacity/clip-path).
   ============================================================================= */

/* ── Deal detail header (title row + status pill) ─────────────────────────── */

/* ── Sticky pin for #deal-header (260618-u67) ───────────────────────────── */
/* article (scroll container: overflow-y:auto + max-height:92vh) is the sticky
   ancestor. #deal-detail-body has no overflow so sticky travels through it.
   Negative margins cancel the article's 32px padding (24px on phones) so the
   opaque background spans full width and no content bleeds at the edges. */
#deal-header {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--pico-card-background-color);
  /* The article's top padding is moved ONTO the header (padding-top below) and zeroed on the
     article, so the scrollport top == the header top — sticky top:0 pins flush with NO padding
     band above where scrolled content could peek (260618-u67 UAT). L/R negative margins fill the
     article's side padding so the opaque bg spans full width. */
  margin-left: -32px;
  margin-right: -32px;
  padding-top: 32px;
  padding-left: 32px;
  padding-right: 32px;
  padding-bottom: 4px;
  /* No shadow/line under the deal-detail title — matches the modal-form header
     (quick 260722-l3x): title flows into the body, opaque bg kept so scrolled
     content doesn't peek. */
  box-shadow: none;
}
@media (max-width: 768px) {
  #deal-header {
    padding-top: 24px;
    margin-left: -24px;
    margin-right: -24px;
    padding-left: 24px;
    padding-right: 24px;
  }
}

/* ── One-line detail header (260617-1tj): #id + object (left) · status + date + × (right) ── */
/* ONE flat flex row (260617-3mm): #id, subject, status form, X are all DIRECT children and
   every child carries a 40px line-box, so their text optical centres land on one midline.
   ROOT CAUSE of the prior misalignment: the title sat in a ~19px line-box (line-height:1) while
   the controls were 40px; align-items:center matched their BOX centres but the title's text
   optical centre rode ~1px high because the line-boxes were unequal. Equalising the line-box to
   40px on the title makes all four items centre their text identically. */
.deal-detail-header-row {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 10px;
  margin-bottom: 18px;
}

/* Close × in the header row: Pico gives dialog [rel=prev] margin-top:-18px /
   margin-bottom:18px (its own corner-pull hack) — under align-items:center
   that rode the glyph 18px above the pill's midline (measured 260722).
   Zeroing both puts the 18px box on the row's centre line, per the эталон. */
.deal-detail-header-row [rel="prev"] {
  margin-top: 0;
  margin-bottom: 0;
}

.deal-detail-id {
  font-size: 19px;          /* same size as the object title — one cohesive line (260617-24x) */
  color: var(--text-6);           /* slightly muted but matched in size */
  font-weight: 600;
  height: 40px;             /* same line-box as the pill/date so text centres identically (260617-3mm) */
  line-height: 40px;
  white-space: nowrap;
  flex: 0 0 auto;
  margin: 0;
}

.deal-detail-subject {
  font-size: 19px;
  font-weight: 600;
  color: var(--text-primary);
  margin: 0 auto 0 0;       /* margin-right:auto pushes the controls to the right edge */
  height: 40px;             /* matched 40px line-box (260617-3mm) */
  line-height: 40px;
  /* ellipsis when the object name is long */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 0 1 auto;
  min-width: 0;
}

/* Close (×) button on the header row */
/* Deal-detail modal close «×» → shared `[rel="prev"]` component (260709-14u).
   Header layout = the ORIGINAL 260617-3mm flat flex row (restored 260709-2jw2):
   direct children [#id] [name] [status-form] [×] in order. `.deal-detail-subject`
   keeps its base `margin:0 auto 0 0` — that single `margin-right:auto` pushes the
   [status][×] pair to the RIGHT edge together, so the pill sits at the right next
   to the ×. The × must NOT add a second auto margin (Pico's `[rel="prev"]` sets
   `margin-left:auto`, which split the free space and floated the pill mid-header),
   so pin it to 0 here — the × stays in flow as the last child, grouped tight after
   the pill, and the flex row's `align-items:center` keeps it on the 40px midline. */
#deal-header [rel="prev"]{margin-left:0}

/* ── Status pill — wraps the <select> for inline status edit ─────────────── */
/* The pill is a colored tinted button that reveals the select for editing.
   All hx-attrs/onchange attributes live on the form/select — CSS is display-only. */

.deal-status-pill-form {
  display: inline-flex;
  align-items: center;     /* pill + compact date inline on the header row (260617-1tj) */
  gap: 10px;
  margin: 0;               /* now a direct flex child of the header row — kill Pico's form margin (260617-3mm) */
  flex: 0 0 auto;
}

.deal-status-pill {
  display: inline-flex;
  align-items: center;
  height: 40px;            /* matched pair with the «Дата завершения» field (260617-2ey) */
  box-sizing: border-box;
  border-radius: 999px;
  padding: 0;
  position: relative;
  overflow: hidden;
  border: 1px solid transparent;
}

/* Color tints per status (matches --status-* tokens) */
.deal-status-pill--pending          { background: var(--nx-1-a18); border-color: var(--nx-2-a35); }
.deal-status-pill--awaiting_payment { background: var(--c-amber-a18);  border-color: var(--c-amber-a35); }
.deal-status-pill--awaiting_buyer   { background: var(--c-blue-a18);  border-color: var(--c-blue-a35); }
.deal-status-pill--in_stock         { background: var(--c-amber-a18);  border-color: var(--c-amber-a35); }
.deal-status-pill--in_progress      { background: var(--c-blue-a18);  border-color: var(--c-blue-a35); }
.deal-status-pill--on_hold          { background: var(--nx-1-a18); border-color: var(--nx-2-a35); }
.deal-status-pill--completed        { background: var(--c-green-a18);   border-color: var(--c-green-a35); }
.deal-status-pill--disputed         { background: var(--c-amber-a18-2);   border-color: var(--c-amber-a35-2); }
.deal-status-pill--refunded         { background: var(--c-red-a18);   border-color: var(--c-red-a35); }
.deal-status-pill--cancelled        { background: var(--c-red-a18);   border-color: var(--c-red-a35); }

.deal-status-pill__select {
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: none;
  padding: 0 28px 0 14px;   /* vertical 0 + height/line-height 38 centres text in the 40px pill */
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  outline: none;
  color: var(--text-primary);
  height: 38px;             /* 40px pill − 1px×2 border (260617-2ey) */
  line-height: 38px;
  box-sizing: border-box;
  margin: 0;
  /* Chevron icon via background */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%237d8aa0' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 8px center;
}

.deal-status-pill__select:focus {
  outline: none;
}

/* Compact inline «Дата завершения» date field — ~pill height, calendar icon (260617-1tj).
   Wave 3 (260617-uqq): native <input type=date> replaced by custom datepicker macro; target
   .datepicker__display inside .deal-close-date-compact instead of input[type="date"]. */
.deal-close-date-compact {
  display: inline-flex;
  align-items: center;
  position: relative;
}
/* Override the 52px form height — compact context matches the 40px status pill. */
.deal-close-date-compact .datepicker__display {
  height: 40px;
  padding: 0 34px 0 12px;  /* right pad for the calendar icon, left matches the pill */
  font-size: 14px;
  color: var(--text-3);
}
/* .datepicker is display:block by default; switch to inline so it sits in the flex row. */
.deal-close-date-compact .datepicker {
  display: inline-block;
}
/* The popover must escape the compact wrapper — it is position:absolute but its nearest
   positioned ancestor is .datepicker (position:relative), so it already pops out correctly
   even if .deal-close-date-compact had overflow:hidden (it does not). No extra rule needed. */

.deal-detail-status-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* HTMX in-flight: dim the select so user knows request is pending */
#deal-header.htmx-request .deal-status-pill__select {
  opacity: 0.5;
  pointer-events: none;
}

/* ── 4-tile stat grid (Закуп / Реализация / Маржа / Цикл) ─────────────────── */

.deal-detail-tiles {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin-bottom: 16px;
}

@media (min-width: 600px) {
  .deal-detail-tiles {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.deal-detail-tile {
  background: var(--surface-tile);
  border-radius: 12px;
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.deal-detail-tile__label {
  font-size: 11px;
  color: var(--text-muted);
  line-height: 1.25;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.deal-detail-tile__value {
  font-size: 17px;
  font-weight: 500;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}

.deal-detail-tile__sub {
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.25;
}

/* Маржа tile: green when ≥ 0, red when < 0 */
.deal-detail-tile--green .deal-detail-tile__value {
  color: var(--c-green);
}

.deal-detail-tile--red .deal-detail-tile__value {
  color: var(--c-red);
}

/* Цикл tile: amber when close_date < occurred_at (invalid backwards cycle) — quick-260617.
   Pairs with title="дата завершения раньше начала" on the value. */
.deal-detail-tile__value--warn {
  color: var(--c-amber-2);
  cursor: help;
}

/* ── 2-col details grid (Дата / Завершение / Количество / Цена / Продавец / Покупатель) ── */

.deal-detail-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  margin-bottom: 20px;
}

@media (min-width: 640px) {
  .deal-detail-grid {
    grid-template-columns: 1fr 1fr;
  }
}

.deal-detail-grid__row {
  display: grid;
  /* Label column: max-content + nowrap (CLAUDE.md: auto/max-content, not min-content) */
  grid-template-columns: max-content minmax(0, 1fr);
  column-gap: 12px;
  align-items: baseline;
  padding: 7px 0;
  border-bottom: 1px solid var(--wa-07);
}
/* All 6 rows (incl. the last «Покупатель») carry the same separator (260617-1tj). */

.deal-detail-grid__label {
  font-size: 13px;
  color: var(--text-muted);
  white-space: nowrap;  /* CLAUDE.md: nowrap for label columns */
}

/* «(≈N лет)» term-in-years hint next to a loan's payment count — secondary. */
.subs-term-years {
  color: var(--text-muted);
}

.deal-detail-grid__value {
  font-size: 13px;
  color: var(--text-3);
  overflow-wrap: anywhere;
}

.deal-own-stock-badge {
  font-style: normal;
  color: var(--c-amber);
  font-size: 13px;
}

/* ── Section headers (Комментарии / Файлы) ───────────────────────────────── */

.deal-detail-section {
  margin-bottom: 16px;
}

.deal-detail-section__title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-muted);
  margin: 0 0 10px 0;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.deal-detail-empty {
  font-size: 13px;
  color: var(--text-muted);
  margin: 0 0 10px 0;
}

/* ── Comment cards ──────────────────────────────────────────────────────────── */

.deal-comments-list {
  list-style: none;
  padding: 0;
  margin: 0 0 12px 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.deal-comment-card {
  display: flex;            /* body (left) + delete × (right) — 260617-373 */
  align-items: flex-start;
  gap: 8px;
  background: var(--surface-tile);
  border-radius: 10px;
  padding: 10px 14px;
}
.deal-comment-card__main {
  flex: 1 1 auto;
  min-width: 0;
}

/* Small × delete button on comment + attachment rows (muted → red on hover). 260617-373 */
.deal-row-delete {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  margin: 0;
  border: none;
  border-radius: 7px;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.deal-row-delete:hover {
  background: var(--c-red-a12);
  color: var(--c-red);
}

.deal-comment-card__date {
  display: block;
  font-size: 12px;
  color: var(--text-muted);
  margin-bottom: 4px;
}

.deal-comment-card__body {
  font-size: 14px;
  color: var(--text-3);
  margin: 0;
}

/* Comment add form */
.deal-comment-form {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
}

/* The <label> wrapping the textarea carries Pico's label margin — zero it so
   the form's 6px gap is the only spacing before the submit (mock 260722). */
.deal-comment-form__label {
  margin-bottom: 0;
}

.deal-comment-form__label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 13px;
  color: var(--text-muted);
}

.deal-comment-form__textarea {
  /* Pico textarea margin-bottom 18px + the wrapping <label>'s own margin
     opened a ~30px void before the submit — the column-flex gap (6px) is
     the single source of rhythm here (mock 260722). */
  margin-bottom: 0;
  background: var(--surface-tile);
  border: 1px solid var(--wa-10);
  border-radius: 10px;
  padding: 8px 12px;
  font-size: 14px;
  color: var(--text-primary);
  resize: vertical;
  height: 54px;
  min-height: 54px;
}

/* «+ Добавить комментарий» — compact blue outline, right-aligned (mirrors .task-add-form__submit /
   .pay-add-form__submit). margin-bottom:0 + width:auto undo Pico's bare-submit defaults. */
.deal-comment-form__submit {
  align-self: flex-end;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  background: transparent;
  border: 1px solid rgba(47,107,255,0.5);
  color: var(--c-blue-9);
  border-radius: 10px;
  margin-bottom: 0;
  width: auto;
  font-size: 13px;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--transition-fast);
}

.deal-comment-form__submit:hover {
  background: rgba(47,107,255,0.08);
}

.deal-comment-form__submit:focus:not(:focus-visible) {
  outline: none;
  box-shadow: none;
}

.deal-comment-form__submit:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px rgba(47,107,255,0.5);
}

/* ── Attachment chips ────────────────────────────────────────────────────────── */

.deal-attachment-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
}

/* Each file = a download chip + a delete × side by side (260617-373). */
.deal-attachment-row {
  display: inline-flex;
  align-items: center;
  gap: 2px;
}

.deal-attachment-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--surface-tile);
  border: 1px solid var(--wa-10);
  border-radius: 8px;
  padding: 5px 10px;
  text-decoration: none;
  color: var(--text-3);
  font-size: 13px;
  max-width: 200px;
  transition: background var(--transition-fast);
}

.deal-attachment-chip:hover {
  background: var(--wa-08);
  color: var(--text-primary);
}

.deal-attachment-chip__icon {
  flex-shrink: 0;
  font-size: 14px;
}

.deal-attachment-chip__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Attachment upload form */
.deal-attachment-form {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
}

.deal-attachment-form__label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 13px;
  color: var(--text-muted);
}

.deal-attachment-form__input {
  font-size: 13px;
  color: var(--text-3);
}

/* «Загрузить» — compact blue outline (mirrors .deal-comment-form__submit); disabled until a
   file is selected (JS toggles .disabled via onchange + the dnd drop handler). */
.deal-attachment-form__submit {
  flex: 0 0 auto;
  height: 34px;
  padding: 0 14px;
  font-size: 13px;
  border-radius: 10px;
  background: transparent;
  border: 1px solid rgba(47,107,255,0.5);
  color: var(--c-blue-9);
  margin-bottom: 0;
  width: auto;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--transition-fast);
}

.deal-attachment-form__submit:hover {
  background: rgba(47,107,255,0.08);
}

.deal-attachment-form__submit:focus:not(:focus-visible) {
  outline: none;
  box-shadow: none;
}

.deal-attachment-form__submit:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px rgba(47,107,255,0.5);
}

.deal-attachment-form__submit:disabled {
  opacity: 0.45;
  cursor: default;
}

.deal-attachment-form__submit:disabled:hover {
  background: transparent;
}

/* ── Styled file-picker control (260616-twb) ─────────────────────────────── */

.deal-file-picker {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 8px;
}

.deal-file-picker__label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 34px;
  padding: 0 14px;
  border-radius: 10px;
  background: transparent;
  border: 1px solid rgba(47,107,255,0.5);
  color: var(--c-blue-9);
  font-size: 13px;
  cursor: pointer;
  transition: background var(--transition-fast), border-color var(--transition-fast);
}

.deal-file-picker__label:hover {
  background: rgba(47,107,255,0.08);
}

.deal-file-picker__label svg {
  flex-shrink: 0;
}

.deal-file-picker__input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.deal-file-picker__name {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  color: var(--text-muted);
  overflow-wrap: anywhere;
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
}

.deal-file-picker__hint {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 6px;
  display: block;
}

/* ── Drag-and-drop file zone (260617-2tu) ────────────────────────────────────
   Hidden until a file is dragged over the form (JS toggles .is-dragover); then the picker +
   submit are swapped for this dashed drop zone, and the form gets a subtle blue ring. */
.deal-file-dropzone {
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 22px 16px;
  border: 2px dashed var(--c-blue);
  border-radius: 12px;
  background: var(--c-blue-a08);
  color: var(--c-blue-4);
  text-align: center;
  cursor: pointer;
}
.deal-file-dropzone__icon { color: var(--c-blue-4); }
.deal-file-dropzone__title { font-size: 14px; font-weight: 600; color: var(--c-blue-10); }
.deal-file-dropzone__hint { font-size: 12px; color: var(--text-muted); }

/* While dragging: show the zone, hide the normal controls, ring the form. */
.deal-attachment-form.is-dragover {
  box-shadow: 0 0 0 3px var(--c-blue-a12);
  border-radius: 12px;
}
.deal-attachment-form.is-dragover .deal-file-dropzone {
  display: flex;
}
.deal-attachment-form.is-dragover .deal-file-picker,
.deal-attachment-form.is-dragover .deal-file-picker__hint {
  display: none;
}

/* ── Detail footer (Удалить / Редактировать) ─────────────────────────────── */

/* Footer bar — top border + slightly darker bg; Удалить (red ghost) left, Редактировать
   (filled secondary) right (260617-1tj). Negative margins make the darker bar span the modal
   padding edge-to-edge. */
.deal-detail-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  /* Flat canon footer for ALL detail modals (260722, was payments-only 0k7):
     same bg as the modal body, hairline divider only — the old darker
     full-bleed band (--surface-14 + negative margins) is gone everywhere.
     Bottom padding 28px optically matches the header air (see 260721-2ku:
     the 19px/40px title carries ~8.5px of cap leading, buttons don't). The
     article has 0 bottom padding, so this padding IS the modal's bottom gap. */
  margin: 15px 0 0;
  padding: 15px 0 28px;
  border-top: 0.5px solid var(--wa-07);
  background: transparent;
}

@media (max-width: 768px) {
  .deal-detail-footer {
    margin: 18px -24px 0;
    padding: 18px 24px 18px;
  }
}

@media (max-width: 480px) {
  .deal-detail-footer {
    flex-direction: column-reverse;
  }

  .deal-detail-footer__delete,
  .deal-detail-footer__edit,
  .deal-detail-footer__pay {
    width: 100%;
    justify-content: center;
  }
}

/* Shared: icon + label inline */
.deal-detail-footer__delete,
.deal-detail-footer__edit {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 14px;
  border-radius: 10px;
  cursor: pointer;
  /* ROOT CAUSE (debug 260617-4fh): Pico's default button margin-bottom:20px was never reset on
     these footer buttons. In the align-items:center flex strip that 20px inflates each button's
     OUTER box, so the visible button centres at the TOP of its margin-box and the 20px margin
     shows as empty black BELOW it (footer 100px, buttons at +20, 39px gap below). Reset to 0 →
     footer 80px, buttons centred (gap 20/19), flush bottom. */
  margin: 0;
  transition: background var(--transition-fast), color var(--transition-fast);
}

/* Удалить — understated red ghost (transparent, no border) */
.deal-detail-footer__delete {
  padding: 10px 14px;
  background: transparent;
  border: none;
  color: var(--c-red);
}
.deal-detail-footer__delete:hover {
  background: var(--c-red-a12);
}

/* Редактировать — prominent filled secondary */
.deal-detail-footer__edit {
  padding: 10px 22px;
  background: var(--surface-12);
  border: 1px solid var(--wa-12);
  color: var(--text-2);
}
.deal-detail-footer__edit:hover {
  background: var(--surface-10);
  color: var(--text-2);
}

/* ── Dark add/edit form (deal-form-* classes) ────────────────────────────── */

/* Error banner */
.deal-form-error-banner {
  background: var(--c-red-a12);
  border: 1px solid var(--c-red-a30);
  border-radius: 8px;
  padding: 8px 12px;
  font-size: 13px;
  color: var(--c-red);
  margin-bottom: 12px;
}

.deal-form-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.deal-form-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.deal-form-field--full {
  grid-column: 1 / -1;
}

.deal-form-label {
  font-size: 12px;
  color: var(--text-muted);
  font-weight: 500;
  margin: 0;
}

.deal-form-input {
  background: var(--surface-tile);
  border: 1px solid var(--wa-10);
  border-radius: 10px;
  padding: 11px 12px;
  font-size: 14px;
  color: var(--text-primary);
  height: 52px;   /* restored comfortable row height — uniform across all fields (260616-w96) */
  box-sizing: border-box;
  margin: 0;
  transition: border-color var(--transition-fast);
}

.deal-form-input:focus {
  border-color: var(--c-blue-a50);
  outline: none;
}

.deal-form-input[aria-invalid="true"] {
  border-color: var(--c-red-a50);
  /* The app signals errors with a red border + a .form-error message — suppress Pico's default
     aria-invalid background icon (it tiled across the narrow defect amount input). !important to
     beat Pico's higher-specificity [aria-invalid] icon rule. (260619-vng) */
  background-image: none !important;
}

.deal-form-select {
  background: var(--surface-tile);
  border: 1px solid var(--wa-10);
  border-radius: 10px;
  padding: 11px 12px;
  font-size: 14px;
  color: var(--text-primary);
  height: 52px;   /* uniform with .deal-form-input (260616-w96) */
  box-sizing: border-box;
  margin: 0;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%237d8aa0' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-color: var(--surface-tile);
  padding-right: 32px;
  transition: border-color var(--transition-fast);
}

.deal-form-select:focus {
  border-color: var(--c-blue-a50);
  outline: none;
}

/* 2-column row */
.deal-form-row-2col {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
}

@media (min-width: 420px) {
  .deal-form-row-2col {
    grid-template-columns: 1fr 1fr;
  }
}

/* Amount + currency side-by-side (price rows) */
.deal-form-amount-row {
  display: flex;
  gap: 8px;
  /* stretch — both cells share IDENTICAL top + bottom edges (not just a shared centre line);
     safe because both children are pinned to 52px below, so the row is exactly 52 and matches
     the neighbouring fields / Маржа strip (260617-0vo, was center per 260616-x1y). */
  align-items: stretch;
}

/* Pin BOTH price children (amount input + currency box) to the Маржа field's 52px at amount-row
   scope. Specificity (0,2,0) beats Pico's input height (0,1,1) by specificity itself — not merely
   load order — so the price elements can never render taller than the rest. margin:0 + align-self
   reset kill any stray vertical offset that could push one cell off-level (260617-0vo). */
.deal-form-amount-row .deal-form-input,
.deal-form-amount-row .deal-form-currency {
  height: 52px;
  min-height: 52px;
  box-sizing: border-box;
  margin: 0;
  align-self: stretch;
}

.deal-form-amount-row .deal-form-input {
  flex: 1 1 auto;
  min-width: 0;
}

/* ── Currency selector — overlay (260617-0fg) ────────────────────────────────
   The native <select> can't reliably centre its closed value, so the visible symbol is a
   real centred <span>; the native select sits invisibly on top for clicks/keyboard. */
.deal-form-currency {
  position: relative;
  flex: 0 0 auto;
  width: 84px;
  height: 52px;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;     /* the «$» span is dead-centre */
  background: var(--surface-tile);
  border: 1px solid var(--wa-08);
  border-radius: 10px;
}
.deal-form-currency .cur-symbol {
  color: var(--text-primary);
  font-size: 14px;
  line-height: 1;
  pointer-events: none;        /* clicks fall through to the select underneath */
}
.deal-form-currency .cur-chevron {
  position: absolute;
  right: 9px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-muted);
  pointer-events: none;
}
/* The real control: invisible, fills the box, captures clicks + keyboard. */
.deal-form-currency .deal-form-currency__select {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  border: none;
  background: transparent;
}

/* ── Uniform field height — beat Pico's form-element sizing (260616-wjz) ──────
   Pico defines `input:not([type=checkbox],[type=radio],[type=range]){height:calc(…)}`
   and `input:not(…),select,textarea{padding:…}` at specificity (0,1,1) — these OUTRANK
   the single-class `.deal-form-input` / `.deal-form-select` (0,1,0) above, so our height
   + vertical padding never applied to <input> elements; the price amount inputs rendered
   TALLER than the Маржа <div> (a plain div Pico never touches → exactly its min-height 52).
   Element-qualified selectors below are (0,1,1): they tie Pico and win by load order
   (theme.css loads after pico-2.min.css), pinning EVERY field to the Маржа field's 52px.
   Full padding re-asserted here so nothing leaks back to Pico's spacing. */
input.deal-form-input,
select.deal-form-select {
  height: 52px;
  min-height: 52px;
  box-sizing: border-box;
}
input.deal-form-input {
  padding: 0 12px;       /* vertical 0 + height 52 → text centred by the input box */
}
select.deal-form-select {
  padding: 0 32px 0 12px; /* room for the chevron on the right */
}

/* Own-stock toggle */
.deal-form-own-stock-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-size: 14px;
  color: var(--text-3);
  margin: 0;
}

.deal-form-own-stock-toggle input[type="checkbox"] {
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--c-blue);
  cursor: pointer;
}

.deal-form-own-stock-toggle__text {
  font-size: 14px;
}

/* dim cost field when own_stock active */
[data-cost-field].own-stock-dim .deal-form-input {
  opacity: 0.45;
}

/* hide seller when own_stock active */
[data-seller-field][hidden] {
  display: none;
}

/* ── Service mode (Phase 20): «Услуга (получаю %)» ───────────────────────────── */
/* Native [hidden] does NOT win over .deal-form-field{display:flex}/.row{display:grid},
   so force it for the goods/service show-hide markers + sub-panels + the panel itself. */
[data-goods-only][hidden],
[data-service-only][hidden],
[data-service-sub][hidden] {
  display: none !important;
}

.deal-form-mode-toggles {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: 18px;
  min-height: 38px;
  align-items: center;
}

/* Blue-tint service-income panel */
.deal-service-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  background: var(--c-blue-a07);
  border: 1px solid var(--c-blue-a22);
  border-radius: 12px;
}

/* Segmented «Фикс. сумма | % от суммы» — compact, content-width, NO track box.
   Just an active blue pill + plain-text inactive option on the panel background. */
.deal-service-seg {
  display: inline-flex;
  align-self: flex-start;   /* hug content — don't stretch to the panel's column width */
  gap: 6px;
}

.deal-service-seg__opt {
  position: relative;
  cursor: pointer;
}

.deal-service-seg__opt input {
  position: absolute;
  opacity: 0;
  inset: 0;
  margin: 0;
  cursor: pointer;
}

.deal-service-seg__opt span {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 34px;
  padding: 0 18px;
  font-size: 13px;
  color: var(--text-1);            /* inactive: transparent bg + muted text */
  background: transparent;
  border-radius: 9px;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.deal-service-seg__opt input:checked + span {
  background: var(--c-blue);       /* active: solid blue pill */
  color: var(--text-2);
}

/* % row: «Сумма операции» (amount + inline currency) flex | «Ставка %» fixed. */
.deal-service-percent-row {
  display: flex;
  gap: 9px;
  align-items: flex-start;
}
.deal-service-base-field {
  flex: 1 1 0;
  min-width: 0;
}
.deal-service-rate-field {
  flex: 0 0 96px;
}

/* Compact fields inside the panel: 46px inputs, 12px labels, ~64px inline currency.
   The currency selector must EXACTLY match the amount input height — beat
   `.deal-form-amount-row .deal-form-currency`'s height:52 + min-height:52 (0,2,0) with a
   (0,3,0) selector that pins BOTH height and min-height. */
.deal-service-panel input.deal-form-input {
  height: 46px;
  min-height: 46px;
}
.deal-service-panel .deal-form-amount-row .deal-form-currency {
  width: 64px;
  height: 46px;
  min-height: 46px;
}
.deal-service-panel .deal-form-label {
  font-size: 12px;
}

/* Compact result line: label (left) + green income (right) with a thin top border. */
.deal-service-result {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--wa-08);
  font-size: 13px;
}
.deal-service-result__label {
  color: var(--text-1);
}
.deal-service-result__value {
  color: var(--c-green);
  font-weight: 600;
  white-space: nowrap;
}

/* ── Margin preview strip ─────────────────────────────────────────────────── */

.deal-margin-preview {
  display: flex;
  align-items: center;   /* vertically centre the text in the taller strip (260616-w96) */
  min-height: 52px;      /* uniform with the form inputs */
  box-sizing: border-box;
  font-size: 13px;
  color: var(--text-muted);
  padding: 0 14px;
  background: var(--surface-row);
  border-radius: 10px;
  border: 1px solid var(--wa-07);
  transition: color var(--transition-fast), background var(--transition-fast);
}

.deal-margin-preview--positive {
  color: var(--c-green);
  background: var(--c-green-a08);
  border-color: var(--c-green-a20);
}

.deal-margin-preview--negative {
  color: var(--c-red);
  background: var(--c-red-a08);
  border-color: var(--c-red-a20);
}

/* ── Blue submit pill (unified, matches .add-deal-btn accent) ─────────────── */
/* Selector class on <button type="submit"> in _new_modal.html / _edit_modal.html.
   Modal sizing binds to dialog.modal-form > article (direct-child — CLAUDE.md). */

.deal-submit-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  line-height: 1;
  height: 44px;               /* fixed height — label vertically centred via align-items */
  box-sizing: border-box;
  background: var(--c-blue);
  color: var(--text-2);
  border: none;
  border-radius: 999px;
  padding: 0 22px;            /* symmetric — no vertical bias */
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  width: auto;
  flex: 0 0 auto;
  transition: background var(--transition-fast), opacity var(--transition-fast);
  letter-spacing: 0.01em;
}

/* '+' icon is a flex child: blockified, no inline descender gap, no baseline push (260616-vr3) */
.deal-submit-pill svg {
  display: block;
  flex-shrink: 0;
}

.deal-submit-pill:hover {
  background: var(--accent-hover, var(--c-blue-3));
}

.deal-submit-pill:active {
  opacity: 0.85;
}

/* Matched-pair secondary pill — same full-pill radius + height as .deal-submit-pill (260616-r3h) */
.deal-cancel-pill {
  background: var(--surface-tile);
  color: var(--c-blue);
  border: 1px solid var(--wa-12);
  border-radius: 999px;
  padding: 9px 22px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  width: auto;
  flex: 0 0 auto;
  letter-spacing: 0.01em;
  transition: background var(--transition-fast), border-color var(--transition-fast);
}
.deal-cancel-pill:hover {
  background: var(--surface-2);
  border-color: var(--wa-20);
}

/* Form error messages in dark context */
.deal-form-body .form-error {
  font-size: 12px;
  color: var(--c-red);
  margin: 0;
}

/* =============================================================================
   KPI STRIP + DEALS CARD (260616-ien)
   Dark-tile palette: matches Операции card + 260616-gxa modal.
   Fixed palette (intentionally not theme-adaptive — same signed-off dark look).
   ============================================================================= */

/* ── KPI strip — 4-tile current-month grid ──────────────────────────────── */
.kpi-strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
  margin-bottom: 16px;
}

@media (max-width: 768px) {
  .kpi-strip {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Individual KPI tile — mirrors .operations-tile dark surface */
.kpi-tile {
  background: var(--surface-tile);
  border-radius: 12px;
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.kpi-tile__label {
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.25;
}

.kpi-tile__value {
  font-size: 21px;
  font-weight: 500;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}

/* Green accent — profit tile value */
.kpi-tile__value--green {
  color: var(--c-green);
}

/* ── Deals card wrapper — dark card with rounded corners ─────────────────── */
.deals-card {
  background: var(--surface-card);
  border: 1px solid var(--wa-08);
  border-radius: 16px;
  overflow: hidden;
  margin-bottom: 12px;
}

/* #deals-table-wrapper inside the card: remove its own border+radius since the
   card clips the corners; keep scroll behaviour intact. */
.deals-card #deals-table-wrapper {
  border: none;
  border-radius: 0;
}

/* Sticky header inside the dark card: dark background so it reads correctly */
.deals-card #deals-table-wrapper thead th {
  background: var(--surface-card);
  box-shadow: inset 0 -1px 0 var(--wa-08);
}

/* ── Status chips — adjust border-bottom for the dark surface ────────────── */
/* The chips sit above the dark deals card; drop the divider so there's no
   double-border effect between the chips bar and the card edge. */
.status-chips {
  border-bottom: none;
}

/* ── Pagination — 32×32 dark-surface restyle (260616-ien) ───────────────── */
/* Override the existing .pagination rules with dark-tile sizing + active blue */

.pagination {
  justify-content: flex-end;
  align-items: center;
}

/* Info line left-aligned — push to left via margin-right:auto trick */
.pagination__info {
  margin-right: auto;
}

.pagination__page,
.pagination__prev,
.pagination__next {
  min-width: 32px;
  height: 32px;
  padding: 0 8px;
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Active page — solid blue (overrides base rule) */
.pagination__page--active {
  background: var(--c-blue);
  border-color: var(--c-blue);
  color: var(--text-2);
}

/* Hover on non-active page/prev/next (existing rule covers this but reinforce) */
.pagination__page:hover:not(:disabled):not(.pagination__page--active),
.pagination__prev:hover:not(:disabled),
.pagination__next:hover:not(:disabled) {
  background: var(--wa-08);
  border-color: var(--wa-20);
}

/* ── Segmented «За период» control (260616-t2l) ──────────────────── */
/* Track-box look removed (260618-vms) — separated pills via .seg-pills shared class.
   Keep: height:44px (row alignment), flex-shrink:0 (no-wrap), width:fit-content,
   margin-bottom (standalone spacing). */
.segmented-period {
  height: 44px;              /* fixed so all segments match the 44px row (260618-p4s) */
  box-sizing: border-box;
  margin-bottom: 12px;       /* standalone (error/empty) spacing; zeroed inside .analytics-topbar */
  width: fit-content;
  flex-shrink: 0;            /* never compress in the top row → «Всё время» can't be forced to wrap */
}
/* .segmented-period__btn and --active look supplied by .seg-pills__btn (shared class in markup) */

/* ── Analytics top bar — one row: period · Настроить аналитику (left) · refresh (right) ──
   Mirrors the dashboard .header-actions pattern (260616-x5n). */
.analytics-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 16px;
}
.analytics-topbar__left {
  display: flex;
  align-items: center;
  gap: 10px;
}
/* Inside the row neither the segmented control nor the period navigator carries a bottom
   margin — otherwise the nav's margin-box makes __left taller than 44px and align-items:center
   pushes it ~10px above its neighbors (260618-p4s). The row owns spacing. */
.analytics-topbar .segmented-period,
.analytics-topbar .period-nav {
  margin-bottom: 0;
}

/* ── Period navigator pill «‹ Label ›» (260617-to0 wave 3) ─────────────────────────────
   Sits in .analytics-topbar__left right after the segmented type selector.
   Tokens mirror the segmented-period pill (#131c2e / #22e754 / #7d8aa0 / #5d6a82). */
.period-nav {
  display: flex;
  align-items: center;
  gap: 2px;
  background: var(--surface-tile);
  border: 1px solid var(--wa-08);
  border-radius: 10px;
  height: 44px;              /* match the segmented toggle + buttons + refresh (260618-p4s) */
  padding: 0 4px;
  box-sizing: border-box;
  /* NO flex-shrink:0 here — it combines with an inherited flex-grow and balloons the pill to
     fill the row (260618-p4s); the nav stays compact at its content width. */
}

.period-nav__arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  background: transparent;
  border: none;
  border-radius: 7px;
  color: var(--text-muted);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  transition: background 150ms, color 150ms;
  padding: 0;
  flex-shrink: 0;
}

.period-nav__arrow:hover:not(:disabled):not([aria-disabled="true"]) {
  background: var(--hairline);
  color: var(--text-primary);
}

.period-nav__arrow:disabled,
.period-nav__arrow[aria-disabled="true"] {
  opacity: 0.35;
  cursor: default;
  pointer-events: none;
}

.period-nav__label {
  background: transparent;
  border: none;
  color: var(--text-primary);
  font-size: 14px;
  font-weight: 600;
  padding: 0 10px;
  cursor: pointer;
  white-space: nowrap;
  transition: color 150ms;
  line-height: 1;
}

.period-nav__label:hover {
  color: var(--text-2);
}

/* ── Period picker popover (260617-to0 Wave 4) ──────────────────────────────
   Positioned absolutely relative to .period-nav (position:relative added below).
   Hidden by default (display:none); .is-open shows it.
   Tokens: #1a2436 surface / #22e754 accent / #7d8aa0 muted / #c3ccdd text. */

.period-nav {
  position: relative;
}

.period-picker-popover {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 240px;
  background: var(--surface-2);
  border: 1px solid var(--wa-14);
  border-radius: 12px;
  box-shadow: 0 12px 30px var(--sc-50);
  padding: 12px;
  z-index: 60;
  display: none;
}

.period-picker-popover.is-open {
  display: block;
}

/* Empty container stays hidden without is-open */
.period-picker-popover:empty {
  display: none;
}

/* ── Year stepper row ───────────────────────────── */
.period-picker__stepper {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}

.period-picker__stepper-year {
  color: var(--text-primary);
  font-size: 13px;
  font-weight: 600;
  user-select: none;
}

.period-picker__stepper-arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  background: transparent;
  border: none;
  border-radius: 6px;
  color: var(--text-muted);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  transition: background 150ms, color 150ms;
}

.period-picker__stepper-arrow:hover:not(:disabled):not([aria-disabled="true"]) {
  background: var(--hairline);
  color: var(--text-primary);
}

.period-picker__stepper-arrow:disabled,
.period-picker__stepper-arrow[aria-disabled="true"] {
  opacity: 0.35;
  cursor: default;
  pointer-events: none;
}

/* ── Month grid 3×4 ─────────────────────────────── */
.period-picker__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
}

/* ── Quarter row (4 equal buttons) ─────────────── */
.period-picker__quarters {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
}

/* ── Year list (column of buttons) ─────────────── */
.period-picker__years {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.period-picker__year-btn {
  width: 100%;
  background: transparent;
  border: none;
  border-radius: 8px;
  color: var(--text-3);
  font-size: 13px;
  font-weight: 500;
  padding: 7px 10px;
  text-align: left;
  cursor: pointer;
  transition: background 150ms, color 150ms;
}

.period-picker__year-btn:hover {
  background: var(--hairline);
  color: var(--text-primary);
}

.period-picker__year-btn.is-selected {
  background: var(--c-blue);
  color: var(--text-2);
}

/* ── Shared cell style (month + quarter buttons) ─ */
.period-picker__cell {
  height: 34px;
  background: transparent;
  border: none;
  border-radius: 8px;
  color: var(--text-3);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: background 150ms, color 150ms;
  padding: 0;
}

.period-picker__cell:hover:not(:disabled):not([aria-disabled="true"]) {
  background: var(--hairline);
  color: var(--text-primary);
}

.period-picker__cell.is-selected {
  background: var(--c-blue);
  color: var(--text-2);
}

.period-picker__cell:disabled,
.period-picker__cell[aria-disabled="true"] {
  opacity: 0.35;
  cursor: default;
  pointer-events: none;
}

/* «сейчас» hint in Операции card header — shown when a non-current period is selected */
.operations-header__now-hint {
  font-size: 11px;
  color: var(--surface-1);
  font-weight: 400;
  margin-left: 4px;
  white-space: nowrap;
}

/* ── datepicker component (wave 1/4) ────────────────────────────────────────── */

.datepicker {
  position: relative;
  display: block;
}

.datepicker__display {
  padding-right: 34px;
  cursor: pointer;
}

.datepicker__icon {
  position: absolute;
  right: 10px;
  top: 50%;
  /* -3px optical nudge: the calendar glyph sits low in its viewBox, so pure box-centering
     reads below the date text. -3px is the level middle (-2 read low, -5 too high). */
  transform: translateY(calc(-50% - 3px));
  color: var(--text-muted);
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 0;
}

/* display:block drops the inline-SVG baseline gap that nudged the icon below center */
.datepicker__icon svg {
  display: block;
}

/* Popover */
.datepicker__popover {
  /* fixed → viewport-anchored; works whether parented to <body> or re-parented into a
     <dialog> top layer (the modal has no transformed ancestor). High z-index so it renders
     above modal content when hosted inside the dialog (was z-index:70 / position:absolute,
     which rendered BEHIND a <dialog showModal()> top layer → invisible inside modals). */
  position: fixed;
  z-index: 1000;
  background: var(--surface-2);
  border: 1px solid var(--wa-12);
  border-radius: 14px;
  box-shadow: 0 16px 40px var(--sc-50);
  padding: 12px;
  box-sizing: border-box;
  /* width = 7 day columns (34px) + 6 gaps (3px) + 2×12 padding = 280px → tidy near-square */
  width: 280px;
  display: none;
}

.datepicker__popover.is-open {
  display: block;
}

/* Reset Pico's default button margin-bottom for ALL popover buttons (day cells, year
   cells, nav arrows, month label, footer) — it was spreading the grid rows ~16px apart
   and bloating the calendar height. */
.datepicker__popover button {
  margin: 0;
}

/* Header */
.dp-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
  gap: 4px;
}

.dp-nav-btn {
  background: transparent;
  border: none;
  color: var(--text-3);
  font-size: 18px;
  line-height: 1;
  padding: 4px 8px;
  border-radius: 6px;
  cursor: pointer;
  transition: background 150ms;
  min-width: 28px;
}

.dp-nav-btn:hover {
  background: var(--wa-08);
  color: var(--text-primary);
}

.dp-month-label {
  flex: 1;
  background: transparent;
  border: none;
  color: var(--text-primary);
  font-size: 14px;
  font-weight: 600;
  text-align: center;
  padding: 4px 8px;
  border-radius: 6px;
  cursor: pointer;
  transition: background 150ms;
}

.dp-month-label:hover {
  background: var(--hairline);
}

/* Weekday row */
.dp-weekdays {
  margin-bottom: 2px;
}

.dp-weekday {
  text-align: center;
  font-size: 11px;
  font-weight: 500;
  color: var(--surface-1);
  padding: 2px 0;
}

/* Day grid — fixed 34px columns + 3px gap → square cells, tight rows */
.dp-grid {
  display: grid;
  grid-template-columns: repeat(7, 34px);
  gap: 3px;
}

.dp-days {
  margin-bottom: 6px;
}

.dp-day {
  height: 34px;
  width: 34px;
  background: transparent;
  border: none;
  border-radius: 8px;
  color: var(--text-3);
  font-size: 13px;
  cursor: pointer;
  transition: background 150ms, color 150ms;
  padding: 0;
  margin: 0;            /* reset Pico's button margin-bottom — was spreading the rows ~16px apart */
  display: flex;
  align-items: center;
  justify-content: center;
}

.dp-day:hover:not(:disabled) {
  background: var(--hairline);
  color: var(--text-primary);
}

.dp-day:focus-visible {
  outline: 2px solid var(--c-blue);
  outline-offset: 1px;
}

.dp-day.is-today {
  box-shadow: inset 0 0 0 1.5px var(--c-blue);
}

.dp-day.is-selected {
  background: var(--c-blue);
  color: var(--text-2);
  font-weight: 600;
}

.dp-day.is-selected.is-today {
  box-shadow: none;
}

.dp-day.is-adjacent {
  color: var(--surface-17);
}

/* Year list quick-jump */
.dp-year-list {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
  margin-bottom: 8px;
}

.dp-year-cell {
  height: 32px;
  background: transparent;
  border: none;
  border-radius: 6px;
  color: var(--text-3);
  font-size: 13px;
  cursor: pointer;
  transition: background 150ms, color 150ms;
  padding: 0;
}

.dp-year-cell:hover {
  background: var(--hairline);
  color: var(--text-primary);
}

.dp-year-cell.is-selected {
  background: var(--c-blue);
  color: var(--text-2);
  font-weight: 600;
}

/* Footer */
.dp-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-top: 1px solid var(--wa-08);
  padding-top: 8px;
  margin-top: 4px;
}

.dp-footer-btn {
  background: transparent;
  border: none;
  color: var(--text-muted);
  font-size: 12px;
  padding: 4px 8px;
  border-radius: 6px;
  cursor: pointer;
  transition: color 150ms, background 150ms;
}

.dp-footer-btn:hover {
  color: var(--text-primary);
  background: var(--hairline);
}

.dp-footer-btn--today {
  color: var(--c-blue);
}

.dp-footer-btn--today:hover {
  color: var(--c-blue-14);
  background: var(--c-blue-a08);
}

/* ── Concentration block ─────────────────────────────────────────── */

/* Card surface — mirrors .metric-card--velocity uniform border */
.metric-card--concentration {
  background: var(--surface-card);
  border: 1px solid var(--wa-08);
  border-left: 1px solid var(--wa-08);
  border-radius: 16px;
  padding: 20px 22px;
}

/* View containers — only active one shown (same pattern as .tops-view) */
.conc-view {
  display: none;
}

.conc-view--active {
  display: block;
}

/* No-data muted note */
.conc-no-data {
  font-size: 14px;
  color: var(--text-muted);
  margin: 0;
}

/* ── HHI gauge row ───────────────────────────────────────────────── */

.conc-gauge-row {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 14px;
}

/* Three-zone track: green 0-15% / amber 15-25% / red 25-100% (1500/2500/10000) */
.conc-gauge__track {
  position: relative;
  height: 10px;
  border-radius: 999px;
  /* Smooth green→amber→red blend that still turns over AROUND the risk thresholds
     (transition zones, not hard blocks) so the marker colour stays meaningful — a
     'высокая' value lands in solid red, not amber (260627). */
  background: linear-gradient(
    90deg,
    var(--c-green) 0%,
    var(--c-green) 10%,
    var(--c-amber) 18%,
    var(--c-red) 28%,
    var(--c-red) 100%
  );
  /* Clip the gradient to the rounded pill (no colour spill past the corners). overflow
     stays visible so the white marker tick can still stick out above/below the track. */
  background-clip: padding-box;
  overflow: visible;
}

/* Marker: a vertical tick at the HHI position */
.conc-gauge__marker {
  position: absolute;
  top: -3px;
  width: 3px;
  height: 16px;
  background: var(--text-primary);
  border-radius: 2px;
  transform: translateX(-50%);
  box-shadow: 0 0 4px var(--sc-50);
}

/* HHI value + zone pill row */
.conc-gauge-label {
  display: flex;
  align-items: center;
  gap: 10px;
}

.conc-hhi-value {
  font-size: 22px;
  font-weight: 600;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

/* Zone pill */
.conc-zone-pill {
  font-size: 12px;
  font-weight: 600;
  padding: 2px 10px;
  border-radius: 999px;
  text-transform: lowercase;
}

.conc-zone-pill--low {
  background: var(--c-green-a15);
  color: var(--c-green);
}

.conc-zone-pill--moderate {
  background: var(--c-amber-a15);
  color: var(--c-amber);
}

.conc-zone-pill--high {
  background: var(--c-red-a15);
  color: var(--c-red);
}

/* ── CR tiles: 3-up grid ─────────────────────────────────────────── */

.operations-tiles--three {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.conc-cr-tiles {
  margin-bottom: 14px;
}

/* ── Pareto note ─────────────────────────────────────────────────── */

.conc-pareto-note {
  font-size: 13px;
  color: var(--text-muted);
  margin: 0 0 8px;
}

.conc-pareto-note strong {
  color: var(--text-primary);
}

/* ── Pareto cumulative bar ───────────────────────────────────────── */

.conc-pareto {
  margin-top: 4px;
}

.conc-pareto__track {
  position: relative;
  height: 10px;
  border-radius: 999px;
  background: var(--surface-tile);
  overflow: visible;
}

.conc-pareto__fill {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--c-blue), var(--c-amber));
  /* Clip the fill to the rounded pill so the gradient never spills past the corners. */
  background-clip: padding-box;
}

/* 80% marker line */
.conc-pareto__marker80 {
  position: absolute;
  left: 80%;
  top: -4px;
  width: 2px;
  height: 18px;
  background: var(--wa-35);
  border-radius: 1px;
  transform: translateX(-50%);
}

/* Tick labels beneath the bar */
.conc-pareto__ticks {
  position: relative;
  height: 16px;
  margin-top: 4px;
}

.conc-pareto__tick {
  position: absolute;
  font-size: 10px;
  color: var(--surface-1);
  transform: translateX(-50%);
  white-space: nowrap;
}

/* ── LTV / повторные block ───────────────────────────────────────── */

/* Card surface — mirrors .metric-card--velocity / --concentration uniform border */
.metric-card--ltv {
  background: var(--surface-card);
  border: 1px solid var(--wa-08);
  border-left: 1px solid var(--wa-08);  /* override base 3px left-accent */
  border-radius: 16px;
  padding: 20px 22px;
}

/* «за всё время» badge — muted pill next to the card title */
.ltv-lifetime-badge {
  margin-left: auto;
  font-size: 11px;
  font-weight: 500;
  color: var(--text-muted);
  background: var(--nx-5-a12);
  border: 1px solid var(--nx-11-a20);
  border-radius: 999px;
  padding: 2px 8px;
  white-space: nowrap;
  flex-shrink: 0;
}

/* No-data muted note */
.ltv-no-data {
  font-size: 14px;
  color: var(--text-muted);
  margin: 0;
}

/* Top-5 section header */
.ltv-top-section {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--wa-07);
}

.ltv-top-title {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
  margin: 0 0 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* =============================================================================
   Payments «Оплата» section (Wave 4 — 260618-lpx)
   Consistent with .deal-detail-section pattern (КОММЕНТАРИИ / ФАЙЛЫ).
   No colored left-stripes; compact for the ½-width detail modal.
   ============================================================================= */

/* ── Section wrapper ─────────────────────────────────────────────────────── */
.deal-payments {
  margin-bottom: 16px;
}

/* ── Header row: «ОПЛАТА» title (left) + paid summary (right) ────────────── */
.deal-payments__header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin: 0 0 10px 0;
}

/* «ОПЛАТА» — mirrors .deal-detail-section__title exactly */
.deal-payments__title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
}

/* Summary right-aligned muted */
.deal-payments__summary {
  font-size: 13px;
  color: var(--text-muted);
  text-align: right;
  min-width: 0;
  overflow-wrap: anywhere;
  font-variant-numeric: tabular-nums;
}

/* ── Progress bar ────────────────────────────────────────────────────────── */
.pay-progress {
  height: 6px;
  border-radius: 999px;
  background: var(--surface-tile);
  overflow: hidden;
  width: 100%;
  margin-bottom: 8px;
}

.pay-progress__fill {
  /* display:block is required — the fill is a <span> (inline by default), and inline
     elements ignore height/width, so the gradient rendered with a 0-height box and the
     bar looked empty (260618-nis). block makes height:100% + the inline width:{percent}% real. */
  display: block;
  height: 100%;
  border-radius: 999px;
  /* Single shared payment-scale fill — red→amber→green. Reuse `.pay-progress__fill`
     anywhere a payment progress scale is rendered so the gradient stays consistent. */
  background: linear-gradient(90deg, var(--c-red), var(--c-amber), var(--c-green));
  transition: width 200ms ease-out;
}

/* ── Status tag line (under the bar): «Оплачено полностью» / «Осталось N $» ── */
.pay-status-tag {
  font-size: 12px;
  color: var(--text-muted);
  margin: 0 0 10px;
  font-variant-numeric: tabular-nums;
}

/* Semantic status colors (approved mock 260722): green when fully paid,
   amber while payments remain — matches the app-wide color code. */
.pay-status-tag--paid { color: var(--c-green); }
.pay-status-tag--due  { color: var(--c-amber); }

/* ── Payments list ───────────────────────────────────────────────────────── */
.pay-list {
  list-style: none;
  padding: 2px 10px;
  margin: 0 0 10px 0;
  background: var(--surface-inset);
  border-radius: 10px;
}

.pay-list__item {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 34px;
  padding: 4px 0;
  border-bottom: 1px solid var(--wa-05);
}

.pay-list__item:last-child {
  border-bottom: none;
}

.pay-list__icon {
  flex-shrink: 0;
  color: var(--text-muted);
  display: inline-flex;
  align-items: center;
}

.pay-list__date {
  font-size: 13px;
  color: var(--text-1);
  white-space: nowrap;
}

.pay-list__amount {
  margin-left: auto;
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Credit = received payment — green */
.pay-list__amount--credit {
  color: var(--c-green);
}

/* Empty state */
.pay-list__empty {
  font-size: 13px;
  color: var(--text-muted);
  padding: 6px 0;
}

/* Auto-payment tag — subtle muted pill, mirrors .defect-badge--free */
.pay-auto-tag {
  display: inline-flex;
  align-items: center;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  border-radius: 5px;
  padding: 1px 5px;
  white-space: nowrap;
  background: var(--nx-12-a10);
  color: var(--text-muted);
  flex-shrink: 0;
}

/* ── Delete button ───────────────────────────────────────────────────────── */
/* Reuses the .deal-row-delete pattern (muted → red on hover); scoped to
   .pay-del to keep specificity clean. */
.pay-del {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  margin: 0;
  border: none;
  border-radius: 7px;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.pay-del:hover {
  background: var(--c-red-a12);
  color: var(--c-red);
}

/* ── Add-payment form — compact inline row ───────────────────────────────── */
/* Wraps gracefully inside the ½-width detail modal. */
.pay-add-form {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 6px;
  margin-top: 10px;
}

/* Amount input: grows to fill space, mirrors .deal-form-input dark look. */
/* Scoped within .deal-payments to never touch global <input>. */
.deal-payments .pay-add-form__amount {
  flex: 1 1 90px;
  min-width: 72px;
  background: var(--surface-tile);
  border: 1px solid var(--wa-10);
  border-radius: 10px;
  padding: 0 10px;
  height: 42px;
  /* min-height defeats the inherited input.deal-form-input min-height (~52px) which,
     under the row's align-items:stretch, was making this field + the datepicker taller
     than the currency box. All three add-row fields share one height (260618-mni). */
  min-height: 42px;
  box-sizing: border-box;
  font-size: 14px;
  color: var(--text-primary);
  margin: 0;
  transition: border-color var(--transition-fast);
}

.deal-payments .pay-add-form__amount:focus {
  border-color: var(--c-blue-a50);
  outline: none;
  box-shadow: none;
}

/* Currency box — compact version of .deal-form-currency. */
.deal-payments .pay-add-form__currency {
  position: relative;
  flex: 0 0 auto;
  width: 56px;
  height: 42px;
  min-height: 42px;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-tile);
  border: 1px solid var(--wa-08);
  border-radius: 10px;
}

/* The currency <select> is invisible but covers the full box for interaction. */
.deal-payments .deal-form-currency__select {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  border: none;
  background: transparent;
}

/* Datepicker widget in the add-row — same 42px height as the amount + currency fields.
   The .datepicker wrapper is the flex child; give it the height so it stops stretching
   to the inherited min-height, and let the display fill it. */
.deal-payments .pay-add-form .datepicker {
  flex: 0 0 118px;
  width: 118px;
  height: 42px;
  min-height: 42px;
  box-sizing: border-box;
}

.deal-payments .datepicker__display {
  height: 42px;
  min-height: 42px;
  margin: 0;
  background: var(--surface-tile);
  border: 1px solid var(--wa-10);
  border-radius: 10px;
  font-size: 14px;
  color: var(--text-primary);
  padding: 0 10px;
  box-sizing: border-box;
}

.deal-payments .datepicker__display:focus {
  border-color: var(--c-blue-a50);
  outline: none;
  box-shadow: none;
}

/* «Внести» submit button — compact blue outline (mirrors «Добавить»). */
.pay-add-form__submit {
  flex: 0 0 auto;
  height: 42px;
  min-height: 42px;
  padding: 0 14px;
  font-size: 14px;
  font-weight: 500;
  border: 1px solid rgba(47,107,255,0.5);
  border-radius: 10px;
  background: transparent;
  color: var(--c-blue-9);
  margin-bottom: 0;
  cursor: pointer;
  transition: background var(--transition-fast), opacity var(--transition-fast);
  white-space: nowrap;
}

.pay-add-form__submit:hover {
  background: rgba(47,107,255,0.08);
}

.pay-add-form__submit:active {
  opacity: 0.85;
}

/* Focus ring only for keyboard (a11y); no ring on mouse click. */
.pay-add-form__submit:focus:not(:focus-visible) {
  outline: none;
  box-shadow: none;
}

.pay-add-form__submit:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px rgba(47,107,255,0.5);
}

/* Inline error below the form */
.pay-add-form__error {
  flex: 1 0 100%;
  font-size: 12px;
  color: var(--c-red);
  margin: 0;
}

/* ── «Завершить сделку» button ───────────────────────────────────────────── */
.pay-complete-btn {
  display: inline-flex;
  align-items: center;
  height: 36px;
  padding: 0 16px;
  font-size: 13px;
  font-weight: 500;
  border-radius: 10px;
  border: 1px solid var(--c-green-a35);
  background: var(--c-green-a10);
  color: var(--c-green);
  cursor: pointer;
  margin-bottom: 10px;
  transition: background var(--transition-fast), border-color var(--transition-fast);
}

.pay-complete-btn:hover {
  background: var(--c-green-a18);
  border-color: var(--c-green-a55);
}

/* =============================================================================
   Defects «Брак / замена» section
   Tokens: bg #0d1320 / surface #131c2e / border rgba(255,255,255,.08)
   blue #22e754 / amber #f0a83c / red #ff6b6b / muted #7d8aa0
   ============================================================================= */

.deal-defects {
  margin-bottom: 16px;
}

/* ── Header row: «БРАК / ЗАМЕНА» title (left) + impact summary (right) ──────── */
.deal-defects__header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin: 0 0 10px 0;
}

/* «БРАК / ЗАМЕНА» — mirrors .deal-payments__title exactly */
.deal-defects__title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
}

/* Right-hand impact summary (shown only when defects exist) */
.deal-defects__summary {
  font-size: 13px;
  color: var(--text-muted);
  text-align: right;
  min-width: 0;
  overflow-wrap: anywhere;
  font-variant-numeric: tabular-nums;
}

/* The «−X cur» impact number in the summary — red */
.deal-defects__impact-num {
  color: var(--c-red);
  font-weight: 600;
}

/* ── Defect list ──────────────────────────────────────────────────────────── */
.defect-list {
  list-style: none;
  padding: 0;
  margin: 0 0 10px 0;
}

.defect-list__item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 0;
  border-bottom: 1px solid var(--wa-05);
  flex-wrap: wrap;
}

.defect-list__item:last-child {
  border-bottom: none;
}

.defect-list__icon {
  flex-shrink: 0;
  color: var(--c-amber);  /* amber — defect indicator */
  display: inline-flex;
  align-items: center;
}

.defect-list__meta {
  font-size: 13px;
  color: var(--text-1);
  white-space: nowrap;
}

/* Muted note text */
.defect-note {
  font-size: 12px;
  color: var(--text-muted);
  min-width: 0;
  overflow-wrap: anywhere;
}

/* Right cluster: badge + delete button */
.defect-list__right {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}

/* Empty state */
.defect-list__empty {
  font-size: 13px;
  color: var(--text-muted);
  padding: 6px 0;
}

/* ── Resolution badges ───────────────────────────────────────────────────── */
.defect-badge {
  display: inline-flex;
  align-items: center;
  font-size: 12px;
  font-weight: 500;
  border-radius: 6px;
  padding: 2px 7px;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* own_cost + refund: red pill (financial loss) */
.defect-badge--cost,
.defect-badge--refund {
  background: var(--c-red-a12);
  color: var(--c-red);
}

/* seller_free: muted pill (no financial impact) */
.defect-badge--free {
  background: var(--nx-5-a12);
  color: var(--text-muted);
}

/* ── Delete button — mirrors .pay-del exactly ────────────────────────────── */
.defect-del {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  margin: 0;
  border: none;
  border-radius: 7px;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.defect-del:hover {
  background: var(--c-red-a12);
  color: var(--c-red);
}

/* ── Shared separated-pill segmented toggle (seg-pills) ─────────────────────
   Used by: defect resolution, period selector, object-metric sort.
   align-items:stretch → pills fill the container's cross-axis height:
   44px in the period row, ~34px elsewhere — one block, contextual height. */
.seg-pills {
  display: flex;
  gap: 8px;
  align-items: stretch;
  /* Neutralize Pico's [role=group] box-shadow ring (260627). The toggle containers carry
     role=group, so Pico draws a blue box-shadow around the WHOLE group when any button inside
     is focused (after a click, while focus persists) via --pico-group-box-shadow-focus-with-button.
     Earlier fixes targeted .seg-pills__btn, but the ring lives on the GROUP container. Selection
     is shown by the solid-blue .is-active pill, so no group ring is needed. */
  --pico-group-box-shadow: none;
  --pico-group-box-shadow-focus-with-button: 0 0 0 transparent;
  --pico-group-box-shadow-focus-with-input: 0 0 0 transparent;
}

.seg-pills__btn {
  flex: 1;
  min-height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 12px;
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  border: 1px solid var(--wa-08);
  /* fully-rounded pill on EVERY segment (per brief). !important overrides Pico's [role=group]
     button-group rounding (it rounds only first/last + squares the middle) on the period +
     object-metric toggles, which carry role=group (260618-vys). */
  border-radius: 999px !important;
  background: var(--surface-tile);        /* inactive = dark tile (per brief) — all 3 toggles identical */
  color: var(--text-muted);
  cursor: pointer;
  box-sizing: border-box;
  transition: background var(--transition-fast), color var(--transition-fast),
              border-color var(--transition-fast);
}

.seg-pills__btn.is-active {
  background: var(--c-blue);
  border-color: var(--c-blue);
  color: var(--text-2);
}

.seg-pills__btn:hover:not(.is-active) {
  background: var(--c-blue-a10);
  border-color: var(--c-blue-a35);
}

/* No blue focus ring on the segmented toggles — for BOTH mouse clicks AND the focus
   HTMX programmatically restores to the button after the hx-get fragment swap (browsers
   treat programmatic focus as :focus-visible, so the old :focus:not(:focus-visible) reset
   below did not catch it). Selection is already shown by the solid-blue .is-active pill, so
   no ring is needed (260627). Note: also drops the keyboard focus ring on these toggles. */
.seg-pills__btn:focus:not(:focus-visible),
.seg-pills__btn:focus-visible {
  outline: none;
  box-shadow: none;
}

/* ── .chip-group — neutralize Pico's [role=group] focus ring ────────────────
   Any chip/pill container carrying role=group makes Pico draw a blue box-shadow
   around the WHOLE group when a button inside is focused (e.g. after a mouse
   click, while focus persists) via --pico-group-box-shadow-focus-with-button.
   Add this utility to such containers; per-button :focus-visible rings stay on
   the buttons themselves for keyboard a11y. Same pattern as .seg-pills (260720-gtu). */
.chip-group {
  --pico-group-box-shadow: none;
  --pico-group-box-shadow-focus-with-button: 0 0 0 transparent;
  --pico-group-box-shadow-focus-with-input: 0 0 0 transparent;
}

/* ── Segmented resolution toggle — transparent track, solid active pill ───── */
.defect-seg {
  display: flex;
  gap: 8px;
  margin-bottom: 8px;
}
/* .defect-seg__btn look supplied by .seg-pills__btn (shared class added in markup).
   Mini-segment override: content-width pills instead of the shared .seg-pills__btn's
   flex:1 (which stretches the 3 defect-type pills full-width). Do NOT touch the shared
   .seg-pills / .seg-pills__btn rules — also used by the period + object-sort toggles. */
.defect-seg .seg-pills__btn {
  flex: 0 0 auto;
}

/* ── Add-defect form — compact 42px equal-height row ─────────────────────── */
.defect-add-form {
  margin-top: 4px;
}

.defect-add-row {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 6px;
}

/* Units field (~80px) */
.deal-defects .defect-add-form__units {
  flex: 0 0 80px;
  width: 80px;
  background: var(--surface-tile);
  border: 1px solid var(--wa-10);
  border-radius: 10px;
  padding: 0 10px;
  height: 34px;
  min-height: 34px;
  box-sizing: border-box;
  font-size: 14px;
  color: var(--text-primary);
  margin: 0;
  transition: border-color var(--transition-fast);
}

.deal-defects .defect-add-form__units:focus {
  border-color: var(--c-blue-a50);
  outline: none;
  box-shadow: none;
}

/* Amount + currency wrapper — hides as a unit for seller_free */
.defect-amount-wrap {
  display: flex;
  align-items: stretch;
  gap: 6px;
  flex: 1 1 160px;
  min-width: 0;
}

/* Amount input */
.deal-defects .defect-add-form__amount {
  flex: 1 1 90px;
  min-width: 72px;
  background: var(--surface-tile);
  border: 1px solid var(--wa-10);
  border-radius: 10px;
  padding: 0 10px;
  height: 34px;
  min-height: 34px;
  box-sizing: border-box;
  font-size: 14px;
  color: var(--text-primary);
  margin: 0;
  transition: border-color var(--transition-fast);
}

.deal-defects .defect-add-form__amount:focus {
  border-color: var(--c-blue-a50);
  outline: none;
  box-shadow: none;
}

/* Inline-validation error: red border (overrides the base + focus border for this input,
   which otherwise win by source order over .deal-form-input[aria-invalid]). (260619-vng) */
.deal-defects .defect-add-form__amount[aria-invalid="true"],
.deal-defects .defect-add-form__amount[aria-invalid="true"]:focus {
  border-color: var(--c-red-a70);
}

/* Currency box — mirrors .deal-payments .pay-add-form__currency */
.deal-defects .defect-add-form__currency {
  position: relative;
  flex: 0 0 auto;
  width: 72px;
  height: 34px;
  min-height: 34px;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-tile);
  border: 1px solid var(--wa-08);
  border-radius: 10px;
}

/* The currency <select> is invisible but covers the full box */
.deal-defects .deal-form-currency__select {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  border: none;
  background: transparent;
}

/* Note input */
.deal-defects .defect-add-form__note {
  flex: 1 1 120px;
  min-width: 80px;
  background: var(--surface-tile);
  border: 1px solid var(--wa-10);
  border-radius: 10px;
  padding: 0 10px;
  height: 34px;
  min-height: 34px;
  box-sizing: border-box;
  font-size: 14px;
  color: var(--text-primary);
  margin: 0;
  transition: border-color var(--transition-fast);
}

.deal-defects .defect-add-form__note:focus {
  border-color: var(--c-blue-a50);
  outline: none;
  box-shadow: none;
}

/* Datepicker widget in the add-row — 34px, mirrors .deal-tasks .task-add-form .datepicker */
.deal-defects .defect-add-row .datepicker {
  flex: 1 1 130px;
  height: 34px;
  min-height: 34px;
  box-sizing: border-box;
}

.deal-defects .datepicker__display {
  height: 34px;
  min-height: 34px;
  margin: 0;
  background: var(--surface-tile);
  border: 1px solid var(--wa-10);
  border-radius: 10px;
  font-size: 14px;
  color: var(--text-primary);
  padding: 0 10px;
  box-sizing: border-box;
}

.deal-defects .datepicker__display:focus {
  border-color: var(--c-blue-a50);
  outline: none;
  box-shadow: none;
}

/* «Отметить» submit button — compact blue outline (mirrors .task-add-form__submit /
   .pay-add-form__submit), right-aligned under the row via .defect-add-actions. */
.defect-add-form__submit {
  flex: 0 0 auto;
  height: 34px;
  padding: 0 14px;
  font-size: 13px;
  font-weight: 500;
  background: transparent;
  border: 1px solid rgba(47,107,255,0.5);
  color: var(--c-blue-9);
  border-radius: 10px;
  margin-bottom: 0;
  width: auto;
  cursor: pointer;
  transition: background var(--transition-fast), opacity var(--transition-fast);
  white-space: nowrap;
}

/* ── Deal-detail section submits: kill Pico's full-width (260722) ──────────
   Pico's `button[type=submit]{width:100%}` is (0,1,1) — one ELEMENT more
   than our single-class (0,1,0) `width:auto` rules above, so every section
   submit stretched to 100%, wrapped onto its own flex line and filled it
   (the «full-width blue band» look the mock replaced). Element-qualified
   selectors tie Pico at (0,1,1); theme.css loads after the vendor file, so
   source order breaks the tie our way. Same trap k7s documented for the
   .form-actions footer buttons. */
button.task-add-form__submit,
button.pay-add-form__submit,
button.deal-comment-form__submit,
button.deal-attachment-form__submit,
button.defect-add-form__submit {
  width: auto;
  flex: 0 0 auto;
}

/* Comment submit: compact, right-aligned under the textarea (approved mock) —
   in the column-flex .deal-comment-form `align-self:flex-end` both
   un-stretches the button and pins it right. */
button.deal-comment-form__submit {
  align-self: flex-end;
}

.defect-add-form__submit:hover {
  background: rgba(47,107,255,0.08);
}

.defect-add-form__submit:active {
  opacity: 0.85;
}

.defect-add-form__submit:focus:not(:focus-visible) {
  outline: none;
  box-shadow: none;
}

.defect-add-form__submit:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px rgba(47,107,255,0.5);
}

.defect-add-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 8px;
}

/* ── Маржа tile: red «−X cur брак» annotation ────────────────────────────── */
.deal-margin-defect {
  color: var(--c-red);
}

/* ── Analytics help badge + popover ─────────────────────────────────────────
   Clip-safety note: .metric-card has NO overflow:hidden (base rule uses only
   border-left + border-radius + padding + transition), so z-index:1000 is
   sufficient to place the popover above siblings.
   .operations-header also has no overflow:hidden (display:flex + align-items +
   gap + margin-bottom only).
   However, as a defensive measure we explicitly set overflow:visible on any
   .operations-header that hosts the badge so future changes don't silently clip.
   ──────────────────────────────────────────────────────────────────────────── */

/* Defensive: keep header overflow visible so the popover is never clipped */
.metric-card .operations-header {
  overflow: visible;
}

/* Wrapper — relative anchor for the absolutely-positioned popover */
.help-badge-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
}

/* The «?» circle button */
.help-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 1px solid var(--wa-12);
  background: transparent;
  color: var(--text-muted);
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  transition: background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}

.help-badge:hover,
.help-badge:focus-visible {
  background: var(--c-blue-a12);
  border-color: var(--c-blue-a50);
  color: var(--c-blue);
  outline: none;
}

/* Popover panel — hidden by default */
.help-pop {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;

  /* position:fixed so the popover is viewport-relative and JS can clamp it to the screen
     edges (no clipping on left/right blocks). left/top are set by analytics-help.js on show;
     the 0/0 fallback only applies for the brief moment before JS positions it. (260619-tih) */
  position: fixed;
  top: 0;
  left: 0;
  width: 236px;
  max-width: calc(100vw - 16px);
  z-index: 1000;

  background: var(--surface-9);
  border: 1px solid var(--wa-12);
  border-radius: 12px;
  padding: 11px 13px;
  box-shadow: 0 12px 30px var(--sc-50);
  text-align: left;

  display: flex;
  flex-direction: column;
  gap: 3px;

  transition: opacity 120ms ease-out, visibility 120ms ease-out;
}

/* Visibility is JS-driven via `.is-open` (analytics-help.js) — NO CSS :hover/:focus-within rule:
   the popover is portaled to <body> on open, so it's no longer a descendant of the badge wrap and
   those selectors couldn't match anyway. JS adds .is-open on hover/focus/tap after positioning. */
.help-pop.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

/* Section labels: «ЧТО ПОКАЗЫВАЕТ» / «КАК СЧИТАЕТСЯ» */
.help-pop__label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--surface-1);
  font-weight: 600;
  line-height: 1.2;
}

/* Second label gets a small top gap to visually separate the two sections */
.help-pop__label--gap {
  margin-top: 6px;
}

/* Body text */
.help-pop__text {
  font-size: 12px;
  color: var(--text-3);
  line-height: 1.4;
  white-space: pre-line;   /* render the newlines in the «как» text as separate lines (260619-u17) */
}

/* ── Надёжность каналов — per-seller defect rate (260619-w8d) ──────────────── */
.reliability-empty {
  color: var(--surface-1);
  font-size: 14px;
  margin: 8px 0 0;
}
.reliability-summary {
  color: var(--text-19);
  font-size: 13px;
  margin: 0 0 14px;
}
.reliability-summary strong {
  color: var(--text-primary);
  font-weight: 600;
}
.reliability-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.reliability-row {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.5fr) auto;
  align-items: center;
  gap: 12px;
}
.reliability-row__head {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.reliability-row__name {
  color: var(--text-primary);
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.reliability-row__meta {
  color: var(--surface-1);
  font-size: 12px;
}
.reliability-row__mid {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 0;
}
.reliability-bar {
  display: block;
  height: 6px;
  border-radius: 999px;
  background: var(--hairline);
  overflow: hidden;
}
.reliability-bar__fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  transition: width var(--transition-fast);
}
.reliability-bar__fill--reliable { background: var(--c-green); }
.reliability-bar__fill--ok { background: var(--c-amber); }
.reliability-bar__fill--risky { background: var(--c-red); }
.reliability-row__sub {
  color: var(--text-muted);
  font-size: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.reliability-row__right {
  display: flex;
  align-items: center;
  gap: 8px;
  justify-self: end;
}
.reliability-row__pct {
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.reliability-row__pct--reliable { color: var(--c-green); }
.reliability-row__pct--ok { color: var(--c-amber); }
.reliability-row__pct--risky { color: var(--c-red); }
.reliability-pill {
  font-size: 11px;
  font-weight: 600;
  padding: 2px 9px;
  border-radius: 999px;
  white-space: nowrap;
}
.reliability-pill--reliable { background: var(--c-green-a15); color: var(--c-green); }
.reliability-pill--ok { background: var(--c-amber-a15); color: var(--c-amber); }
.reliability-pill--risky { background: var(--c-red-a15); color: var(--c-red); }

/* ── Задачи (deal task checklist) — PART A.2 ────────────────────────────────── */
.deal-tasks {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--wa-07);
}

.deal-tasks__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}

.deal-tasks__title {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--pico-muted-color, var(--text-muted));
  text-transform: uppercase;
}

.deal-tasks__counter {
  font-size: 11px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Chip row */
.task-chips-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 10px;
}

.task-chip-form {
  margin: 0;
  padding: 0;
}

.task-chip {
  /* Pico gives <button> a 16px margin-bottom — inflated .task-chips-row to
     47px and read as a void before «Задач нет.» (convention: buttons in
     custom rows zero it). */
  margin-bottom: 0;
  font-size: 12px;
  font-weight: 500;
  padding: 5px 12px;
  border-radius: var(--radius-pill, 999px);
  border: 1px solid var(--c-blue-a45-3);
  background: var(--c-blue-a10-2);
  color: var(--accent, var(--c-blue-2));
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--transition-fast, 150ms ease-out),
              border-color var(--transition-fast, 150ms ease-out);
  line-height: 1.4;
}

.task-chip:hover {
  background: var(--c-blue-a20-2);
  border-color: var(--c-blue-a70);
}

/* Task list */
.task-list {
  list-style: none;
  margin: 0 0 10px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.task-list__item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
}

.task-list__title {
  flex: 1;
  font-size: 14px;
  color: var(--pico-color, var(--text-primary));
  line-height: 1.4;
}

/* Done state: strikethrough + muted */
.task-list__item.is-done .task-list__title {
  text-decoration: line-through;
  color: var(--pico-muted-color, var(--text-muted));
}

.task-list__empty {
  font-size: 13px;
  color: var(--pico-muted-color, var(--text-muted));
  padding: 4px 0;
}

/* Toggle button */
.task-toggle-form {
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
}

.task-toggle {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  cursor: pointer;
  color: var(--pico-muted-color, var(--text-muted));
  display: flex;
  align-items: center;
  line-height: 1;
  transition: color var(--transition-fast, 150ms ease-out);
}

.task-toggle:hover,
.task-toggle--done {
  color: var(--accent, var(--c-blue-2));
}

/* Due date */
.task-due {
  font-size: 12px;
  color: var(--pico-muted-color, var(--text-muted));
  white-space: nowrap;
}

/* Amber when past due */
.task-due--past {
  color: var(--c-amber-2);
  font-weight: 600;
}

/* Delete button */
.task-delete-form {
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
}

.task-del {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  cursor: pointer;
  color: var(--pico-muted-color, var(--text-muted));
  display: flex;
  align-items: center;
  line-height: 1;
  opacity: 0.6;
  transition: color var(--transition-fast, 150ms ease-out),
              opacity var(--transition-fast, 150ms ease-out);
}

.task-del:hover {
  color: var(--pico-del-color, var(--c-red-4));
  opacity: 1;
}

/* Soft hint */
.task-hint {
  font-size: 12px;
  color: var(--pico-muted-color, var(--text-muted));
  margin: 0 0 8px;
}

/* Add form */
.task-add-form {
  margin-top: 8px;
}

.task-add-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.task-add-form__title {
  flex: 1;
  min-width: 140px;
}

/* Class-heavy selector defeats the global input.deal-form-input ~52px min-height
   (same trick as .deal-payments .pay-add-form__amount) to pin the title input to 34px.
   margin-bottom:0 kills the Pico input margin (18px) that rode the input 9px above
   the date/button under the row's align-items:center (260722). */
.deal-tasks .task-add-form__title {
  height: 34px;
  min-height: 34px;
  box-sizing: border-box;
  margin-bottom: 0;
}

/* Compact 118px × 34px datepicker in the add-row; mirrors the .deal-payments pattern. */
.deal-tasks .task-add-form .datepicker {
  flex: 0 0 118px;
  width: 118px;
  height: 34px;
  min-height: 34px;
  box-sizing: border-box;
}

.deal-tasks .datepicker__display {
  height: 34px;
  min-height: 34px;
  box-sizing: border-box;
  margin: 0;
  background: var(--surface-tile);
  border: 1px solid var(--wa-10);
  border-radius: 10px;
  font-size: 13px;
  color: var(--text-primary);
  padding: 0 10px;
}

.deal-tasks .datepicker__display:focus {
  border-color: var(--c-blue-a50);
  outline: none;
  box-shadow: none;
}

/* «Добавить» — compact blue outline, replaces the Pico full-width blue button.
   width:auto + margin-bottom:0 undo the Pico bare-submit width:100% + margin-bottom. */
.task-add-form__submit {
  height: 34px;
  padding: 0 14px;
  width: auto;
  background: transparent;
  border: 1px solid rgba(47,107,255,0.5);
  color: var(--c-blue-9);
  border-radius: 10px;
  margin-bottom: 0;
  font-size: 13px;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--transition-fast, 150ms ease-out);
}

.task-add-form__submit:hover {
  background: rgba(47,107,255,0.08);
}

/* Focus ring only for keyboard (a11y); no ring on mouse click (project convention). */
.task-add-form__submit:focus:not(:focus-visible) {
  outline: none;
  box-shadow: none;
}

.task-add-form__submit:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px rgba(47,107,255,0.5);
}

/* ── FX Strip (PART C) ────────────────────────────────────────────────────── */

.fx-strip {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 10px 14px;
  overflow-x: auto;  /* safety on narrow windows; no scroll at normal width */
  padding: 10px 16px;
  background: var(--pico-card-background-color, var(--surface-23));
  border-radius: var(--radius-card, 16px);
  font-size: 13px;
}

.fx-group {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 8px 16px;
}

.fx-divider {
  width: 1px;
  height: 24px;
  background: var(--wa-12);
  flex-shrink: 0;
}

.fx-item {
  display: flex;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
}

.fx-icon {
  display: flex;
  align-items: center;
  color: var(--pico-muted-color, var(--text-muted));
  flex-shrink: 0;
}

.fx-strip .fx-flag,
.fx-strip .fx-logo {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  display: block;
}

/* 260708-qhj: lettered-circle fallback for a code with no vendored asset
   (fx_icon macro in _fx_strip.html / _fx_popover.html). Self-contained inline
   SVG — no /static path, no broken-image flash. */
.fx-icon-fallback {
  flex-shrink: 0;
  display: block;
}

.fx-code {
  color: var(--pico-muted-color, var(--text-muted));
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .04em;
}

.fx-value {
  font-weight: 600;
  color: var(--pico-color, var(--text-10));
}

.fx-change {
  font-size: 11px;
  font-weight: 500;
}

.fx-up {
  color: var(--c-green-3);   /* success green — iOS/macOS system green */
}

.fx-down {
  color: var(--c-red-2);   /* danger red — iOS/macOS system red */
}

.fx-flat {
  color: var(--pico-muted-color, var(--text-muted));
}

.fx-empty {
  color: var(--pico-muted-color, var(--text-muted));
  font-style: italic;
}

/* ── FX item: compact dark pill — defeat Pico's [role="button"] blue ─── */
/*
 * Pico 2 styles [role="button"] as a primary-filled block button (blue bg, block
 * padding, block display).  The .fx-item uses role="button" for a11y semantics,
 * so we must reset every state Pico touches across the full selector matrix.
 * Rules are scoped under .fx-strip so they ONLY affect the FX strip, never the
 * analytics '?' badges or any other button in the app.
 */
.fx-strip .fx-item[data-help],
.fx-strip [role="button"].fx-item {
  /* Pill geometry — compact, dark, NOT a blue block */
  display: inline-flex;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
  background: var(--surface-tile);
  border: 1px solid var(--wa-08);
  border-radius: 9px;
  padding: 6px 10px;
  box-shadow: none;
  /* Typography reset — Pico resets these to button defaults */
  color: inherit;
  font: inherit;
  line-height: normal;
  /* Size reset — Pico sets width: 100% on [role="button"] */
  width: auto;
  margin: 0;
  cursor: pointer;
  transition: background 120ms, border-color 120ms;
}
.fx-strip .fx-item[data-help]:hover,
.fx-strip [role="button"].fx-item:hover {
  background: var(--surface-4);
  border-color: var(--wa-16);
  box-shadow: none;
  color: inherit;
}
.fx-strip .fx-item[data-help]:focus,
.fx-strip [role="button"].fx-item:focus {
  background: var(--surface-tile);
  border-color: var(--wa-20);
  box-shadow: none;
  outline: none;
  color: inherit;
}
.fx-strip .fx-item[data-help]:focus-visible,
.fx-strip [role="button"].fx-item:focus-visible {
  background: var(--surface-tile);
  border-color: var(--c-blue-a40-3);
  box-shadow: 0 0 0 2px var(--c-blue-a20);
  outline: none;
  color: inherit;
}
.fx-strip .fx-item[data-help]:active,
.fx-strip [role="button"].fx-item:active {
  background: var(--surface-21);
  border-color: var(--wa-16);
  box-shadow: none;
  color: inherit;
}

/* Ensure .help-badge-wrap inside the strip lays out inline (not block) so pills
 * sit in the same horizontal row as the rest of the flex items. */
.fx-strip .help-badge-wrap {
  display: inline-flex;
}

/* ── FX price-chart popover (.fx-pop) ───────────────────────────────── */
/* Reuses .help-pop base card (#1a2438, fixed position, JS-driven .is-open).
   Only content classes are added here; positioning is handled by analytics-help.js.
   Scope all selectors under .fx-pop so nothing leaks to analytics help tooltips. */

.fx-pop.help-pop {
  /* Wider than the analytics help tooltip to fit the 120px sparkline + min/max */
  width: 210px;
  padding: 12px 12px 10px;
  gap: 6px;
}

/* Head row: flag/coin icon + full name */
.fx-pop > .fx-pop__head {
  display: flex;
  align-items: center;
  gap: 7px;
}

.fx-pop > .fx-pop__head > .fx-pop__icon {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}

.fx-pop > .fx-pop__head > .fx-pop__name {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-3);
  line-height: 1.2;
}

/* Current value — prominent */
.fx-pop > .fx-pop__value {
  font-size: 15px;
  font-weight: 700;
  color: var(--text-primary);
  line-height: 1.2;
}

/* 24h change — reuses .fx-up / .fx-down from the strip */
.fx-pop > .fx-pop__change {
  font-size: 12px;
  font-weight: 500;
}

/* Sparkline SVG */
.fx-pop__svg {
  display: block;
  width: 100%;
  height: auto;
  margin-top: 4px;
}

/* Min/max label below sparkline */
.fx-pop__minmax {
  font-size: 11px;
  color: var(--surface-1);
  margin: 2px 0 0;
  line-height: 1.3;
}

.fx-pop__minmax--empty {
  font-size: 18px;
  color: var(--surface-1);
  text-align: center;
  padding: 6px 0;
}

/* Period toggle row */
.fx-toggle-row {
  display: flex;
  gap: 4px;
  margin-top: 6px;
}

.fx-toggle {
  flex: 1;
  padding: 3px 0;
  font-size: 11px;
  font-weight: 500;
  color: var(--surface-1);
  background: var(--hairline);
  border: 1px solid var(--wa-10);
  border-radius: 6px;
  cursor: pointer;
  text-align: center;
  transition: background 100ms, color 100ms, border-color 100ms;
}

.fx-toggle:hover {
  background: var(--wa-12);
  color: var(--text-3);
}

.fx-toggle.is-active {
  background: var(--c-blue-a18);
  border-color: var(--c-blue-a40-3);
  color: var(--c-blue-15);
  font-weight: 600;
}

/* × close button inside .fx-pop popover */
/* .fx-pop__head already has display:flex via .fx-pop > .fx-pop__head above;
   add width:100% so the × can sit at the far right via margin-left:auto. */
.fx-pop > .fx-pop__head {
  width: 100%;
}
.fx-pop__close {
  /* Defeat Pico [role="button"] / button blue in every state */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  padding: 0;
  margin-left: auto;
  background: transparent;
  border: none;
  border-radius: 4px;
  box-shadow: none;
  color: var(--surface-1);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  transition: color 100ms, background 100ms;
}
.fx-pop__close:hover,
.fx-pop__close:focus,
.fx-pop__close:focus-visible,
.fx-pop__close:active {
  background: var(--wa-08);
  border: none;
  box-shadow: none;
  color: var(--text-3);
  outline: none;
}

/* ── FX chart crosshair + value hover box ────────────────────────────── */

/* Vertical dashed crosshair line — positioned by fx-chart-hover.js */
.fx-pop__crosshair {
  stroke: var(--nx-8-a45);   /* muted #c3ccdd at 45% */
  stroke-width: 1px;
  stroke-dasharray: 3 2;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}

/* Snapping dot at the nearest data point */
.fx-pop__cursor-dot {
  fill: currentColor;                  /* inherits the sparkline track color */
  color: var(--text-3);                      /* fallback muted white */
  pointer-events: none;
}

/* Value hover box — sits above the chart inside .fx-pop, flow-positioned */
.fx-pop__hover-box {
  display: block;
  font-size: 11px;
  font-weight: 500;
  color: var(--text-3);
  background: var(--wa-07);
  border-radius: 5px;
  padding: 2px 6px;
  margin-top: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
  min-height: 18px;
  line-height: 1.5;
  pointer-events: none;
}

/* ── Planner widget (PART E) ──────────────────────────────────────────── */

.planner {
  background: var(--pico-card-background-color, var(--surface-22));
  border-radius: 12px;
  padding: 1.25rem 1.5rem;
}

.planner__header {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0 0 1rem;
  font-size: 0.85rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--pico-muted-color, var(--text-muted));
}

.planner__group {
  margin-bottom: 1rem;
}

.planner__group:last-child {
  margin-bottom: 0;
}

.planner__group-label {
  margin: 0 0 0.4rem;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--pico-muted-color, var(--text-muted));
}

.planner__group-label--overdue {
  color: var(--c-amber-2);  /* amber — matches .task-due--past */
}

.planner__list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.planner__item {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
}

.planner__link {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  text-decoration: none;
  color: inherit;
}

.planner__link:hover .planner__title {
  text-decoration: underline;
  color: var(--pico-primary, var(--c-blue-13));
}

.planner__title {
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--pico-color, var(--text-10));
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.planner__deal {
  font-size: 0.75rem;
  color: var(--pico-muted-color, var(--text-muted));
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.planner__due {
  flex-shrink: 0;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--pico-muted-color, var(--text-muted));
  white-space: nowrap;
}

.planner__due--overdue {
  color: var(--c-red-2);  /* iOS danger red */
}

.planner__due--today {
  color: var(--c-amber-2);  /* amber — highlights today's tasks */
}

.planner__empty {
  margin: 0;
  font-size: 0.9rem;
  color: var(--pico-muted-color, var(--text-muted));
  font-style: italic;
}

/* ── Home page command-center restyle (260627-r2a) ───────────────────────────
   All rules scoped under #home-body or home/today-actions/home-tiles/ classes.
   Does NOT affect analytics, deals, or any other page.
   ────────────────────────────────────────────────────────────────────────── */

/* ── Shared metric-card value color modifiers (used by home tiles + elsewhere) */
.metric-card__value--green  { color: var(--c-green); }
.metric-card__value--amber  { color: var(--c-amber); }
.metric-card__value--muted  { color: var(--text-muted); }
.metric-card__value--red    { color: var(--c-red); }
.metric-card--muted         { opacity: 0.7; }
.metric-card--warning       { border-left-color: var(--c-amber) !important; }

/* ── Page chrome ─────────────────────────────────────────────────────────── */
#home-body {
  max-width: 1080px;
  margin: 0 auto;
  padding: 0 16px 40px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Strip default link and heading styles within the home scope */
#home-body a {
  color: inherit;
  text-decoration: none;
}

/* ── FX strip spacing tweak ──────────────────────────────────────────────── */
#home-body .fx-strip {
  margin-bottom: 0;  /* gap handled by #home-body flex gap */
}

/* ── Section group-label headers (Финансы, Пайплайн) ────────────────────── */
/* Muted UPPERCASE letter-spaced caption — mirrors .analytics-group-label */
.home-tiles__group-label,
.home-tiles__group-label--finance,
.home-tiles__group-label--pipeline {
  color: var(--text-1);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin: 0 0 8px;
  padding-top: 4px;
  border-top: 1px solid var(--wa-08);
}

/* First group: no top border — it follows directly after .today-actions */
.home-tiles__group:first-child .home-tiles__group-label {
  border-top: none;
  padding-top: 0;
}

/* ── Tile grid — compact 4-up (Finance) + 3-up (Pipeline) responsive ─────── */
.home-tiles__row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
}

/* On narrow screens fall to 2-col */
@media (max-width: 520px) {
  .home-tiles__row {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Tile sizing: compact — override the giant .metric-card base padding/font */
#home-body .metric-card.deal-detail-tile {
  background: var(--surface-tile);
  border: 1px solid var(--wa-08);
  border-radius: 14px;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  border-left: 1px solid var(--wa-08); /* override base 3px accent */
}

#home-body .metric-card.deal-detail-tile:hover {
  box-shadow: 0 4px 16px var(--sc-40);
  transform: translateY(-1px);
}

/* Compact label and value sizes for home tiles */
#home-body .metric-card.deal-detail-tile .metric-card__label {
  font-size: 12px;
  color: var(--text-1);
  margin: 0;
}

#home-body .metric-card.deal-detail-tile .metric-card__value {
  font-size: 22px;
  font-weight: 600;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
  margin: 0;
}

#home-body .metric-card.deal-detail-tile .metric-card__sub {
  display: block;   /* override the two-col grid from the global rule */
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 2px;
}

/* ── «Сегодня обязательно» card ──────────────────────────────────────────── */
.today-actions {
  background: var(--surface-card);
  border: 1px solid var(--c-red-a30);   /* subtle red accent border */
  border-radius: 16px;
  padding: 16px 20px;
}

/* Header: muted uppercase caption — mirrors .planner__header */
.today-actions__header {
  color: var(--text-1);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin: 0 0 12px;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

/* Action list: no default list chrome */
.today-actions__list {
  list-style: none;
  padding: 0;
  margin: 0;
}

/* Each action row */
.today-actions__item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 8px;
  border-radius: 8px;
  border-top: 1px solid var(--hairline);
  transition: background var(--transition-fast, 150ms ease);
  position: relative;
}

.today-actions__item:first-child {
  border-top: none;
}

.today-actions__item:hover {
  background: var(--surface-row);
}

/* Icon: inherits kind color via sibling rules below */
.today-actions__icon {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  color: var(--text-muted);   /* default muted */
}

/* Colored dot per kind via ::before on the item */
.today-actions__item::before {
  content: '';
  display: block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--text-muted);   /* default / stale */
}

.today-actions__item--payment::before      { background: var(--c-red); }
.today-actions__item--defect::before       { background: var(--c-amber); }
.today-actions__item--stale::before        { background: var(--text-muted); }
.today-actions__item--subscription::before { background: var(--c-blue); }
.today-actions__item--task::before         { background: var(--c-blue); }

/* Icon color mirrors dot color */
.today-actions__item--payment .today-actions__icon      { color: var(--c-red); }
.today-actions__item--defect  .today-actions__icon      { color: var(--c-amber); }
.today-actions__item--stale   .today-actions__icon      { color: var(--text-muted); }
.today-actions__item--subscription .today-actions__icon { color: var(--c-blue); }
.today-actions__item--task    .today-actions__icon      { color: var(--c-blue); }

/* Label link: white, no underline */
.today-actions__label {
  color: var(--text-primary);
  text-decoration: none;
  font-size: 14px;
  font-weight: 500;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.today-actions__item:hover .today-actions__label {
  color: var(--c-blue-8);
}

/* Detail text (optional) */
.today-actions__detail {
  font-size: 12px;
  color: var(--text-muted);
  white-space: nowrap;
  flex-shrink: 0;
}

/* Empty state */
.today-actions__empty {
  color: var(--text-muted);
  font-size: 14px;
  font-style: italic;
  margin: 0;
}

/* ── Ближайшие подписки section ──────────────────────────────────────────── */
.home-upcoming-subs {
  background: var(--surface-card);
  border: 1px solid var(--wa-08);
  border-radius: 16px;
  padding: 16px 20px;
}

.home-upcoming-subs__header {
  color: var(--text-1);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin: 0 0 12px;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.home-upcoming-subs__list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.home-upcoming-subs__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 0;
  border-top: 1px solid var(--hairline);
}

.home-upcoming-subs__item:first-child {
  border-top: none;
}

.home-upcoming-subs__name {
  font-size: 14px;
  color: var(--text-primary);
  text-decoration: none;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.home-upcoming-subs__name:hover {
  color: var(--c-blue-8);
  text-decoration: underline;
}

.home-upcoming-subs__amount {
  font-size: 13px;
  color: var(--text-muted);
  white-space: nowrap;
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}

/* ── Planner: scoped spacing within home ─────────────────────────────────── */
/* No global .planner changes — only container-level margin handled by
   the #home-body flex gap. Planner is already styled. */


/* ══════════════════════════════════════════════════════════════════════════════
   Calendar + agenda (260627-sqh PART 2)
   Tokens: card #0d1320, tile #131c2e, caption #9aa6bd, value #e8eef7,
           green #30d158, amber #f0a83c, red #ff453a, blue #22e754, muted #7d8aa0
   ══════════════════════════════════════════════════════════════════════════════ */

/* ── Two-month calendar block wrapper (PART 2 minimal; PART 4 re-grids) ─── */
.home-calendar-block {
  display: flex;
  gap: 12px;
  align-items: flex-start;
}

/* ── Calendar card ───────────────────────────────────────────────────────── */
.home-calendar {
  background: var(--surface-card);
  border-radius: 12px;
  padding: 16px;
  flex: 0 0 auto;
}

.home-calendar__header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 14px;
  color: var(--text-1);
}

.home-calendar__caption {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-1);
}

.home-calendar__months {
  display: flex;
  gap: 24px;
  flex-wrap: wrap;
  justify-content: flex-start;
}

.home-calendar__month {
  flex: 0 0 auto;
}

.home-calendar__month-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 8px;
  text-align: center;
}

/* 8-column grid: week-number + 7 days */
.home-calendar__grid {
  display: grid;
  grid-template-columns: 20px repeat(7, 32px);
  row-gap: 3px;
  column-gap: 2px;
  align-items: center;
  justify-items: center;
}

.home-calendar__week-no-header {
  /* empty spacer above week-number column */
  justify-self: end;
}

.home-calendar__weekday-header {
  font-size: 10px;
  font-weight: 600;
  color: var(--text-muted);
  text-align: center;
  padding: 2px 0 4px;
  letter-spacing: 0.04em;
}

.home-calendar__week-no {
  font-size: 9px;
  color: var(--text-muted);
  text-align: right;
  padding-right: 4px;
  font-variant-numeric: tabular-nums;
  line-height: 32px;
  justify-self: end;
}

/* Day cell button */
.home-calendar__day {
  appearance: none;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 8px;
  font-size: 12px;
  color: var(--text-primary);
  text-align: center;
  width: 32px;
  height: 32px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-variant-numeric: tabular-nums;
  transition: background 120ms ease, border-color 120ms ease;
  padding: 0 0 5px;
  box-sizing: border-box;
  flex-shrink: 0;
  position: relative;
  flex-direction: column;
  gap: 0;
}

/* Density dots — absolute bottom-center of the day cell */
.home-calendar__dots {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.5px;
  position: absolute;
  bottom: 2px;
  left: 0;
  right: 0;
  pointer-events: none;
}

.home-calendar__dot {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--c-blue);
  flex-shrink: 0;
}

.home-calendar__day:hover {
  background: var(--surface-4);
  border-color: var(--surface-10);
}

/* Adjacent-month days — muted */
.home-calendar__day--out {
  color: var(--surface-3);
}

.home-calendar__day--out:hover {
  color: var(--text-muted);
}

/* Today — soft red rounded badge (гамма-F: no solid-red, no white text) */
.home-calendar__day--today {
  background: var(--c-blue-a16);
  color: var(--c-blue);
  font-weight: 500;
  border-color: transparent;
  border-radius: 7px;
}

.home-calendar__day--today:hover {
  background: var(--c-blue-a28);
}

/* Selected — blue ring (overrides today if same day) */
.home-calendar__day--selected:not(.home-calendar__day--today) {
  border-color: var(--c-blue);
  background: var(--c-blue-a12);
  color: var(--c-blue-6);
}

.home-calendar__day--selected.home-calendar__day--today {
  /* Today + selected: keep soft-red badge, NO blue ring (гамма-F) */
  box-shadow: none;
}

.home-calendar__empty {
  font-size: 13px;
  color: var(--text-muted);
  padding: 8px 0;
}

/* ── Agenda panel ────────────────────────────────────────────────────────── */
.home-agenda {
  background: var(--surface-card);
  border-radius: 12px;
  padding: 16px;
  flex: 0 0 220px;
  min-width: 180px;
  max-width: 280px;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* Header: «Сб, 27 июня» + compact «+» top-right */
.home-agenda__header {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  color: var(--text-1);
  flex-shrink: 0;
}

.home-agenda__weekday {
  color: var(--text-1);
}

/* Day number rendered in blue (accent) */
.home-agenda__day {
  color: var(--c-blue);
  font-weight: 700;
  font-size: 15px;
}

.home-agenda__month {
  color: var(--text-1);
}

/* Items list */
.home-agenda__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
}

.home-agenda__item {
  display: flex;
  align-items: flex-start;
  background: var(--surface-tile);
  border-radius: 9px;
  padding: 4px 6px;
}

/* Event row layout: chip + title */
.home-agenda__event-row {
  display: flex;
  align-items: baseline;
  gap: 6px;
  width: 100%;
  flex-wrap: wrap;
  font-size: 12px;
}

/* Kind chip — colored label showing time or '·' */
.home-agenda__chip {
  font-size: 10px;
  font-weight: 600;
  padding: 1px 5px;
  border-radius: 4px;
  white-space: nowrap;
  flex-shrink: 0;
  color: var(--surface-card);
}

.home-agenda__chip--call       { background: var(--c-blue); color: var(--text-2); }
.home-agenda__chip--handover   { background: var(--c-amber); color: var(--surface-card); }
.home-agenda__chip--task       { background: var(--c-red); color: var(--text-2); }
.home-agenda__chip--subscription { background: var(--text-muted); color: var(--text-2); }
.home-agenda__chip--custom     { background: var(--text-muted); color: var(--text-2); }

/* Loan-kind tint (260713-s47) — mirrors .subs-credit-badge--* palette:
   credit violet / installment blue / mortgage amber. */
.home-agenda__chip--credit       { background: var(--c-violet-a14); color: var(--c-violet); }
.home-agenda__chip--installment  { background: var(--c-lightblue-a14); color: var(--c-lightblue); }
.home-agenda__chip--mortgage     { background: var(--c-amber-a14); color: var(--c-amber); }

/* Event row stacks the optional note line below the chip+title row */
.home-agenda__item--event {
  flex-direction: column;
}

.home-agenda__event-note {
  display: block;
  width: 100%;
  font-size: 11px;
  line-height: 1.3;
  margin-top: 2px;
  padding-left: 2px;
  word-break: break-word;
}

/* Task row button */
.home-agenda__task-btn {
  appearance: none;
  background: transparent;
  border: none;
  padding: 4px 6px;
  border-radius: 6px;
  cursor: pointer;
  text-align: left;
  display: flex;
  align-items: baseline;
  gap: 4px;
  width: 100%;
  font-size: 12px;
  color: var(--text-primary);
  transition: background 100ms ease;
  flex-wrap: wrap;
}

.home-agenda__task-btn:hover {
  background: var(--surface-4);
}

.home-agenda__item--done .home-agenda__task-btn {
  opacity: 0.5;
  text-decoration: line-through;
}

.home-agenda__time {
  color: var(--text-muted);
  font-size: 11px;
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
}

.home-agenda__title {
  color: var(--text-primary);
  flex: 1;
  word-break: break-word;
}

.home-agenda__deal-ref {
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
}

/* Subscription row link */
.home-agenda__sub-link {
  display: flex;
  align-items: baseline;
  gap: 6px;
  padding: 4px 6px;
  border-radius: 6px;
  font-size: 12px;
  color: var(--text-1);
  text-decoration: none;
  transition: background 100ms ease;
  width: 100%;
}

.home-agenda__sub-link:hover {
  background: var(--surface-4);
  color: var(--text-primary);
}

.home-agenda__amount {
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* Empty state */
.home-agenda__empty {
  font-size: 13px;
  color: var(--text-muted);
  padding: 4px 0;
  flex: 1;
}

/* «+» compact add button — top-right of agenda header */
/* Pico [role=button] defeat: these are <button type="button"> but cover all states */
.home-agenda__add,
.home-agenda__add:link,
.home-agenda__add:visited,
.home-agenda__add:hover,
.home-agenda__add:focus,
.home-agenda__add:active,
.home-agenda__add:focus-visible {
  appearance: none;
  background: var(--surface-9);
  border: none;
  box-shadow: none;
  outline: none;
  border-radius: 50%;
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--text-1);
  flex-shrink: 0;
  padding: 0;
  box-sizing: border-box;
  margin-left: auto;
  transition: background 120ms ease;
  text-decoration: none;
}

.home-agenda__add:hover {
  background: var(--surface-19);
}

.home-agenda__add svg {
  width: 14px;
  height: 14px;
  stroke: var(--text-1);
  display: block;
  flex-shrink: 0;
}

/* Responsive: stack calendar and agenda vertically on narrow screens */
@media (max-width: 700px) {
  .home-calendar-block {
    flex-direction: column;
  }

  .home-agenda {
    flex: 1 1 auto;
    max-width: none;
  }

  .home-calendar__months {
    flex-direction: column;
  }
}

/* ══════════════════════════════════════════════════════════════════════════════
   Task modal (260627-sqh PART 3)
   Compact edit/add modal for agenda tasks.
   Binds sizing to dialog.modal.task-modal > article (direct child) per
   CLAUDE.md convention — avoids leaking onto any nested <article> elements.
   ══════════════════════════════════════════════════════════════════════════════ */

/* ── Dialog shell — inherits .modal base (Pico dialog defaults) ─────────────── */
dialog.modal.task-modal {
  padding: 0;
  border: none;
  border-radius: 14px;
  background: transparent;
  max-width: 420px;
  width: 94vw;
}

dialog.modal.task-modal::backdrop {
  background: var(--sc-55);
}

/* ── Article card — compact, dark tile ──────────────────────────────────────── */
dialog.modal.task-modal > article {
  background: var(--surface-tile);
  border-radius: 14px;
  border: 1px solid var(--wa-07);
  padding: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 0;
  margin: 0;
}

/* ── Header row ─────────────────────────────────────────────────────────────── */
.task-modal__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px 10px;
  border-bottom: none;
}

.task-modal__title-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
}

/* Task modal close «×» → shared `[rel="prev"]` component (260709-14u). */

/* ── Error banner ───────────────────────────────────────────────────────────── */
.task-modal__error {
  margin: 10px 16px 0;
  padding: 8px 12px;
  border-radius: 8px;
  background: var(--c-red-a12-2);
  border: 1px solid var(--c-red-a30-2);
  color: var(--c-red);
  font-size: 13px;
}

/* ── Deal back-link ─────────────────────────────────────────────────────────── */
.task-modal__deal-link {
  padding: 8px 16px 0;
}

.task-modal__deal-anchor {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: var(--c-blue);
  text-decoration: none;
  transition: opacity 120ms ease;
}

.task-modal__deal-anchor:hover {
  opacity: 0.8;
}

/* ── Form fields ────────────────────────────────────────────────────────────── */
.task-modal__form {
  padding: 14px 16px 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.task-modal__field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.task-modal__label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.task-modal__label--inline {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text-1);
  cursor: pointer;
}

.task-modal__input {
  background: var(--surface-card);
  border: 1px solid var(--wa-10);
  border-radius: 8px;
  padding: 8px 10px;
  color: var(--text-primary);
  font-size: 13px;
  width: 100%;
  box-sizing: border-box;
  transition: border-color 120ms ease;
}

.task-modal__input:focus {
  outline: none;
  border-color: var(--c-blue);
}

.task-modal__input--time {
  /* time inputs can render narrower */
  max-width: 140px;
}

/* Datepicker inside the modal inherits .task-modal__input look via .datepicker */
dialog.modal.task-modal .datepicker {
  width: 100%;
}

dialog.modal.task-modal .deal-form-input.datepicker__display {
  background: var(--surface-card);
  border: 1px solid var(--wa-10);
  border-radius: 8px;
  padding: 8px 10px;
  color: var(--text-primary);
  font-size: 13px;
  width: 100%;
  box-sizing: border-box;
}

dialog.modal.task-modal .deal-form-input.datepicker__display:focus {
  border-color: var(--c-blue);
}

/* Done checkbox */
.task-modal__checkbox {
  width: 16px;
  height: 16px;
  cursor: pointer;
  accent-color: var(--c-blue);
  flex-shrink: 0;
}

.task-modal__field--done {
  flex-direction: row;
  align-items: center;
}

/* ── Footer: Save button ────────────────────────────────────────────────────── */
.task-modal__footer {
  padding: 12px 16px;
  display: flex;
  justify-content: flex-end;
}

/* ── Delete form ────────────────────────────────────────────────────────────── */
.task-modal__delete-form {
  padding: 0 16px 14px;
  display: flex;
  justify-content: flex-start;
}

/* ── Buttons ────────────────────────────────────────────────────────────────── */
.task-modal__btn {
  appearance: none;
  border-radius: 8px;
  padding: 8px 16px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: opacity 120ms ease, filter 120ms ease;
  border: 1px solid transparent;
}

.task-modal__btn:hover {
  filter: brightness(1.1);
}

/* Save — filled blue */
.task-modal__btn--save {
  background: var(--c-blue);
  color: var(--text-2);
  border-color: var(--c-blue);
}

/* Delete — red ghost */
.task-modal__btn--delete {
  background: transparent;
  color: var(--c-red-3);
  border-color: var(--c-red-a40);
}

.task-modal__btn--delete:hover {
  background: var(--c-red-a10);
  border-color: var(--c-red-3);
}

/* ── Event modal (260628-nrz Task 2; reworked 260630-v47) ─────────────────── */
/* Sizing/field/footer styling now inherited from .modal-form + .deal-form-*
   (see deals modal). Only the kind-chip group + datepicker overrides remain. */

/* Datepicker inside event modal */
dialog.modal.event-modal .datepicker {
  width: 100%;
}

dialog.modal.event-modal .deal-form-input.datepicker__display {
  background: var(--surface-tile);
  border: 1px solid var(--wa-10);
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 13px;
  color: var(--text-primary);
  width: 100%;
  box-sizing: border-box;
}

dialog.modal.event-modal .deal-form-input.datepicker__display:focus {
  border-color: var(--c-blue);
  outline: none;
}

/* Kind chip radio group */
.event-modal__kind-group {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.event-modal__kind-chip {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  font-weight: 500;
  padding: 4px 10px;
  border-radius: 20px;
  border: 1px solid var(--wa-12);
  background: var(--surface-tile);
  color: var(--text-1);
  cursor: pointer;
  transition: background 100ms ease, border-color 100ms ease, color 100ms ease;
}

.event-modal__kind-chip input[type="radio"] {
  display: none;
}

.event-modal__kind-chip:has(input:checked) {
  border-color: var(--c-blue);
  background: var(--c-blue-a15-2);
  color: var(--c-blue-6);
}

.event-modal__kind-chip--call:has(input:checked)         { border-color: var(--c-blue); background: var(--c-blue-a15-2); color: var(--c-blue-6); }
.event-modal__kind-chip--handover:has(input:checked)     { border-color: var(--c-amber); background: var(--c-amber-a15); color: var(--c-amber); }
.event-modal__kind-chip--task:has(input:checked)         { border-color: var(--c-red); background: var(--c-red-a15); color: var(--c-red); }
.event-modal__kind-chip--subscription:has(input:checked) { border-color: var(--text-muted); background: var(--nx-6-a15); color: var(--text-12); }
.event-modal__kind-chip--custom:has(input:checked)       { border-color: var(--text-muted); background: var(--nx-6-a15); color: var(--text-12); }

/* ── Event modal canon extras (quick 260721-k7s) ─────────────────────────── */

/* Дата | С | До — fixed 3-col row (modal is 560px, no responsive collapse). */
.event-modal__datetime-row {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 10px;
}

/* «Весь день» toggle row — .settings-switch (theme.css :9673) + text label. */
.event-modal__allday-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.event-modal__allday-label {
  font-size: 13px;
  color: var(--text-primary);
}

/* Compact chips 6px 13px (base .event-modal__kind-chip is 4px 10px). Scoped
   under .modal-form--canon (0,2,0) so it wins the tied-specificity (0,1,0)
   tie-break over the base rule regardless of source order — the event
   dialog carries both classes. */
.modal-form--canon .event-modal__kind-chip {
  padding: 6px 13px;
}

/* Align the datepicker display with the two 38px selects in the same row —
   the base override above sets its own padding/font-size but no height, so
   without this it renders at its natural (slightly shorter) content height. */
.modal-form--canon .datepicker__display {
  height: 38px;
}

/* Dashboard FX-currency chips (settings card) — checkbox variant of the kind chip.
   The base .event-modal__kind-chip only hides radios; hide the checkbox here so the
   chip itself is the visible toggle. Checked state reuses the generic :has rule. */
.dash-fx-chip input[type="checkbox"] {
  display: none;
}

/* 260708-qhj: 24-currency selector — «Фиат»/«Крипта» sub-group labels + the
   dimmed state for chips disabled by the 12-selection cap script. Reuses the
   width:auto/max-content + white-space:nowrap label convention (CLAUDE.md
   «Frontend / CSS») — these are inline labels, not grid/flex label columns,
   so no explicit width rule is needed beyond nowrap. */
.dash-fx-subgroup-label {
  display: block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  white-space: nowrap;
  margin: 2px 0 -2px;
}

.dash-fx-chip--dim {
  opacity: 0.35;
  cursor: not-allowed;
}

/* ══════════════════════════════════════════════════════════════════════════════
   Command-center grid (260627-sqh PART 4)
   Tokens: card #0d1320, tile #131c2e, caption #9aa6bd, value #e8eef7,
           green #30d158, amber #f0a83c, red #ff453a, blue #22e754, muted #7d8aa0
   All rules scoped under #home-body or the new grid/group classes.
   Does NOT regress r2a / PART2 / PART3 blocks.
   ══════════════════════════════════════════════════════════════════════════════ */

/* ── .home-calendar-block — 2-col wrapper: calendar | agenda ────────────────── */
/* PART 2 already defines .home-calendar-block as flex; PART 4 confirms the
   column widths so calendar expands and agenda stays compact. */
.home-calendar-block {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 12px;
  align-items: flex-start;
}

@media (max-width: 900px) {
  .home-calendar-block {
    grid-template-columns: 1fr;
  }
}

/* ── .home-center-row — 2-col: Сегодня (left) | Финансы+Пайплайн (right) ────── */
#home-body .home-center-row {
  display: grid;
  grid-template-columns: minmax(240px, 1fr) minmax(280px, 1.4fr);
  gap: 16px;
  align-items: flex-start;
}

@media (max-width: 720px) {
  #home-body .home-center-row {
    grid-template-columns: 1fr;
  }
}

/* Left column just holds the today-actions section full-height */
.home-center-row__left {
  display: flex;
  flex-direction: column;
}

/* Right column: Финансы + Пайплайн stacked */
.home-center-row__right {
  display: flex;
  flex-direction: column;
}

/* ── Grouped «Сегодня обязательно» summary rows ─────────────────────────────── */

/* Groups container */
.today-actions__groups {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* <details> wrapper — each group row */
.today-group-row {
  border-radius: 8px;
  border-top: 1px solid var(--hairline);
  transition: background var(--transition-fast, 150ms ease);
}

.today-group-row:first-child {
  border-top: none;
}

/* <summary> — the visible compact row (~36px) */
.today-group-row__summary {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 8px;
  border-radius: 8px;
  cursor: pointer;
  list-style: none;
  user-select: none;
}

/* Remove default disclosure triangle */
.today-group-row__summary::-webkit-details-marker { display: none; }
.today-group-row__summary::marker { display: none; }

.today-group-row__summary:hover {
  background: var(--surface-row);
}

/* Type icon */
.today-group-row__icon {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  width: 18px;
  height: 18px;
}

/* Per-kind icon color */
.today-group-row--payment .today-group-row__icon  { color: var(--c-red); }
.today-group-row--defect  .today-group-row__icon  { color: var(--c-amber); }
.today-group-row--stale   .today-group-row__icon  { color: var(--text-muted); }
.today-group-row--subscription .today-group-row__icon { color: var(--c-blue); }

/* Amber «последняя оплата» prompt (Quick 260713-s47) */
.today-group-row--subscription_last .today-group-row__icon  { color: var(--c-amber); }
.today-group-row--subscription_last .today-group-row__label { color: var(--c-amber); }

/* Label */
.today-group-row__label {
  color: var(--text-primary);
  font-size: 14px;
  font-weight: 500;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Count badge */
.today-group-row__count {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-2);
  background: var(--wa-12);
  border-radius: 10px;
  padding: 1px 7px;
  white-space: nowrap;
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}

/* «when» variant for subscription (same style, distinct class for targeting) */
.today-group-row__count--when {
  background: var(--c-blue-a18);
  color: var(--c-blue-6);
}

/* Expand chevron — CSS-flip chevron-left to point right; rotates on open */
.today-group-row__chevron {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  color: var(--surface-16);
  transform: rotate(180deg); /* chevron-left → points right (›) */
  transition: transform 150ms ease;
}

.today-group-row[open] .today-group-row__chevron {
  transform: rotate(270deg); /* points down when open (↓) */
}

/* Expanded items panel */
.today-group-row__items {
  list-style: none;
  padding: 2px 8px 8px 34px; /* indent under icon column */
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

/* Each underlying item in the expand panel */
.today-group-row__item {
  display: flex;
}

.today-group-row__item-link {
  font-size: 12px;
  color: var(--text-1);
  text-decoration: none;
  padding: 3px 4px;
  border-radius: 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
  transition: color 100ms ease, background 100ms ease;
}

.today-group-row__item-link:hover {
  color: var(--text-primary);
  background: var(--surface-row);
}

/* ── Settings page: calendar-feed subscription card (quick 260702) ─────────── */
/* ── Settings page — compact icon header (260702-139) ──────────────────────── */
/* Narrow content column (quick 260720-123): list/form pages (/settings,
   /subscriptions) center their content at 860px inside .main-content instead
   of hugging the left edge. Shared header used only by settings + subscriptions
   (both narrow) — wide dashboards/tables never use this class. */
.settings-page-header {
  max-width: 860px;
  margin: 0 auto 18px;
}

.settings-page-title {
  display: flex;
  align-items: center;
  gap: 8px;
}

.settings-page-title__icon {
  display: inline-flex;
  color: var(--text-1);
}

.settings-page-title__icon svg {
  width: 18px;
  height: 18px;
}

.settings-page-title__text {
  font-size: 19px;
  font-weight: 500;
  color: var(--text-primary);
  line-height: 1.1;
}

.settings-page-subtitle {
  color: var(--text-muted);
  font-size: 12px;
  /* Offset under the title text (icon 18px + 8px gap) */
  margin: 4px 0 0 26px;
}

.settings-page-body {
  max-width: 520px;
}

/* ── Two-panel settings shell (left nav / right content) — quick 260704-ksi ── */
.settings-shell{max-width:860px;margin:0 auto;display:grid;grid-template-columns:200px 1fr;
  background:var(--surface-card);border:1px solid var(--wa-08);border-radius:16px;overflow:hidden}
.settings-nav{display:flex;flex-direction:column;gap:2px;padding:14px 10px;
  background:var(--wa-02);border-right:1px solid var(--wa-07)}
.settings-nav__title{margin:2px 8px 8px;font-size:11px;font-weight:600;letter-spacing:.06em;
  text-transform:uppercase;color:var(--surface-3)}
.settings-nav__item{display:flex;align-items:center;gap:9px;width:100%;margin:0;padding:8px 10px;
  border:none;background:none;border-radius:8px;color:var(--text,var(--text-17));font-size:13px;
  text-align:left;cursor:pointer;transition:background .12s,color .12s}
.settings-nav__item:hover{background:var(--wa-05)}
.settings-nav__item.active{background:var(--c-blue-a14);color:var(--c-blue-4);font-weight:500}
.settings-nav__icon{display:inline-flex;width:15px;height:15px}
.settings-nav__icon svg{width:15px;height:15px}
.settings-content{padding:18px 22px 14px;min-width:0;display:flex;flex-direction:column}
.settings-section[hidden]{display:none}
/* Flatten the moved cards inside the pane */
.settings-content .settings-card{border:none;background:none;border-radius:0;padding:0;margin:0 0 18px}
.settings-content .settings-card:last-child{margin-bottom:0}
/* label-left / control-right rows */
.settings-row{display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:12px 0;border-top:1px solid var(--hairline)}
.settings-row--stack{flex-direction:column;align-items:stretch;gap:10px}
.settings-row__meta{display:flex;flex-direction:column;gap:2px;min-width:0}
.settings-row__label{font-size:13px;color:var(--text,var(--text-16))}
.settings-row__hint{font-size:12px;color:var(--surface-3)}
.settings-row__control{display:flex;align-items:center;gap:8px;flex-shrink:0}
.settings-row__unit{font-size:12px;color:var(--text-21)}
.settings-num{width:52px;text-align:center}
/* Zero Pico's default input margin-bottom (21px): in the align-items:center
   .settings-row__control flex row it centred the input's margin box, sinking the
   «дней» unit ~10px below the number's visual centre. (0,2,0) beats Pico's element
   rule; verified live delta 10px → 0px on both day-rows (quick 260706-sr9). */
.settings-row__control .settings-num{margin-bottom:0}
/* «Умный риск» switch — checkbox mirror of .subs-toggle (quick 260706-sr9) */
.settings-switch{position:relative;display:inline-flex;align-items:center;cursor:pointer;flex-shrink:0}
.settings-switch input{position:absolute;opacity:0;width:0;height:0;margin:0}
.settings-switch__track{position:relative;width:34px;height:18px;border-radius:999px;background:var(--surface-11);transition:background var(--transition-fast)}
.settings-switch__knob{position:absolute;top:2px;left:2px;width:14px;height:14px;border-radius:50%;background:var(--text-2);transition:transform var(--transition-fast)}
.settings-switch input:checked + .settings-switch__track{background:var(--c-blue)}
.settings-switch input:checked + .settings-switch__track .settings-switch__knob{transform:translateX(16px)}
.settings-switch input:focus-visible + .settings-switch__track{box-shadow:0 0 0 3px var(--c-blue-a35)}
/* dim the fixed «Под риском» row + swap its hint when smart is on (:has, already used here) */
#dashboard-card form:has(input[name="smart_risk"]:checked) .settings-row--at-risk{opacity:.5}
.settings-row__hint--fallback{display:none}
#dashboard-card form:has(input[name="smart_risk"]:checked) .settings-row--at-risk .settings-row__hint--default{display:none}
#dashboard-card form:has(input[name="smart_risk"]:checked) .settings-row--at-risk .settings-row__hint--fallback{display:block}
.settings-section__actions{display:flex;align-items:center;justify-content:flex-end;
  gap:12px;margin-top:14px}
.settings-section__actions .deal-submit-pill{width:auto}
/* ── Pin the Save footer to the bottom of the panel — form sections only (260704-prp) ─ */
/* Дашборд / Календарь / Пресеты fill the panel height so the footer (compact Save
   pill + «Сохранено ✓», + the ghost «Сбросить» link in Presets) sits bottom-right on
   short content and flows normally (scrolls) on long content. Account/Integrations
   keep their in-content buttons. :not([hidden]) keeps the hide rule winning. */
.settings-section[data-section="dashboard"]:not([hidden]),
.settings-section[data-section="calendar"]:not([hidden]),
.settings-section[data-section="presets"]:not([hidden]) {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  /* Defeat Pico's default <section> margin-bottom (~21px). It sat BELOW the
     pinned section, so the footer pinned to the section bottom but 21px margin
     + 14px content padding pushed the button row ~35px off the panel edge.
     Zeroing it drops the gap to the 14px .settings-content padding-bottom
     (~15px to the modal edge) — the 260706-pva padding tweak alone couldn't
     reach it. Selector (0,3,0) beats Pico's `section` (0,0,1). */
  margin-bottom: 0;
}
.settings-section[data-section="dashboard"] > .settings-card,
.settings-section[data-section="calendar"] > .settings-card,
.settings-section[data-section="presets"] > .settings-card {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  margin-bottom: 0;
}
.settings-section[data-section="dashboard"] > .settings-card > form,
.settings-section[data-section="calendar"] > .settings-card > form,
.settings-section[data-section="presets"] > .settings-card > form {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
}
/* Footer → pushed to the bottom, with the top divider kept. Дашборд/Календарь/Пресеты
   all now use .preset-actions (red Reset left + Save right), so the pin + full-width
   divider + centered button row are pixel-identical across the three sections. */
.settings-section[data-section="dashboard"] .preset-actions,
.settings-section[data-section="calendar"] .preset-actions,
.settings-section[data-section="presets"] .preset-actions {
  margin-top: auto;
  border-top: 1px solid var(--hairline);
  padding-top: 12px;
}
/* Account-section «Сохранить»/«Сменить пароль» pills read compact (not full-width)
   inside the panel — consistent with the Дашборд/Календарь section pills. */
.settings-content .account-form .deal-submit-pill{width:auto;align-self:flex-start}
/* responsive: nav collapses to a horizontal chip strip */
@media (max-width:760px){
  .settings-shell{grid-template-columns:1fr}
  .settings-nav{flex-direction:row;overflow-x:auto;gap:6px;
    border-right:none;border-bottom:1px solid var(--wa-07)}
  .settings-nav__title{display:none}
  .settings-nav__item{flex:0 0 auto;white-space:nowrap}
}

/* ── Settings as a modal overlay (quick 260704-mfi) ─────────────────────────── */
/* The sized/centered window is the > article (mirrors dialog.modal-form/-detail):
   the <dialog> stays the app's full-viewport overlay (::backdrop dims the page)
   and its > article is the floating 860×640 tile — sizing the dialog itself gets
   overridden to full-screen by the base dialog.modal rules. The inner
   .settings-shell drops its own frame and fills the article. */
dialog.settings-modal > article{width:min(860px,92vw);height:min(640px,85vh);max-width:none;
  max-height:85vh;padding:0;border-radius:16px;overflow:hidden;position:relative;background:var(--surface-card);
  border:1px solid var(--wa-08);box-shadow:var(--shadow-modal)}
.settings-modal .settings-shell{max-width:none;margin:0;height:100%;border:none;
  border-radius:0;background:transparent}
.settings-modal .settings-nav{overflow-y:auto}   /* left fixed column, scrolls if long */
.settings-modal .settings-content{overflow-y:auto} /* right pane scrolls inside the tile */
/* Shared modal close «×» (260709-14u). Normalise EVERY modal's `[rel="prev"]`
   close to the identical Pico close look — Pico only applies its width/padding
   reset inside certain header contexts, so a headerless modal (settings) otherwise
   inherits the default 42×31.5 padded button. Forcing 1rem here makes all modals'
   × pixel-identical regardless of their header structure. */
.modal [rel="prev"]{
  width:1rem; height:1rem; padding:0; border:none;
  background-color:transparent; background-size:auto 1rem; background-position:center;
  --pico-box-shadow:none; box-shadow:none;
}
/* The settings modal has no header, so pin its close to the top-right of the
   article (the header-based modals position it in flow via Pico's margins). */
.settings-modal > article > [rel="prev"]{
  position:absolute; top:14px; right:16px; z-index:2; margin:0; float:none;
}
/* Keyboard-only focus ring on any modal close «×» — no ring on the programmatic
   showModal() auto-focus / mouse (the shared _modal_host helper already moves the
   initial focus off the ×). Pico's :focus handles the opacity bump. (260709-14u) */
.modal [rel="prev"]:focus-visible{
  outline:2px solid var(--pico-primary,var(--c-blue)); outline-offset:3px;
  border-radius:4px; opacity:1;
}

/* ── Subscriptions page — dark deal-modal system (quick 260702-1le) ─────────── */
.subs-page-body {
  max-width: 860px;      /* quick 260720-123: was 680px — widened + centered */
  margin: 0 auto;        /* center the content column in .main-content */
}

/* Quick 260719-q8x — page header restructure: title/subtitle left, moved
   ₽/$ toggle + «+ Добавить» pill right. New dedicated classes only — the
   shared .settings-page-header/.settings-page-title are NOT restyled. */
.subs-page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.subs-page-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}

/* Two metric tiles: Итого/мес $ and ₽ */
.subs-metrics {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-bottom: 14px;
}

.subs-metric {
  display: flex;
  flex-direction: column;
  gap: 4px;
  background: var(--surface-tile);
  border-radius: 10px;
  padding: 12px 14px;
}

.subs-metric__label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.subs-metric__value {
  font-size: 20px;
  font-weight: 600;
  color: var(--text-primary);
  line-height: 1.1;
}

/* q1z: ₽-equiv / nearest subline · row letter avatar · payment badge */
.subs-metric__sub {
  display: block;
  margin-top: 3px;
  font-size: 11px;
  color: var(--text-muted);
}
.subs-metric__sub--urgent {
  color: var(--c-amber);
}
.subs-avatar {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 600;
}
.subs-badge {
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
}
.subs-badge--urgent {
  color: var(--c-amber);
}

/* Card head: caption left, «+ Добавить» pill right */
.subs-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.subs-add-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 32px;
  padding: 0 14px;
  background: var(--c-blue);
  color: var(--text-2);
  border: none;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  line-height: 1;
  transition: background var(--transition-fast), opacity var(--transition-fast);
}

.subs-add-pill svg {
  display: block;
  flex-shrink: 0;
  width: 14px;
  height: 14px;
}

.subs-add-pill:hover {
  background: var(--accent-hover, var(--c-blue-3));
}

.subs-add-pill:active {
  opacity: 0.85;
}

/* Subscription rows */
.subs-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.subs-row {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--surface-tile);
  border-radius: 10px;
  padding: 10px 12px;
  transition: opacity var(--transition-fast);
}

.subs-row--inactive {
  opacity: 0.55;
}

.subs-row__main {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  flex: 1 1 auto;
}

.subs-row__name {
  font-size: 13px;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-decoration: none;
}

/* A subscription name is an <a> when service_url is set (Quick 260713-r1p) —
   same visual as the plain <span>, underline only on hover for affordance. */
a.subs-row__name:hover {
  text-decoration: underline;
}

.subs-cat-chip {
  flex-shrink: 0;
  font-size: 11px;
  color: var(--text-1);
  background: var(--hairline);
  border-radius: 999px;
  padding: 2px 8px;
  white-space: nowrap;
}

.subs-row__meta {
  display: flex;
  align-items: baseline;
  gap: 5px;
  flex-shrink: 0;
}

.subs-row__amount {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
  white-space: nowrap;
}

.subs-row__day {
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
}

.subs-row__actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}

/* Compact toggle switch */
.subs-toggle {
  position: relative;
  width: 34px;
  height: 18px;
  border-radius: 999px;
  border: none;
  background: var(--surface-11);
  cursor: pointer;
  padding: 0;
  flex-shrink: 0;
  transition: background var(--transition-fast);
}

.subs-toggle--on {
  background: var(--c-blue);
}

.subs-toggle__knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--text-2);
  transition: transform var(--transition-fast);
}

.subs-toggle--on .subs-toggle__knob {
  transform: translateX(16px);
}

/* Icon action buttons (edit / delete) */
.subs-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border: none;
  background: transparent;
  color: var(--text-muted);
  border-radius: 7px;
  cursor: pointer;
  padding: 0;
  transition: color var(--transition-fast), background var(--transition-fast);
}

.subs-icon-btn svg {
  width: 14px;
  height: 14px;
}

.subs-icon-btn:hover {
  color: var(--text-primary);
  background: var(--hairline);
}

.subs-icon-btn--danger:hover {
  color: var(--c-red);
  background: var(--c-red-a12);
}

/* Quick 260721-i69: compact single-line subscription row — scoped modifier,
   never applied to credit/installment/mortgage rows. Purely additive; every
   selector below is prefixed with .subs-row--compact. */
.subs-row--compact {
  padding: 8px 12px;
  gap: 9px;
}

.subs-row--compact .subs-avatar {
  width: 24px;
  height: 24px;
  border-radius: 7px;
  font-size: 12px;
}

.subs-row--compact .subs-row__name {
  font-size: 13px;
  font-weight: 500;
}

.subs-row--compact .subs-row__amount {
  font-size: 13px;
  font-weight: 500;
}

.subs-row--compact .subs-row__fx-equiv {
  font-size: 11.5px;
}

.subs-row--compact .subs-status {
  font-size: 12px;
}

.subs-row--compact .subs-toggle {
  width: 28px;
  height: 16px;
}

.subs-row--compact .subs-toggle__knob {
  width: 12px;
  height: 12px;
  top: 2px;
  left: 2px;
}

.subs-row--compact .subs-toggle--on .subs-toggle__knob {
  transform: translateX(12px);
}

.subs-row--compact .subs-icon-btn {
  color: #6b7385;
}

/* Pico gives every native <button> a default margin-bottom (--pico-spacing,
   ~16-21px), which inflates the .subs-row__actions flex line and kept the
   compact row at ~58-63px instead of ~42px (the i69 sizing was applied but
   eaten by this margin). Zero it so the row hits its true compact height. */
.subs-row--compact .subs-toggle,
.subs-row--compact .subs-icon-btn {
  margin-bottom: 0;
}

.subs-empty {
  text-align: center;
  font-size: 12px;
  color: var(--text-muted);
  padding: 18px 0;
  margin: 0;
}

/* «Активна» checkbox inside the modal — REMOVED quick 260722-jk9 (Bug #5):
   markup switched to canon `.settings-switch` (deal-form-switch-item), which
   already has its own rules (~L1128/L1142); the old `.subs-active-check`
   class is no longer referenced anywhere in the template (grep-confirmed). */

/* ── Quick 260710-279: installment credits + 4-tile summary ─────────────── */

/* 4-tile summary grid (Итого $ / Итого ₽ / Оплачено·месяц / Предстоит·месяц) */
.subs-metrics--4 {
  grid-template-columns: repeat(4, 1fr);
}
@media (max-width: 560px) {
  .subs-metrics--4 {
    grid-template-columns: repeat(2, 1fr);
  }
}
.subs-metric--paid {
  border-left: 2px solid var(--c-green);
}
.subs-metric__value--paid {
  color: var(--c-green);
}
.subs-metric--upcoming {
  border-left: 2px solid var(--c-amber);
}
.subs-metric__value--upcoming {
  color: var(--c-amber);
}

/* Quick 260719-ifd — ₽/$ display-currency toggle: card-head chip pair,
   «ДОЛГ ОСТАТОК» purple tile, per-row/label gray equivalents, fallback hint. */
.subs-card__head-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.subs-ccy-chips {
  display: flex;
  gap: 4px;
  background: var(--surface-tile);
  border-radius: 999px;
  padding: 3px;
}

/* Reset Pico <button> defaults (padding/display/box-shadow) on the chip
   pair; focus ring is a box-shadow (not outline), scoped to :focus-visible
   (mirrors .bug-action-btn's pico-defaults-leak fix). */
.subs-ccy-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 30px;
  height: 26px;
  padding: 0 10px;
  margin: 0;
  background: transparent;
  border: none;
  border-radius: 999px;
  color: var(--text-muted);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: none;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.subs-ccy-chip:hover:not(.subs-ccy-chip--active) {
  background: var(--hairline);
  color: var(--text-5);
}

.subs-ccy-chip--active {
  background: var(--c-blue);
  color: var(--text-2);
}

.subs-ccy-chip:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--c-blue-a45);
}

/* Quick 260720-jmf — inline period toggle (deal-detail-grid «Период» row).
   Same track/pill look as .subs-ccy-chip (reuses the .chip-group utility
   above to neutralize Pico's [role=group] focus ring); focus-visible ring
   is added to the combined selector below (260720-gnz convention). */
/* «Период» row mini-segment (variant B, 260720-q7z) — modelled on the ₽/$
   toggle but sized to sit in the row's value cell WITHOUT distending it:
   short «мес»/«год» labels, 11px, ~22px segment inside a 2px-padded pill. */
.subs-period-chips {
  display: inline-flex;
  gap: 2px;
  vertical-align: middle;
  background: var(--surface-tile);
  border: 1px solid var(--wa-12);
  border-radius: 999px;
  padding: 2px;
  /* Override Pico's [role=group] defaults (confirmed via DevTools 260721-06z):
     Pico sets the group container `width:100%` + `margin-bottom:var(--pico-spacing)`
     (≈21px), which stretched the segment across the cell AND distended the «Период»
     row to 64px vs 35px for the other rows. Pin to content width + zero margin so
     the row matches «Сервис»/«День оплаты» and the two-column hairlines line up. */
  width: max-content;
  margin-bottom: 0;
}

.subs-period-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* flex:0 0 auto overrides Pico's `[role=group]>*{flex:1 1 auto}`, which stretched
     each segment to half the container (132px). Content-sized pills instead. */
  flex: 0 0 auto;
  padding: 3px 11px;
  margin: 0;
  background: transparent;
  border: none;
  border-radius: 999px;
  color: var(--text-1);
  font-size: 11px;
  font-weight: 500;
  cursor: pointer;
  box-shadow: none;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.subs-period-chip:hover:not(.subs-period-chip--active) {
  background: var(--hairline);
  color: var(--text-5);
}

.subs-period-chip--active {
  background: var(--c-blue-5);
  color: var(--text-2);
}

.subs-metric--debt {
  border-left: 2px solid var(--c-violet-2);
}
.subs-metric__value--debt {
  color: var(--c-violet-2);
}

.subs-metrics__hint {
  margin: -6px 0 14px;
  font-size: 11px;
  color: var(--text-muted);
}

/* Quick 260719-q8x — thin month progress bar (paid_count/total_count). */
.subs-progress {
  height: 5px;
  border-radius: 999px;
  background: var(--wa-08);
  overflow: hidden;
  margin: 0 0 14px;
}
.subs-progress__fill {
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--c-green-6), var(--c-green));
  transition: width var(--transition-fast);
}

/* Quick 260719-q8x — «Ближайшие» occurrences feed (≤4 mini-cards). */
.subs-upcoming__caption {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-1);
  margin: 0 0 8px;
}
.subs-upcoming {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-bottom: 14px;
}
@media (max-width: 560px) {
  .subs-upcoming {
    grid-template-columns: repeat(2, 1fr);
  }
}
.subs-upcoming__card {
  display: flex;
  flex-direction: column;
  gap: 3px;
  background: var(--surface-tile);
  border: 1px solid transparent;
  border-radius: 10px;
  padding: 10px 12px;
  min-width: 0;
}
.subs-upcoming__card--soon {
  border-color: var(--c-amber-a50);
}
.subs-upcoming__date {
  font-size: 11px;
  font-weight: 600;
  color: var(--c-amber);
  text-transform: uppercase;
}
.subs-upcoming__card:not(.subs-upcoming__card--soon) .subs-upcoming__date {
  color: var(--text-muted);
}
.subs-upcoming__name {
  font-size: 13px;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.subs-upcoming__amount {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-1);
  white-space: nowrap;
}
/* Быстрая кнопка «Оплатить» на карточке «Ближайшие» (260723) */
.subs-upcoming__pay {
  margin: 6px 0 0;
  width: 100%;
  padding: 6px 8px;
  font-size: 12px;
  font-weight: 600;
  color: #fff;
  background: linear-gradient(180deg, var(--accent-hover, #47eb70), var(--accent, #22e754));
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: filter .15s ease, transform .1s ease;
}
.subs-upcoming__pay:hover { filter: brightness(1.08); }
.subs-upcoming__pay:active { transform: scale(.98); }
.subs-upcoming__pay:focus:not(:focus-visible) { outline: none; box-shadow: none; }
.subs-upcoming__pay.htmx-request { opacity: .6; pointer-events: none; }
.subs-upcoming__paid {
  margin-top: 6px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--status-completed, #30D158);
  white-space: nowrap;
}

/* Quick 260719-q8x — client-side filter tabs. */
.subs-filter-tabs {
  display: flex;
  gap: 6px;
  margin-bottom: 14px;
}
.subs-filter-tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  flex: 0 0 auto;
  height: 30px;
  padding: 0 12px;
  margin: 0;
  background: var(--surface-tile);
  border: none;
  border-radius: 999px;
  color: var(--text-muted);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  box-shadow: none;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.subs-filter-tab:hover:not(.subs-filter-tab--active) {
  background: var(--hairline);
  color: var(--text-5);
}
.subs-filter-tab--active {
  background: var(--c-blue);
  color: var(--text-2);
}

/* ── Interactive chips/pills — focus ring ONLY on :focus-visible (quick 260720-gnz) ──
   Recurring class (modal ×, Pico toggles): a Pico/browser default focus
   indicator drew a ring on MOUSE click. Suppress it on :focus:not(:focus-visible)
   (pointer) and show the ring only for keyboard focus (:focus-visible, a11y).
   Covers the filter tabs, the ₽/$ toggle, the modal срок/тип/kind chips, and
   (260720-jmf) the detail-modal period chips.
   See CLAUDE.md Conventions. */
.subs-filter-tab:focus:not(:focus-visible),
.subs-ccy-chip:focus:not(:focus-visible),
.subs-period-chip:focus:not(:focus-visible),
.subs-kind-chip:has(input:focus:not(:focus-visible)) {
  outline: none;
  box-shadow: none;
}
.subs-filter-tab:focus-visible,
.subs-ccy-chip:focus-visible,
.subs-period-chip:focus-visible,
.subs-kind-chip:has(input:focus-visible) {
  outline: none;
  box-shadow: 0 0 0 2px var(--c-blue-a45);
}

.subs-row__fx-equiv {
  color: var(--text-muted);
  font-size: 11px;
  white-space: nowrap;
}

/* ПОДПИСКИ / КРЕДИТЫ group captions + divider */
.subs-group-caption {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-1);
  margin: 14px 0 8px;
}
.subs-group-caption:first-of-type {
  margin-top: 0;
}
.subs-group-divider {
  height: 1px;
  background: var(--hairline);
  margin: 4px 0 14px;
}

/* Credit rows: badge, progress bar, status label */
.subs-row--credit {
  align-items: flex-start;
}
.subs-row__body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  flex: 1 1 auto;
}
.subs-credit-badge {
  flex-shrink: 0;
  font-size: 10px;
  font-weight: 600;
  color: var(--c-violet);
  background: var(--c-violet-a14);
  border-radius: 999px;
  padding: 2px 8px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.subs-credit-badge--done {
  color: var(--c-green);
  background: var(--c-green-a14);
}
/* Quick 260712-wvh: per-kind badge colors (data-driven, kind_badge_class from router).
   credit keeps the existing violet default; installment=blue, mortgage=amber. */
.subs-credit-badge--credit {
  color: var(--c-violet);
  background: var(--c-violet-a14);
}
.subs-credit-badge--installment {
  color: var(--c-lightblue);
  background: var(--c-lightblue-a14);
}
.subs-credit-badge--mortgage {
  color: var(--c-amber);
  background: var(--c-amber-a14);
}
.subs-status {
  font-size: 11px;
  white-space: nowrap;
}
.subs-status--paid {
  color: var(--c-green);
}
.subs-status--upcoming {
  color: var(--c-amber);
}
.subs-credit-progress {
  display: flex;
  align-items: center;
  gap: 8px;
}
.subs-credit-bar {
  flex: 1 1 auto;
  height: 4px;
  border-radius: 999px;
  background: var(--wa-08);
  overflow: hidden;
}
.subs-credit-bar__fill {
  height: 100%;
  background: var(--c-violet);
  border-radius: 999px;
}
/* Quick 260712-wvh: per-kind progress fill colors, matching the badge palette. */
.subs-credit-bar__fill--credit {
  background: var(--c-violet);
}
.subs-credit-bar__fill--installment {
  background: var(--c-lightblue);
}
.subs-credit-bar__fill--mortgage {
  background: var(--c-amber);
}
.subs-credit-progress-text {
  flex-shrink: 0;
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
}

/* ── Quick 260713-r1p: plain-subscription period + payment-term link ────── */

/* Muted «/ год» suffix next to a yearly subscription's amount. */
.subs-row__period {
  font-size: 11px;
  font-weight: 400;
  color: var(--text-muted);
}

/* Payment-term badges — «осталось N оплат» (muted, default), «последняя
   оплата» (amber, remaining==1), «завершена» (green, remaining==0).
   Mirrors .subs-credit-badge's tokens/shape for visual consistency with the
   loan badges, but is a SEPARATE class (plain subscriptions, not a loan). */
.subs-term-badge {
  flex-shrink: 0;
  font-size: 10px;
  font-weight: 600;
  color: var(--text-1);
  background: var(--hairline);
  border-radius: 999px;
  padding: 2px 8px;
  white-space: nowrap;
}
.subs-term-badge--last {
  color: var(--c-amber);
  background: var(--c-amber-a14);
}
.subs-term-badge--done {
  color: var(--c-green);
  background: var(--c-green-a14);
}

/* Hint under the optional «Первая оплата»/«Количество оплат» row in the
   create/edit modal (subscription tab only). */
.subs-field-hint {
  font-size: 11px;
  color: var(--text-muted);
  margin: -2px 0 0;
}

/* Radio-chip kind selector (Подписка | Кредит) in the create/edit modal */
.subs-kind-chips {
  display: inline-flex;
  gap: 6px;
  background: var(--surface-tile);
  border-radius: 999px;
  padding: 3px;
}
.subs-kind-chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 6px 16px;
  border-radius: 999px;
  font-size: 12px;
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.subs-kind-chip input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.subs-kind-chip:has(input:checked) {
  background: var(--c-blue);
  color: var(--text-2);
}
.subs-credit-fields[hidden] {
  display: none;
}

/* ── Quick 260714-lii: muted calc-loan badge in the list («аннуитет 18%») ── */
.subs-calc-badge {
  display: inline-flex;
  align-items: center;
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 500;
  color: var(--text-20);
  background: transparent;
  border: 1px solid var(--wa-14);
  white-space: nowrap;
}

/* ── Quick 260714-lii: «Рассчитать по ставке» calc block + live summary ──── */
.subs-calc-fields[hidden] {
  display: none;
}
.subs-calc-fields {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
/* Blue live-summary card — display-only preview (backend Decimal is truth). */
.loan-calc-summary {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 16px;
  border-radius: 12px;
  background: var(--c-blue-a10);
  border: 1px solid var(--c-blue-a28);
}
.loan-calc-summary[hidden] {
  display: none;
}
.loan-calc-summary__main {
  font-size: 13px;
  color: var(--text-18);
}
.loan-calc-summary__amount {
  font-size: 20px;
  font-weight: 700;
  color: var(--text-primary);
}
.loan-calc-summary__row {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  font-size: 12px;
  color: var(--text-1);
}
.loan-calc-summary__over {
  color: var(--c-amber);
}
.loan-calc-summary__fine {
  font-size: 11px;
  color: var(--text-6);
}

/* ── Quick 260713-08h: loan payment-schedule block (edit modal) ──────────── */
.subs-schedule-block {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--wa-08);
}
.subs-schedule-status {
  font-size: 12px;
  color: var(--text-1);
  margin: 0 0 10px;
}
.subs-schedule-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
/* Native file input is visually hidden — the <label> is the styled trigger. */
.subs-schedule-file-input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.subs-schedule-upload-btn,
.subs-schedule-delete-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* Zero Pico's native <button> margin-bottom — otherwise the delete <button>
     sits lower than the upload <label> in this flex row (CLAUDE.md rule). */
  margin: 0;
  font-size: 12px;
  padding: 7px 14px;
  border-radius: 999px;
  cursor: pointer;
  border: 1px solid var(--wa-10);
  background: var(--surface-row);
  color: var(--text-8);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.subs-schedule-upload-btn svg,
.subs-schedule-delete-btn svg {
  width: 14px;
  height: 14px;
}
.subs-schedule-upload-btn:hover {
  background: var(--c-blue-a14);
  color: var(--c-blue-12);
  border-color: var(--c-blue-a35);
}
/* Keyboard focus mirrors hover (the label proxies the hidden input). */
.subs-schedule-file-input:focus-visible + .subs-schedule-delete-btn,
.subs-schedule-upload-btn:focus-within {
  outline: none;
  box-shadow: 0 0 0 2px var(--c-blue-a50);
}
.subs-schedule-delete-btn:hover {
  background: var(--c-red-a12);
  color: var(--c-red);
  border-color: var(--c-red-a35-2);
}
.subs-schedule-preview-box {
  margin-top: 12px;
}
.subs-schedule-preview-summary {
  font-size: 12px;
  color: var(--text-8);
  margin: 0 0 10px;
}
.subs-schedule-preview-skipped {
  color: var(--c-amber);
}
.subs-schedule-currency-detected {
  font-size: 12px;
  color: var(--text-8);
  margin: 0 0 10px;
}
.subs-schedule-currency-hint {
  color: var(--c-amber);
}
.subs-schedule-preview-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.settings-card {
  background: var(--surface-card);
  border: 1px solid var(--wa-08);
  border-radius: 16px;
  padding: 19px;
  margin: 0;
}

/* ── Card head — uppercase caption (mirrors .home-calendar__caption) ────────── */
.settings-card__head {
  margin-bottom: 16px;
}

.settings-card__caption {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-1);
}

.settings-card__caption-icon {
  display: inline-flex;
}

.settings-card__caption-icon svg {
  width: 15px;
  height: 15px;
}

.settings-card__subtitle {
  font-size: 12px;
  color: var(--text-muted);
  margin: 4px 0 0;
}

.feed-url-row {
  display: flex;
  gap: 8px;
  align-items: stretch;
}

/* ── One-click subscribe buttons (Apple/Google) ────────────────────────────── */
.feed-sub-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 10px;
}

.feed-sub-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--surface-tile);
  border: 1px solid var(--wa-14);
  border-radius: 999px;
  color: var(--text-primary);
  font-size: 12px;
  font-weight: 500;
  padding: 7px 14px;
  text-decoration: none;
  transition: border-color 120ms ease, background 120ms ease;
}

.feed-sub-btn:hover {
  border-color: var(--wa-28);
  background: var(--surface-5);
}

.feed-sub-btn__icon {
  display: inline-flex;
}

.feed-sub-btn__icon svg {
  width: 15px;
  height: 15px;
}

/* ── Link row — URL + copy + square regenerate, ~34px ──────────────────────── */
/* input.-qualified (0,1,1) ties Pico's input:not(...) reset and wins by load
   order (theme.css after pico) so height/min-height actually pin — same
   technique as input.deal-form-input above. */
input.feed-url-input {
  flex: 1 1 auto;
  min-width: 0;
  height: 34px;
  min-height: 34px;
  box-sizing: border-box;
  background: var(--surface-tile);
  border: 1px solid var(--wa-10);
  border-radius: 10px;
  color: var(--text-primary);
  font-size: 11px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  padding: 0 11px;
  margin: 0;
  /* Long link is truncated with an ellipsis rather than wrapping. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

input.feed-url-input:focus {
  outline: none;
  border-color: var(--c-blue-a55);
}

.feed-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 34px;
  box-sizing: border-box;
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  padding: 0 14px;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}

.feed-btn__icon {
  display: inline-flex;
}

.feed-btn__icon svg {
  width: 13px;
  height: 13px;
}

/* «Копировать» — solid blue pill */
.feed-btn--copy {
  background: var(--c-blue-5);
  color: var(--text-2);
}

.feed-btn--copy:hover {
  background: var(--c-blue-17);
}

/* «Перевыпустить» — square ghost-danger icon button (34×34) */
.feed-btn--regen {
  width: 34px;
  padding: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--c-red-5);
  border-color: var(--c-red-a35-2);
}

.feed-btn--regen .feed-btn__icon svg {
  width: 14px;
  height: 14px;
}

.feed-btn--regen:hover {
  border-color: var(--c-red-a60);
  background: var(--c-red-a07);
}

/* ── Settings control-height unification (quick 260704-pi4) ─────────────────── */
/* Every settings input + pill + square icon button snaps to ONE height — the
   Integrations feed-url row (the .feed-url-input / «Копировать» reference = 34px),
   exposed as --settings-ctl-h. Scoped to .settings-shell so the shared
   .deal-form-input (52px) / .deal-submit-pill (44px) stay untouched inside the
   deal/task/event modals. Left intentionally smaller: currency/radio/preset chips
   + «+ добавить» (~28px), the label/value rows, and the ghost «Сбросить» link. */
.settings-shell {
  --settings-ctl-h: 34px;
}

/* Text / password / number inputs (display_name, password ×3, thresholds, users).
   Element-qualified (0,2,1) so it beats the global input.deal-form-input 52px. */
.settings-shell input.deal-form-input {
  height: var(--settings-ctl-h);
  min-height: var(--settings-ctl-h);
  padding-top: 0;      /* height + 0 vertical padding → text vertically centred */
  padding-bottom: 0;
  font-size: 13px;
}

/* Pills: Сохранить (every section) · Сменить пароль · Скачать xlsx/csv · Apple ·
   Google · Копировать · Создать пользователя → the same reference height, 13px/500. */
.settings-shell .deal-submit-pill,
.settings-shell .preset-save-pill,
.settings-shell .feed-sub-btn,
.settings-shell .feed-btn,
.settings-shell .users-add-pill {
  height: var(--settings-ctl-h);
  min-height: var(--settings-ctl-h);
  padding-top: 0;
  padding-bottom: 0;
  font-size: 13px;
  font-weight: 500;
}
/* preset-save-pill / users-add-pill are plain buttons → flex-centre the label at
   the fixed height (the others are already inline-flex). */
.settings-shell .preset-save-pill,
.settings-shell .users-add-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Square icon button — regenerate feed link: var × var. */
.settings-shell .feed-btn--regen {
  width: var(--settings-ctl-h);
  height: var(--settings-ctl-h);
}

/* Button icons 14px (feed-sub keeps its own 15px; give deal-submit an explicit size). */
.settings-shell .deal-submit-pill svg,
.settings-shell .feed-btn__icon svg {
  width: 14px;
  height: 14px;
}

/* ── Small footnote ────────────────────────────────────────────────────────── */
.feed-note {
  margin: 14px 0 0;
  font-size: 11px;
  line-height: 1.5;
  color: var(--surface-3);
}

/* ── «Пресеты задач» settings card (quick 260703-lrw) ───────────────────────── */
/* Groups: tight, divided like the Dashboard rows (border-top between blocks). */
.preset-block {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--hairline);
}
.preset-block:first-of-type {
  margin-top: 8px;
  padding-top: 0;
  border-top: none;
}

.preset-block__label {
  display: block;
  margin: 0 0 8px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* Chips + the ghost add-input share ONE wrapping row. */
.preset-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}

/* Compact chip pill with an inline × remove button. */
.preset-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px 8px 5px 12px;
  background: var(--surface-tile);
  border: 1px solid var(--wa-14);
  border-radius: 999px;
  font-size: 12px;
  color: var(--text-11);
}

.preset-chip__text {
  line-height: 1.2;
}

/* Element-qualified (.preset-chip button.preset-chip__x) so the compact 15px box
   beats Pico's `button` form-element padding/height/margin — a bare
   `.preset-chip__x` loses the race and Pico inflates the chip row to ~48px. */
.preset-chip button.preset-chip__x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  min-height: 0;
  padding: 0;
  margin: 0;
  border: none;
  border-radius: 999px;
  background: transparent;
  color: var(--text-muted);
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
}

.preset-chip__x:hover {
  background: var(--c-red-a14);
  color: var(--c-red-5);
}

/* «+ добавить» — a ghost chip (same height as chips): dashed, transparent, ~140px.
   Width is element+descendant-qualified (.preset-chips input.preset-add) so it
   beats Pico's `input:not(...) { width:100% }` reset — a bare `.preset-add` loses
   the specificity race and the field stretches full-width. */
.preset-add {
  flex: 0 0 auto;
  padding: 5px 12px;
  background: transparent;
  border: 1px dashed var(--wa-18);
  border-radius: 999px;
  font-size: 12px;
  color: var(--text-11);
  box-sizing: border-box;
}
.preset-chips input.preset-add {
  width: 140px;
  padding: 5px 12px;   /* element-qualified so Pico's larger input padding/height loses */
  height: auto;
  min-height: 0;
  line-height: 15px;   /* match the chip's content height (12px text) → equal pill height */
  margin: 0;
}
.preset-add::placeholder {
  color: var(--text-muted);
}
.preset-add:focus {
  border-style: solid;
  border-color: var(--c-blue-a50);
  outline: none;
}

/* «Сбросить к стандартным» — shared RED ghost reset button, sits left of the Save
   pill in the Дашборд/Календарь/Пресеты footers (mirrors .feed-btn--regen danger
   ghost). Var height matches the section control-height reference (--settings-ctl-h). */
.settings-reset-btn {
  height: var(--settings-ctl-h);
  display: inline-flex;
  align-items: center;
  padding: 0 16px;
  background: var(--c-amber-a08);
  border: 1px solid var(--c-amber-a45);
  border-radius: 999px;
  font-size: 13px;
  font-weight: 500;
  color: var(--c-amber);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color 0.12s, color 0.12s, background 0.12s;
}

.settings-reset-btn:hover {
  border-color: var(--c-amber-a65);
  background: var(--c-amber-a14);
  color: var(--c-amber-4);
}

/* Element-qualified (0,2,1) so Pico's base <button> rules can't inflate the height
   or re-add margin — mirrors the .settings-shell .*-pill pi4 technique. */
.settings-shell button.settings-reset-btn {
  height: var(--settings-ctl-h);
  margin: 0;
}

/* Footer: reset link (left) + «Сохранено ✓» flash & compact Save pill (right). */
.preset-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 18px;
}
.preset-actions__end {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* Compact blue Save pill (matches the compact section-footer spec). */
.preset-save-pill {
  padding: 7px 16px;
  margin: 0;   /* kill Pico's button margin-bottom */
  background: var(--c-blue);
  color: var(--text-2);
  border: none;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
}
.preset-save-pill:hover {
  background: var(--c-blue-3);
}

/* ── /account «Личный кабинет» — profile + password cards (quick 260702-1iy) ─── */
/* Reuse .settings-page-*, .settings-card*, .deal-form-input, .deal-submit-pill.
   Only account-specific spacing + read-only rows + flash/hint styles below. */

/* Vertical gap between the two cards (profile + password). */
.account-cards > * + * {
  margin-top: 14px;
}

/* Stacked form: inputs then the Save/Change pill. */
.account-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
}

/* Read-only label/value rows («Логин», «Регистрация»). */
.account-fields {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--wa-07);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.account-field-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.account-field-label {
  color: var(--text-muted);
  font-size: 12px;
}

.account-field-value {
  color: var(--text-primary);
  font-size: 13px;
  overflow-wrap: anywhere;
}

/* Flash lines — success (green) / error (red), muted to fit the dark system. */
.account-flash {
  margin: 12px 0 0;
  font-size: 12.5px;
}

.account-flash--ok {
  color: var(--c-green-5);
}

.account-flash--error {
  color: var(--c-red);
}

/* Muted hint shown to the env-admin instead of the password form. */
.account-hint {
  margin: 0;
  color: var(--text-muted);
  font-size: 12.5px;
  line-height: 1.5;
}

/* ── Env-admin-ONLY «Пользователи» card (quick 260703-luj) ──────────────────── */
/* Reuses .settings-card*, .deal-form-input, .deal-submit-pill, .account-flash. */
.users-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 14px;
  /* 260721-iru: inset scroll box (canon: .subs-schedule-list) — rows scroll in
     place; the «Добавить пользователя» control stays below the box. */
  max-height: 260px;
  overflow-y: auto;
  background: var(--surface-inset);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 8px 10px;
}

.users-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 8px 10px;
  background: var(--surface-tile);
  border: 1px solid var(--wa-08);
  border-radius: 12px;
  padding: 10px 12px;
}

.users-row__info {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  min-width: 0;
}

.users-row__name {
  color: var(--text-primary);
  font-size: 13px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  overflow-wrap: anywhere;
}

.users-row__display {
  color: var(--text-1);
  font-size: 12px;
  overflow-wrap: anywhere;
}

.users-row__date {
  color: var(--text-muted);
  font-size: 11.5px;
}

.users-row__reset-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  background: var(--surface-5);
  border: 1px solid var(--wa-14);
  border-radius: 9px;
  color: var(--text-5);
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease;
}

.users-row__reset-btn:hover {
  border-color: var(--wa-28);
  background: var(--surface-13);
}

.users-row__reset-btn svg {
  width: 15px;
  height: 15px;
}

/* Inline reset + create forms span the full row when revealed. */
.users-reset-form,
.users-create-form {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0;
}

.users-create-form {
  margin-top: 10px;
}

.users-empty {
  color: var(--text-muted);
  font-size: 12.5px;
  margin: 0;
}

.users-add-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--surface-24);
  border: 1px solid var(--c-blue-a40);
  border-radius: 999px;
  color: var(--c-blue-11);
  font-size: 12.5px;
  font-weight: 500;
  padding: 8px 15px;
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease;
}

.users-add-pill:hover {
  border-color: var(--c-blue-a60);
  background: var(--surface-20);
}

.users-add-pill svg {
  width: 15px;
  height: 15px;
}

/* ── Env-admin-ONLY «Баг-репорты» card (quick 260714-138) ────────────────────
   Reuses .settings-card* (caption/subtitle). Status dot colors reuse the
   existing palette values (amber #FF9F0A / muted / green #30d158) — no new
   tokens introduced, per the nav-dot precedent (SCOUT §9). */
.bug-reports-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  /* 260721-iru: inset scroll box (canon: .subs-schedule-list) so many reports
     scroll in place instead of growing the settings pane. */
  max-height: 260px;
  overflow-y: auto;
  background: var(--surface-inset);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 8px 10px;
}

.bug-report-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: start;
  gap: 10px;
  background: var(--surface-tile);
  border: 1px solid var(--wa-08);
  border-radius: 12px;
  padding: 10px 12px;
}

.bug-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-top: 5px;
  flex: 0 0 auto;
}

.bug-dot--new {
  background: var(--c-amber);
  box-shadow: 0 0 0 3px var(--c-amber-a18-3);
}

.bug-dot--seen {
  background: var(--text-muted);
}

.bug-dot--fixed {
  background: var(--c-green);
}

.bug-report-row__body {
  min-width: 0;
}

.bug-report-row__message {
  margin: 0 0 4px;
  color: var(--text-primary);
  font-size: 13px;
  line-height: 1.4;
  overflow-wrap: anywhere;
  cursor: pointer;
  /* Collapsed by default — click to expand (finBugToggle toggles this class). */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.bug-report-row__message--expanded {
  -webkit-line-clamp: unset;
  overflow: visible;
}

.bug-report-row__meta {
  margin: 0;
  color: var(--text-muted);
  font-size: 11.5px;
  overflow-wrap: anywhere;
}

.bug-report-row__actions {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* Reset Pico <button> defaults (padding/display/box-shadow) on the status
   pills; focus ring is a box-shadow (not outline), scoped to :focus-visible. */
.bug-action-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-5);
  border: 1px solid var(--wa-14);
  border-radius: 999px;
  color: var(--text-5);
  font-size: 11.5px;
  font-weight: 500;
  padding: 5px 12px;
  margin: 0;
  cursor: pointer;
  box-shadow: none;
  transition: border-color 120ms ease, background 120ms ease;
}

.bug-action-btn:hover {
  border-color: var(--wa-28);
  background: var(--surface-13);
}

.bug-action-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--c-blue-a45);
}

.bug-action-btn--fixed {
  border-color: var(--c-green-a35);
  color: var(--c-green-4);
}

.bug-action-btn--fixed:hover {
  border-color: var(--c-green-a55);
  background: var(--c-green-a10);
}

.bug-reports-empty {
  color: var(--text-muted);
  font-size: 12.5px;
  margin: 0;
}

/* ── «Колокольчик обновлений» bell modal (quick 260714-1xr) ──────────────────
   Plain modal (not a settings card) — width via dialog.modal-form > article
   (default). Reuses the app palette: green ✓ = #30d158 (same as bug-dot--fixed),
   blue ✦ = the sidebar accent #22e754. */
/* 260721-iru: self-contained scroll card (mirrors .subs-schedule-list canon) so a
   long release history scrolls INSIDE its own --surface-inset box instead of
   stretching the modal to 90vh. The sticky header (with the × moved into it)
   stays pinned above this box. */
.releases-list {
  display: flex;
  flex-direction: column;
  gap: 18px;
  max-height: 260px;
  overflow-y: auto;
  background: var(--surface-inset);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 14px 16px;
}

.release-entry + .release-entry {
  padding-top: 16px;
  border-top: 1px solid var(--wa-08);
}

.release-entry__header {
  margin: 0 0 8px;
  color: var(--text-primary);
  font-size: 13.5px;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.release-entry__group {
  margin-top: 8px;
}

.release-entry__group-title {
  margin: 0 0 4px;
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.release-entry__bullets {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.release-bullet {
  display: flex;
  align-items: baseline;
  gap: 8px;
  color: var(--text-5);
  font-size: 12.5px;
  line-height: 1.4;
  overflow-wrap: anywhere;
}

.release-bullet__mark {
  flex: 0 0 auto;
  color: var(--c-blue);
}

.release-bullet__mark--fixed {
  color: var(--c-green);
}

.releases-empty {
  color: var(--text-muted);
  font-size: 12.5px;
  margin: 0;
}

/* ── Env-admin-ONLY «Обновления» card (quick 260714-1xr) ──────────────────────
   Reuses .settings-card*, .deal-form-input, .deal-submit-pill, .releases-list*
   (bullet groups above) — the row/list below is the admin-only publish list,
   distinct markup from the bell modal's grouped entries. */
.releases-publish-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 16px;
}

.releases-publish-form__notes {
  resize: vertical;
  min-height: 90px;
  font-family: inherit;
}

.releases-publish-form__hint {
  margin: -2px 0 0;
  color: var(--text-muted);
  font-size: 11.5px;
}

.releases-list--admin {
  display: flex;
  flex-direction: column;
  gap: 8px;
  /* 260721-iru: inset scroll box (canon: .subs-schedule-list) so a long admin
     history scrolls in place instead of growing the settings pane. */
  max-height: 260px;
  overflow-y: auto;
  background: var(--surface-inset);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 8px 10px;
}

.release-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 8px 10px;
  background: var(--surface-tile);
  border: 1px solid var(--wa-08);
  border-radius: 12px;
  padding: 10px 12px;
}

.release-row__info {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  min-width: 0;
}

.release-row__version {
  color: var(--text-primary);
  font-size: 13px;
  overflow-wrap: anywhere;
}

.release-row__title {
  color: var(--text-1);
  font-size: 12px;
  overflow-wrap: anywhere;
}

/* Reset Pico <button> defaults (padding/display/box-shadow); focus ring is a
   box-shadow (not outline), scoped to :focus-visible — mirrors .users-row__reset-btn. */
.release-row__delete-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  background: var(--surface-5);
  border: 1px solid var(--wa-14);
  border-radius: 9px;
  color: var(--text-5);
  cursor: pointer;
  box-shadow: none;
  transition: border-color 120ms ease, background 120ms ease;
}

.release-row__delete-btn:hover {
  border-color: var(--c-red-a45);
  background: var(--c-red-a10-2);
  color: var(--c-red-7);
}

.release-row__delete-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--c-blue-a45);
}

.release-row__delete-btn svg {
  width: 15px;
  height: 15px;
}

.releases-empty--admin {
  color: var(--text-muted);
  font-size: 12.5px;
  margin: 0;
}


/* ── Top-center toast pill (260709-0hp) ───────────────────────────────────────
   Popover API element (top-layer) so it shows ABOVE the settings <dialog>.
   Overrides the [popover] UA defaults (inset:0; margin:auto; border; padding). */
.app-toast{
  position:fixed; inset:auto; margin:0; overflow:visible;
  top:16px; left:50%;
  transform:translateX(-50%) translateY(0);
  display:flex; align-items:center; gap:6px;
  max-width:360px;
  padding:9px 18px; border-radius:999px;
  background:var(--c-green-a16);
  backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
  border:1px solid var(--c-green-a45);
  box-shadow:0 6px 20px var(--sc-28);
  color:var(--c-green-4); font-size:13px; font-weight:500; line-height:1;
  opacity:1; pointer-events:none;
  transition:
    opacity 180ms ease,
    transform 180ms ease,
    background-color 200ms ease,
    border-color 200ms ease,
    color 200ms ease,
    overlay 180ms ease allow-discrete,
    display 180ms ease allow-discrete;
}
.app-toast__icon{flex:0 0 auto; display:inline-flex; align-items:center}
.app-toast__check{font-size:13px; line-height:1; flex:0 0 auto}
/* «Loading» variant (260709-26w) — neutral pill + a spinning refresh-cw icon.
   Same size/position; morphs to the green success pill in place (color transition). */
.app-toast--loading{
  background:var(--nx-7-a80);
  border-color:var(--wa-14);
  color:var(--text-primary);
}
.app-toast__spin svg{display:block; animation:app-toast-spin 1s linear infinite}
@keyframes app-toast-spin{to{transform:rotate(360deg)}}
/* «Danger» variant (260714-3la) — red pill + trash icon for deletions.
   Overrides the green base the same way loading does. */
.app-toast--danger{
  background:var(--c-red-a14-2);
  border-color:var(--c-red-a40-2);
  color:var(--c-red-6);
}
.app-toast__trash svg{display:block}
@media (prefers-reduced-motion: reduce){
  .app-toast__spin svg{animation:none}
}
/* Clipped text box — keeps the pill from stretching; the inner span may scroll.
   (260709-1yw: deal-added toast with a marquee for long subject names.) */
.app-toast__text{
  flex:0 1 auto; min-width:0; overflow:hidden; white-space:nowrap;
}
.app-toast__text-inner{display:inline-block; white-space:nowrap}
/* Marquee: slow ping-pong translateX; soft fade at both edges via mask. Duration +
   shift distance are set inline by toast.js from the measured overflow (~40px/s). */
.app-toast--marquee .app-toast__text{
  -webkit-mask-image:linear-gradient(90deg, transparent 0, var(--surface-6) 12px, var(--surface-6) calc(100% - 12px), transparent 100%);
  mask-image:linear-gradient(90deg, transparent 0, var(--surface-6) 12px, var(--surface-6) calc(100% - 12px), transparent 100%);
}
.app-toast--marquee .app-toast__text-inner{
  animation:app-toast-marquee var(--marquee-dur, 6s) ease-in-out infinite;
}
@keyframes app-toast-marquee{
  0%, 10%   {transform:translateX(0)}
  45%, 55%  {transform:translateX(var(--marquee-shift, 0))}
  90%, 100% {transform:translateX(0)}
}
@media (prefers-reduced-motion: reduce){
  /* No scrolling — clip long names with an ellipsis instead. */
  .app-toast__text{text-overflow:ellipsis}
  .app-toast--marquee .app-toast__text-inner{animation:none}
}
/* Exit-to state (popover closing) — slide-up + fade; display:none deferred. */
.app-toast:not(:popover-open){opacity:0; transform:translateX(-50%) translateY(-8px)}
/* Enter-from state (popover opening) — slide-down + fade in. */
@starting-style{
  .app-toast:popover-open{opacity:0; transform:translateX(-50%) translateY(-8px)}
}
@media (prefers-reduced-motion: reduce){
  .app-toast{transform:translateX(-50%)}
  .app-toast:not(:popover-open){transform:translateX(-50%)}
  @starting-style{
    .app-toast:popover-open{transform:translateX(-50%)}
  }
}

/* ── Subscriptions modal «Секции» (quick 260719-prw) ─────────────────────────
   Every selector below is scoped under `.subs-modal` (the modifier class added
   to the subscriptions dialog alongside the shared `modal modal-form`). This
   dialog shares `.deal-form-input`/`.deal-form-select`/`.deal-form-row-2col`/
   `.form-actions` with deals/_new_modal.html + _edit_modal.html — NO bare
   unscoped rule for those classes is added here; the deal modals keep their
   existing 52px fields untouched. */

/* 1) Sections + captions + dividers ----------------------------------------- */
.subs-modal .subs-section {
  border-top: 1px solid var(--hairline);
  padding-top: 14px;
  margin-top: 14px;
}
.subs-modal .subs-section:first-of-type {
  border-top: none;
  margin-top: 0;
  padding-top: 0;
}
.subs-modal .subs-section__caption {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--text-muted);
  margin: 0 0 10px;
}

/* 2) Even grid + uniform compact height (34px, scoped — deals stay 52px) ---- */
.subs-modal {
  --subs-ctl-h: 34px;
}
/* Element-qualified (0,3,1) to beat the global `input.deal-form-input,
   select.deal-form-select` (0,1,1) height rule @5408. */
.subs-modal input.deal-form-input,
.subs-modal select.deal-form-select {
  height: var(--subs-ctl-h);
  min-height: var(--subs-ctl-h);
  padding-top: 0;
  padding-bottom: 0;
  font-size: 13px;
}
.subs-modal select.deal-form-select {
  padding-right: 32px; /* keep room for the chevron */
}
/* #subs-note is a <textarea class="deal-form-input"> — not matched by the
   input/select-qualified rule above, so it would otherwise inherit the base
   `.deal-form-input{height:52px}`. Give it its own sensible min-height instead
   of pinning it to the 34px control height. */
.subs-modal textarea.deal-form-input {
  height: auto;
  min-height: 56px;
  padding: 10px 12px;
}
.subs-modal .deal-form-body {
  gap: 12px;
}
.subs-modal .deal-form-row-2col {
  gap: 12px;
}
.subs-modal .deal-form-label {
  font-size: 12px;
  color: var(--text-muted);
}
.subs-modal .deal-form-field {
  gap: 5px;
}

/* 3) Green ✓ removal (Pico's aria-invalid="false" background icon) —
   INPUT ONLY so the <select> chevron (#subs-billing-day, class
   `deal-form-input deal-form-select`) survives. !important mirrors the
   existing @5285 pattern (Pico's own [aria-invalid] rule out-specifies a
   plain class selector via its `:not(select)` clause). The `aria-invalid`
   attribute itself is left in the HTML (a11y) — only the visual icon is
   suppressed. */
.subs-modal input.deal-form-input[aria-invalid="false"] {
  background-image: none !important;
}

/* 4) Footer divider (pills unchanged — .deal-submit-pill / .deal-cancel-pill) */
.subs-modal .form-actions {
  border-top: 1px solid var(--hairline);
  padding-top: 14px;
}

/* 5) Compact header — removed (quick 260721-wwo): the per-kind dynamic
   icon+title (`.subs-modal-title`/`.subs-title*`) was replaced by a single
   canon `<h2>` in the template (19px/500 via `.modal-form--canon`'s k7s
   rule); kind is conveyed only by the kind chips now. */

/* 6) РАСЧЁТ section visibility — loan-only, pure CSS (mirrors is_loan, no JS
   added). No Jinja `hidden` on `.subs-section--calc` itself; this is the only
   thing that toggles it. */
.subs-modal .subs-section--calc {
  display: none;
}
.subs-modal article:has(input[name="kind"]:checked:not([value="subscription"])) .subs-section--calc {
  display: block;
}

/* ── quick 260721-wwo: payment modal → form canon shell ─────────────────────
   Dialog now also carries `.modal-form--canon` (alongside `.subs-modal`).
   Scoped under `.modal-form--canon.subs-modal` so nothing here touches the
   existing 260719-prw block above (still governs plain `.subs-modal` — kept
   for the rare case the modifier class is ever absent). Title is now a canon
   `<h2>` (19px/500 via the k7s rule ~1014) — the old per-kind icon+title
   system + its CSS (removed above, item 5) no longer exists. */

/* ── quick 260722-jk9 (Bug #2): ~14px between caption groups ────────────────
   Root cause (confirmed): `.subs-modal .subs-section{margin-top:14px;
   padding-top:14px}` (~L12053) STACKS with `.subs-modal .deal-form-body{
   gap:12px}` (~L12097) → ~27px before the border-top even starts, plus the
   section's own `border-top+padding-top` add another ~15px, plus the
   caption's `margin:0 0 10px` — ≈50px total void between groups. Kill the
   flex-gap AND the section's own margin-top for THIS canon dialog only
   (plain `.subs-modal` without the modifier class, and any other modal, are
   untouched — different, lower-specificity selector); the remaining
   `border-top(1px)+padding-top(14px)` alone gives the ~14-15px divider the
   mock wants. `:first-of-type` (still `border-top:none;margin-top:0;
   padding-top:0`, unscoped rule above) keeps ОСНОВНОЕ itself flush under the
   kind chips — untouched by either override below. */
.modal-form--canon.subs-modal .subs-section { margin-top: 0; }
.modal-form--canon.subs-modal .deal-form-body {
  gap: 0;
}

/* ── quick 260722-lku (Bug #2, root cause #2): #subs-period-field/
   #subs-term-fields are Jinja-`hidden` for non-subscription kinds (template
   `{% if kind != 'subscription' %}hidden{% endif %}`), but native `[hidden]`
   (a UA-origin `display:none` rule) does NOT win over the author-origin
   `.deal-form-field{display:flex}`/`.deal-form-row-2col{display:grid}` these
   elements also carry — author beats UA regardless of specificity (same
   documented gotcha as ~L5884). Result: for кредит/рассрочка/ипотека the
   Срок chips + Первая-оплата/Количество-оплат row rendered anyway, sitting
   between the ОПЛАТА amount row and Категория/Примечание — the vertical
   void. Force `display:none` explicitly, same pattern as ~L5889. */
.modal-form--canon.subs-modal #subs-period-field[hidden],
.modal-form--canon.subs-modal #subs-term-fields[hidden] {
  display: none !important;
}

/* Fields to 38px (not 34px — 260719-prw's --subs-ctl-h). SPECIFICITY TRAP:
   `.subs-modal input.deal-form-input,.subs-modal select.deal-form-select`
   (~12016) pins height:34px/min-height:34px at (0,2,1); the wd2/k7s canon
   blocks (~1025-1032, 1086-1090) are (0,2,0)/(0,3,0) — still lower. This
   element-qualified, class-doubled selector is (0,4,1) — outranks all of
   them. Select keeps its chevron `padding-right:32px` from the unqualified
   ~12024 rule (untouched — lower specificity, and we don't set that property). */
.modal-form--canon.subs-modal input.deal-form-input,
.modal-form--canon.subs-modal select.deal-form-select {
  height: 38px;
  min-height: 38px;
}

/* Kind chips (Подписка/Кредит/Рассрочка/Ипотека) — tighter for the 4-up row.
   Scoped to #subs-kind-chips only; loan-mode/payment-type/period chips get
   their own treatment in Tasks 2-3. `:has(input:checked)` blue-fill (~10825)
   and the `:focus-visible`-only ring (~10639/10646) are untouched selectors —
   still apply here unchanged. */
.modal-form--canon.subs-modal #subs-kind-chips .subs-kind-chip {
  padding: 5px 12px;
  font-size: 11.5px;
}

/* × placement: neutralize the absolute-corner rule (~12511, quick 260720-odc)
   for THIS modal only — position/top/right/z-index fall back to Pico's
   in-flow `float:right` (`dialog>article>header :is(a,button)[rel=prev]`)
   + app canon `.modal [rel="prev"]` (~10004: size/opacity/focus-ring only).
   `margin` is left undeclared here so ~12511's `margin:0` keeps winning
   (flush corner, no float-right auto-margin gap). Matches ONLY
   `.subs-modal header [rel="prev"]` — #subs-detail-header's × (~12123-ish,
   `#subs-detail-header [rel="prev"]`) and dialog.subs-pay-modal's × use
   different selectors and are untouched. */
.modal-form--canon.subs-modal header [rel="prev"] {
  position: static;
  top: auto;
  right: auto;
  z-index: auto;
}

/* ── quick 260721-wwo: Подписка layout per mock ──────────────────────────────
   Markup-only reorder (Название|Сервис, Категория|Примечание paired into
   `.deal-form-row-2col`; Активна trailing full-width; ПРОЧЕЕ folded into
   ОПЛАТА) — no id/name/data-attrs/hidden/disabled changed, no JS touched. */

/* Срок mini-segment (В месяц | В год) — compact rectangular segment control,
   distinct from the pill-shaped #subs-kind-chips row above. Scoped to
   #subs-period-chips only; other `.subs-kind-chip` consumers (loan-mode,
   payment-type, kind chips) are untouched. */
.modal-form--canon.subs-modal #subs-period-chips {
  border-radius: 8px;
  padding: 2px;
}
.modal-form--canon.subs-modal #subs-period-chips .subs-kind-chip {
  padding: 5px 14px;
  font-size: 12px;
  border-radius: 6px;
}

/* Первая оплата/Количество оплат hint — 11.5px (mock). Scoped under
   `.modal-form--canon.subs-modal`; the list-page usages of `.subs-field-hint`
   (different DOM location) are untouched. */
.modal-form--canon.subs-modal .subs-field-hint {
  font-size: 11.5px;
  /* Muted, not green: as an in-field sibling of an [aria-invalid="false"]
     input the hint matches Pico's valid-helper `~ small` rule (0,2,2), which
     outranks the base .subs-field-hint (0,1,0) color. This (0,3,0) wins. */
  color: var(--text-muted);
}

/* ── quick 260721-wwo: Кредит layout + blue strip tokens + strip wording ─────
   Markup unchanged in `#subs-calc-fields` — the mock's «Сумма кредита |
   Валюта» / «Первая оплата | Сервис» pairings are NOT achievable without
   moving `#subs-currency`/`#subs-service-url`, which are the SINGLE shared
   nodes also used by Подписка's ОСНОВНОЕ/ОПЛАТА rows (Task 2, Подписка
   commit) and Рассрочка/Ипотека (Task 3) — moving them would either
   duplicate/rename a hook (forbidden) or require JS/handler edits (outside
   the HARD LOGIC-FREEZE). Flagged for the Task 4 human-verify checkpoint
   per the plan's own escape hatch; see SUMMARY.md Deviations. The two rows
   that DON'T need those shared fields (Сумма кредита|Ставка, Срок|Тип
   платежа) were already gap-free in this order — no reorder needed there. */

/* Режим (Рассчитать по ставке | Платёж вручную | Загрузить график) — narrow
   OUTLINE chips instead of the filled-tile pill row above; `:has(input:
   checked)` blue-fill kept (re-asserted here at higher specificity, same
   visual result as the base ~10825 rule). Scoped to #subs-loan-mode-chips
   only. */
.modal-form--canon.subs-modal #subs-loan-mode-chips {
  background: transparent;
  gap: 6px;
  padding: 0;
}
.modal-form--canon.subs-modal #subs-loan-mode-chips .subs-kind-chip {
  background: transparent;
  border: 1px solid var(--wa-14);
  padding: 5px 12px;
  font-size: 11.5px;
}
.modal-form--canon.subs-modal #subs-loan-mode-chips .subs-kind-chip:has(input:checked) {
  background: var(--c-blue);
  border-color: var(--c-blue);
  color: var(--text-2);
}

/* Тип платежа (Аннуитет | Дифференцированный) — same compact mini-segment
   treatment as Подписка's Срок chips (#subs-period-chips, above). Scoped to
   #subs-payment-type-chips only. */
.modal-form--canon.subs-modal #subs-payment-type-chips {
  border-radius: 8px;
  padding: 2px;
  /* Same level as the «Срок (платежей)» input beside it (260722): its label
     is a real <label> and gets the 8px margin-bottom from `dialog.modal-form
     label`, while «Тип платежа» is a <span> that the element rule misses —
     compensate here; height matches the 38px canon inputs, chips centered. */
  margin-top: 8px;
  height: 38px;
  box-sizing: border-box;
  align-items: center;
}
.modal-form--canon.subs-modal #subs-payment-type-chips .subs-kind-chip {
  padding: 5px 14px;
  font-size: 12px;
  border-radius: 6px;
}

/* Blue mock-token strip — `.loan-calc-summary` is the shared class on BOTH
   `#loan-calc-summary` (credit/mortgage calc preview) and the NEW
   `#subs-installment-summary` (Task 3); scoping the class alone covers both
   IDs. Overrides the base blue-a10/a28 tokens (~10863-10864) at higher
   specificity. */
.modal-form--canon.subs-modal .loan-calc-summary {
  background: rgba(47, 107, 255, .08);
  border: 1px solid rgba(47, 107, 255, .3);
  border-radius: 10px;
}

/* ── quick 260721-wwo: Рассрочка layout + amount÷term display preview ───────
   Markup: dual #subs-amount label (Сумма/«Сумма покупки»), the «Рассчитать
   по ставке» chip hidden for installment (radio stays in the DOM — never
   removed, so #subs-loan-mode-chips is untouched for other kinds), and the
   NEW #subs-installment-summary strip (blue tokens via the shared
   .loan-calc-summary rule above). No id/name/data-attrs/hidden/disabled/JS
   orchestration changed — only the ONE new additive JS function
   (finRenderInstallmentSummary) + its two input listeners. */

/* Сумма — dual label toggle. Generic «Сумма» is the default; «Сумма покупки»
   shows only for kind=installment. Same #subs-amount input either way. */
.modal-form--canon.subs-modal .subs-amount-label--purchase {
  display: none;
}
.modal-form--canon.subs-modal article:has(input[name="kind"][value="installment"]:checked) .subs-amount-label--generic {
  display: none;
}
.modal-form--canon.subs-modal article:has(input[name="kind"][value="installment"]:checked) .subs-amount-label--purchase {
  display: inline;
}

/* ── quick 260722-jk9 (Bug #1): один лейбл суммы в calc-режиме ───────────────
   Investigation-confirmed: in a loan kind (credit/mortgage) with
   loan_mode='calc' (the default), BOTH #subs-amount (ОПЛАТА «Сумма», already
   `disabled` server-side in calc mode — hiding it changes nothing about
   submit) AND #subs-loan-principal (РАСЧЁТ «Сумма кредита») render at once —
   two dollar-amount labels for one concept. Hide the ОПЛАТА amount CELL only
   for loan+calc (installment has its own dual-label above and is unaffected —
   its calc chip is CSS-hidden so it never satisfies `loan_mode=calc:checked`
   here); subscription kind is excluded via `:not([value="subscription"])`.
   No id/name/disabled/hidden touched — #subs-amount stays in the DOM,
   `disabled`, and out of the submit — this is purely a visibility fix. */
.modal-form--canon.subs-modal article:has(input[name="kind"]:checked:not([value="subscription"])):has(input[name="loan_mode"][value="calc"]:checked) .deal-form-field:has(#subs-amount) { display: none; }
/* Валюта would otherwise sit alone in a 2-col grid with an empty gap where
   Сумма used to be — collapse that ONE row to a single column so it spans
   full width instead of orphaning in the left half. */
.modal-form--canon.subs-modal article:has(input[name="kind"]:checked:not([value="subscription"])):has(input[name="loan_mode"][value="calc"]:checked) .deal-form-row-2col:has(#subs-amount) {
  grid-template-columns: 1fr;
}

/* «Рассчитать по ставке» — installment has no rate; hide just that chip
   (its radio input stays in the DOM, never removed/disabled, so it can't
   collide with anything — it simply becomes unreachable by mouse while
   installment is selected, matching the mock's 2-mode Режим row). */
.modal-form--canon.subs-modal article:has(input[name="kind"][value="installment"]:checked) #subs-loan-mode-chips label:has(input[name="loan_mode"][value="calc"]) {
  display: none;
}

/* ── quick 260721-wwo: Ипотека layout + Срок,лет display hint ────────────────
   #subs-calc-payments-total (persisted, name=payments_total) stays enabled/
   submitting for ALL loan kinds — only its WRAPPER's display toggles per
   kind (never `disabled`, never `hidden` attr). The NEW #subs-mortgage-years
   (no name=, never submits) shows in the opposite case, so the calc grid's
   2-col row always has exactly 2 visible cells (Срок variant + Тип платежа)
   — no gap either way. Value-sync (years↔payments_total mirror + the
   back-fill on kind→mortgage) is NEW additive JS (finSyncMortgageYears). */
.modal-form--canon.subs-modal #subs-mortgage-years-field {
  display: none;
}
.modal-form--canon.subs-modal article:has(input[name="kind"][value="mortgage"]:checked) #subs-mortgage-years-field {
  display: flex;
}
.modal-form--canon.subs-modal article:has(input[name="kind"][value="mortgage"]:checked) #subs-calc-payments-total-field {
  display: none;
}

/* ── Quick 260720-1yc: read-only detail modal — schedule/debt/clickable-row bits.
   Reuses .deal-detail-tile*, .deal-detail-grid*, .deal-detail-footer* as-is (not
   restyled here) — only NEW subs-prefixed classes are added. ──────────────── */

/* Row click target (whole row opens the detail modal; row action buttons
   stopPropagation in the template so they keep working). */
.subs-row--clickable {
  cursor: pointer;
}

/* ── Detail header re-compose (Quick 260720-367, Part 1) ──────────────────
   Scoped to #subs-detail-header ONLY — the deal-detail modal reuses the
   shared .deal-detail-* classes below and must NEVER be restyled from here.
   Goal: × fully inside the card (top padding, dialog.modal-detail>article
   has padding-top:0); [name][kind badge][calc badge] grouped LEFT; «активна»
   pushed to the RIGHT edge; × last. DOM order is already name → kind badge
   → calc badge → status pill → × (unchanged) — achieved via CSS only. */
#subs-detail-header {
  padding-top: 20px;
}
#subs-detail-header .deal-detail-subject {
  /* Cancels the shared rule's margin:0 auto 0 0, which would otherwise
     float the badges to the center/right instead of grouping them with
     the name on the left. */
  margin-right: 0;
}
#subs-detail-header .subs-detail-status-pill {
  margin-left: auto;
}
#subs-detail-header .subs-credit-badge,
#subs-detail-header .subs-calc-badge {
  /* Badges never shrink; the name (flex:0 1 auto;min-width:0 from the
     shared subject rule) ellipsizes first when space is tight. */
  flex: 0 0 auto;
}
/* ── × in-flow, end of header row (Quick 260720-vyv) — SUPERSEDES the
   260720-odc absolute-corner × (removed: the `:has()` positioning-context
   rule, the header-row right-padding reservation, and the absolute
   top/right pin). The mock wants a single-line header ending in a round ×,
   not a floating corner button — the status pill's margin-left:auto still
   pushes [pill][×] to the row's right edge, but the × is now the LAST
   in-flow flex child instead of being pulled out of flow. Scoped to
   #subs-detail-header ONLY — does not touch the pay mini-modal's corner ×
   (dialog.subs-pay-modal [rel="prev"]) or the add/edit modal's corner ×
   (.subs-modal header [rel="prev"]), both of which stay absolute. */
#subs-detail-header [rel="prev"] {
  /* LAYOUT ONLY (260721-0qj): keep the × as the last in-flow flex child of the
     one-line header — flex:0 0 auto so it doesn't stretch, margin:0 kills Pico's
     margin-left:auto so the «активна» pill's own auto-margin alone right-aligns
     [pill][×] (the jgo double-auto-margin bug). Appearance + behaviour fall back
     to the app canon `.modal [rel="prev"]` used by the deal detail: bare × glyph,
     transparent bg, muted → hover opacity:1 (brighter), ring only on :focus-visible.
     The round backdrop added in vyv/06z is REMOVED here (not overridden). Scoped
     to #subs-detail-header — pay mini-modal × and add/edit × stay absolute-corner. */
  flex: 0 0 auto;
  margin: 0;
}

/* Header status pill (active/off) — small muted pill, mirrors deal-status-pill
   sizing without pulling in its color-per-status logic (subs only has 2 states). */
.subs-detail-status-pill {
  display: inline-flex;
  align-items: center;
  height: 26px;
  padding: 0 12px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  background: var(--c-green-a18);
  color: var(--c-green);
  flex: 0 0 auto;
}
.subs-detail-status-pill--off {
  background: var(--nx-1-a18);
  color: var(--text-1);
}

/* ── Detail tile scoped overrides (Quick 260720-vyv) ───────────────────────
   The mock's tile spec (bg #131c2e r10, padding 11px 13px, label 11px
   uppercase, value 17px/500 nowrap, sub 11.5px) differs slightly from the
   shared .deal-detail-tile* (reused as-is by the deals modal) — scope
   everything to #subs-detail-body so deals is never touched. */
#subs-detail-body .deal-detail-tile {
  background: var(--surface-tile);
  border-radius: 10px;
  padding: 11px 13px;
}
#subs-detail-body .deal-detail-tile__label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-9);
}
#subs-detail-body .deal-detail-tile__value {
  font-size: 17px;
  font-weight: 500;
  white-space: nowrap;
}
#subs-detail-body .deal-detail-tile__sub {
  font-size: 11.5px;
  color: var(--text-9);
}
/* Blue-bordered «Следующее/Следующий» tile — subs-only concept. */
#subs-detail-body .deal-detail-tile--next {
  border: 1px solid var(--c-blue-a40-2);
}

/* Остаток долга tile — purple debt token, matches .subs-metric__value--debt (#bf5af2). */
.subs-detail-tile__value--debt {
  color: var(--c-violet-2);
}

/* Credit progress bar (Quick 260720-vyv) — distinct from the page-level
   .subs-progress (list.html month bar); width is the pure-int progress_pct
   from _build_detail_context, never a float/user string. */
.subs-loan-progress {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 16px;
}
.subs-loan-progress__track {
  flex: 1 1 auto;
  height: 6px;
  border-radius: 999px;
  /* Confirmed via DevTools (260721-06z): the track was already full-width (545px)
     with the blue fill at 16%, but #131c2e blends into the modal bg so it read as
     absent. Lightened so the grey track is actually visible behind the fill. */
  background: var(--wa-09);
  overflow: hidden;
}
.subs-loan-progress__fill {
  height: 100%;
  border-radius: 999px;
  background: var(--c-blue-5);
}
.subs-loan-progress__caption {
  flex: 0 0 auto;
  font-size: 12px;
  color: var(--text-9);
  white-space: nowrap;
}

/* Schedule caption + list + collapse-toggle. */
.subs-schedule-caption {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-1);
  margin: 20px 0 8px;
}
/* 260720-vyv: self-contained scroll card (bg/border/radius) — the modal no
   longer stretches to a long schedule; the list scrolls INSIDE its own box. */
.subs-schedule-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 260px;
  overflow-y: auto;
  background: var(--surface-inset);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 2px 10px;
}
.subs-schedule-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 4px;
  border-bottom: 1px solid var(--hairline);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.subs-schedule-row__date {
  color: var(--text-primary);
  flex: 0 0 auto;
}
.subs-schedule-row__amount {
  color: var(--text-3);
  margin-left: auto;
}
.subs-schedule-row__check {
  color: var(--c-green);
  flex: 0 0 auto;
}

/* Unmark control (manual marks only): a <button> that must LOOK like the
   plain ✓ span — without this reset Pico paints it as a giant solid-blue
   primary button inside the schedule row (260722, owner report). Element-
   qualified to out-rank Pico's button[type=button]-level rules; hover turns
   red as a «снять отметку» affordance. */
button.subs-schedule-row__check--clickable {
  width: auto;
  height: auto;
  min-height: 0;
  padding: 0 2px;
  margin: 0;
  background: transparent;
  border: none;
  color: var(--c-green);
  font-size: inherit;
  line-height: inherit;
  cursor: pointer;
  transition: color var(--transition-fast, 150ms ease-out);
}
button.subs-schedule-row__check--clickable:hover {
  color: var(--c-blue-9);
}

/* 260723 partial payments: amber «частично X из Y» note + amber ✎ trigger */
.subs-schedule-row__partial {
  color: var(--c-amber);
  font-size: 12px;
  margin-right: 4px;
}
button.subs-schedule-row__check--partial {
  color: var(--c-amber);
}

/* Editor footer: «Снять отметку» — red ghost pinned left of Отмена/Сохранить */
.subs-pay-edit-actions .subs-pay-edit-remove {
  margin-right: auto;
  width: auto;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: none;
  color: var(--c-red);
  font-size: 13px;
  padding: 8px 0;
  margin-bottom: 0;
  cursor: pointer;
}
.subs-pay-edit-actions .subs-pay-edit-remove svg {
  width: 14px;
  height: 14px;
}
button.subs-schedule-row__check--clickable:focus:not(:focus-visible) {
  outline: none;
  box-shadow: none;
}
.subs-schedule-row--past {
  color: var(--surface-15);
  opacity: 0.85;
}
.subs-schedule-row--future {
  opacity: 1;
}
/* Next-payment row highlight (260720-vyv) — auto-scrolled into view by
   subscriptions-ui.js on open via the static data-next-payment marker. */
.subs-schedule-row--next {
  background: var(--c-blue-a09);
  box-shadow: inset 2px 0 0 var(--c-blue-5);
  border-radius: 6px;
}
.subs-schedule-row__next-tag {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 8px;
  font-size: 11px;
  color: var(--c-blue-9);
  background: var(--c-blue-a15);
  border-radius: 999px;
}
/* Collapsed rows stay in the DOM (no server round-trip to expand) but are
   hidden until the list carries --expanded (toggled by subscriptions-ui.js). */
.subs-schedule-row--collapsed-hide {
  display: none;
}
.subs-schedule-list--expanded .subs-schedule-row--collapsed-hide {
  display: flex;
}
.subs-schedule-toggle {
  display: inline-flex;
  align-items: center;
  height: 30px;
  padding: 0 14px;
  margin: 10px 0 0;
  background: var(--surface-tile);
  border: none;
  border-radius: 999px;
  color: var(--text-1);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
}
.subs-schedule-toggle:hover {
  background: var(--hairline);
  color: var(--text-5);
}

/* ── Quick 260720-hcj — manual payment marks: shared «Оплатить» inline
   mini-confirm widget (subscription БЛИЖАЙШИЕ card + loan footer) and the
   clickable early ✓ (loan schedule rows). ──────────────────────────────── */

.subs-pay-widget {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
}
.subs-pay-check-anchor:empty {
  display: none;
}
.subs-pay-check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  color: var(--c-green);
  font-size: 13px;
  font-weight: 700;
  line-height: 1;
  background: none;
  border: none;
  padding: 0;
}
button.subs-pay-check--clickable {
  cursor: pointer;
  background: var(--c-green-a14);
}
button.subs-pay-check--clickable:hover {
  background: var(--c-green-a24);
}
.subs-upcoming__card--paid {
  opacity: 0.85;
}

/* First-unpaid БЛИЖАЙШИЕ card highlight (Quick 260720-vyv) — new modifier +
   caption classes, only rendered by the detail fragment (list.html's own
   БЛИЖАЙШИЕ feed uses --soon instead), so no scoping needed for a clash. */
.subs-upcoming__card--next {
  border-color: var(--c-blue-a55-2);
}
.subs-upcoming__caption-next {
  display: block;
  font-size: 11px;
  color: var(--c-blue-9);
  margin-top: 2px;
}

/* ── Quick 260720-odc — footer pay button + inline mini-modal ───────────────
   The pill + inline confirm form (Quick 260720-hcj) moved out of the card
   into a unified detail footer button + a centered top-layer mini-modal. */

/* Footer pay button (Quick 260720-vyv redesign — supersedes the odc
   blue-tinted-ghost look) — now the RIGHTMOST, LAST DOM child (see
   _detail_fragment.html footer reorder), a SOLID blue primary action:
   [Удалить] … [Редактировать][Оплатить]. `.deal-detail-footer__edit` (below)
   carries the only auto-margin, so this button's own margin-left is reset
   to 0 to stay flush against it — a second auto-margin here would split the
   pair with a gap instead of grouping them tight on the right.
   `.deal-detail-footer__pay` is used ONLY by subscriptions/_detail_fragment
   (grep-verified — the deals detail fragment has no pay button), but scoped
   to #subs-detail-body anyway for clarity/consistency with __edit below. */
#subs-detail-body .deal-detail-footer__pay {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 14px;
  border-radius: 11px;
  cursor: pointer;
  margin: 0;
  padding: 9px 16px;
  background: var(--c-blue-5);
  border: 1px solid transparent;
  color: var(--text-2);
  transition: background var(--transition-fast);
}
#subs-detail-body .deal-detail-footer__pay:hover {
  background: var(--c-blue-16);
}

/* Footer edit button (Quick 260720-vyv) — `.deal-detail-footer__edit` is a
   SHARED class also used by deals/_detail_fragment.html (filled #22304d,
   theme.css ~5216); restyling it globally would regress the deals modal.
   Scoped override: ghost treatment per mock + the ONLY auto-margin in the
   footer, pushing [Редактировать][Оплатить] together to the right edge. */
#subs-detail-body .deal-detail-footer__edit {
  border-radius: 11px;
  padding: 9px 16px;
  margin-left: auto;
  background: transparent;
  border: 1px solid var(--wa-16);
  color: var(--text-5);
}
#subs-detail-body .deal-detail-footer__edit:hover {
  background: var(--hairline);
  color: var(--text-2);
}

/* Mini-modal — ~380px, stacks above the open detail via the browser
   top-layer (nested <dialog>.showModal()). Overrides the shared 560px
   dialog.modal-form>article width (same specificity, later in source order
   — the cascade tiebreaker — never a bare dialog.modal-form rule). */
dialog.subs-pay-modal > article {
  width: min(380px, 92vw);
  max-height: 90vh;
  padding: 24px;
  position: relative;
}
dialog.subs-pay-modal [rel="prev"] {
  position: absolute;
  top: 14px;
  right: 16px;
  z-index: 2;
  margin: 0;
}
.subs-pay-modal__title {
  margin: 0 32px 4px 0; /* right margin reserves room for the × */
  font-size: 17px;
  font-weight: 600;
}
.subs-pay-modal__caption {
  margin: 0 0 16px;
  font-size: 13px;
  color: var(--text-1);
}
/* Amount field with a static, muted currency suffix ($ / ₽ / €) pinned inside
   the input's right edge — read-only affix, not part of the value (260720-pzx). */
.subs-pay-modal__amount {
  position: relative;
}
.subs-pay-modal__amount .deal-form-input {
  padding-right: 32px;
}
.subs-pay-modal__ccy {
  position: absolute;
  top: 50%;
  right: 14px;
  transform: translateY(-50%);
  color: var(--text-muted);
  font-size: 14px;
  pointer-events: none;
}
dialog.subs-pay-modal .form-actions {
  justify-content: flex-end;
}
.subs-pay-modal__cancel {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 38px;
  padding: 0 18px;
  border-radius: 10px;
  border: 1px solid var(--wa-12);
  background: none;
  color: var(--text-1);
  font-size: 14px;
  cursor: pointer;
  width: auto;
  flex: 0 0 auto;
}
.subs-pay-modal__cancel:hover {
  color: var(--text-5);
}
.subs-pay-modal__submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 38px;
  padding: 0 20px;
  border-radius: 10px;
  border: none;
  background: var(--c-blue);
  color: var(--text-2);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  width: auto;
  flex: 0 0 auto;
}
.subs-pay-modal__submit:hover {
  background: var(--c-blue-7);
}

/* Subscription add/edit modal × — same top-right corner as the detail +
   mini-modal (Quick 260720-odc). Scoped to `.subs-modal header` only. The
   sticky header (dialog.modal-form>article>header, position:sticky)
   establishes the positioning context; pulling the × out of the flex flow
   removes it from Pico's default margin-left:auto placement. */
.subs-modal header [rel="prev"] {
  position: absolute;
  top: 14px;
  right: 16px;
  z-index: 2;
  margin: 0;
}

/* Loan schedule row «оплачено {paid_on}» sub-line (paid_on != due_date). */
.subs-schedule-row__paid-on {
  display: block;
  font-size: 11px;
  color: var(--text-6);
  margin-top: 2px;
}

/* ═════════════════════════════════════════════════════════════════════════
   MOBILE — slice A (260723): bottom nav replaces the sidebar on phones.
   EVERYTHING here is scoped to @media (max-width: 767px) except the two
   default-hide rules — desktop is untouched by design.
   ═════════════════════════════════════════════════════════════════════════ */

/* Hidden on desktop; the media block below reveals them on phones. */
.mobile-nav { display: none; }

@media (max-width: 767px) {
  /* Off-canvas sidebar + floating hamburger are RETIRED on phones —
     the bottom nav is the only navigation. (The sidebar stays in the DOM:
     the «Тема» sheet item proxies to its #theme-toggle.) */
  .sidebar, .sidebar-toggle { display: none !important; }

  .main-content {
    margin-left: 0 !important;
    padding: 12px 12px calc(72px + env(safe-area-inset-bottom));
  }

  /* ── Bottom tab bar ── */
  .mobile-nav {
    display: flex;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 900;                       /* below dialogs (top layer), above content */
    background: var(--surface-14);
    border-top: 1px solid var(--hairline);
    padding: 6px 4px calc(6px + env(safe-area-inset-bottom));
  }
  .mobile-nav__item {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 3px 0;
    /* <button> resets: Pico width:100%/margins/bg would wreck the row */
    width: auto; margin: 0; border: none; background: none;
    min-height: 0; height: auto;
    color: var(--text-muted);
    text-decoration: none;
    font-size: 10px;
    line-height: 1.2;
    cursor: pointer;
  }
  .mobile-nav__icon { display: inline-flex; }
  .mobile-nav__icon svg { width: 20px; height: 20px; }
  .mobile-nav__item--active { color: var(--c-blue); }
  .mobile-nav__item:focus:not(:focus-visible) { outline: none; box-shadow: none; }

  /* ── «Ещё» bottom sheet ── */
  dialog.mobile-sheet {
    position: fixed;
    inset: auto 0 0 0;
    width: 100%;
    max-width: 100%;
    margin: 0;
    border: none;
    padding: 0;
    background: transparent;
  }
  dialog.mobile-sheet::backdrop { background: rgba(0, 0, 0, .55); }
  /* The dialog spans the viewport (UA :modal inset) — flex pins the card
     to the bottom edge, giving the bottom-sheet look. */
  dialog.mobile-sheet[open] {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    height: 100%;
    max-height: 100%;
  }
  dialog.mobile-sheet > article {
    margin: 0;
    background: var(--surface-14);
    border: 1px solid var(--hairline);
    border-bottom: none;
    border-radius: 16px 16px 0 0;
    padding: 8px 16px calc(14px + env(safe-area-inset-bottom));
  }
  .mobile-sheet__grab {
    width: 36px; height: 4px;
    border-radius: 999px;
    background: var(--wa-14);
    margin: 4px auto 10px;
  }
  .mobile-sheet__item {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    min-height: 48px; height: auto;
    margin: 0; padding: 0 4px;
    border: none;
    border-bottom: 0.5px solid var(--hairline);
    border-radius: 0;
    background: none;
    color: var(--text-primary);
    font-size: 14px;
    text-align: left;
    cursor: pointer;
  }
  .mobile-sheet__logout { margin: 0; }
  .mobile-sheet__logout .mobile-sheet__item { border-bottom: none; }
  .mobile-sheet__item--danger { color: var(--c-red); }
  .mobile-sheet__icon { display: inline-flex; color: var(--text-muted); }
  .mobile-sheet__item--danger .mobile-sheet__icon { color: var(--c-red); }
  .mobile-sheet__item:focus:not(:focus-visible) { outline: none; box-shadow: none; }

  /* ── FX strip: one scrollable row, never wraps or clips into the header ── */
  .fx-strip {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .fx-strip::-webkit-scrollbar { display: none; }

  /* ── Page headers: allow wrapping instead of clipping off-screen ── */
  .settings-page-header, .subs-page-header { flex-wrap: wrap; row-gap: 8px; }

  /* ── Deals top bar: wrap instead of pushing «Добавить» off-screen ── */
  .header-actions { flex-wrap: wrap; row-gap: 8px; }

  /* ── Chip/filter rows scroll horizontally instead of clipping ── */
  .status-chips, .subs-filter-tabs, .chip-group {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    max-width: 100%;
  }
  .status-chips::-webkit-scrollbar,
  .subs-filter-tabs::-webkit-scrollbar,
  .chip-group::-webkit-scrollbar { display: none; }
}

/* ── Mobile deal cards (slice B, 260723) — table on desktop, cards on phones ── */
.deals-cards-mobile { display: none; }

@media (max-width: 767px) {
  .deals-card { display: none; }           /* the table wrapper card */
  .deals-cards-mobile { display: block; }

  .dcard {
    background: var(--surface-14);
    border: 0.5px solid var(--hairline);
    border-radius: 10px;
    padding: 9px 12px;
    margin-bottom: 6px;
    cursor: pointer;
  }
  .dcard__top {
    display: flex;
    align-items: center;
    gap: 7px;
    min-width: 0;
  }
  .dcard__id { color: var(--text-muted); font-size: 12px; flex: none; }
  .dcard__subject {
    font-size: 13px;
    font-weight: 500;
    flex: 1 1 auto;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .dcard__status {
    flex: none;
    font-size: 10.5px;
    padding: 2px 8px;
    border-radius: 999px;
    white-space: nowrap;
  }
  .dcard__bottom {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 5px;
    font-size: 11.5px;
    color: var(--text-muted);
    white-space: nowrap;
    min-width: 0;
  }
  .dcard__flow { overflow: hidden; text-overflow: ellipsis; }
  .dcard__margin {
    margin-left: auto;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--c-green);
  }
  .dcard__margin--neg { color: var(--c-red); }
}

/* ── Mobile Главная (slice C, 260723) — summary first, one-month calendar ── */
@media (max-width: 767px) {
  /* Block order per the approved mock: FX → «Сегодня» + плитки → календарь.
     Flex column on the fragment root lets CSS reorder the server markup. */
  #home-body { display: flex; flex-direction: column; }
  #home-body > .fx-strip { order: 0; }
  #home-body > .home-center-row { order: 1; }
  #home-body > .home-calendar-block { order: 2; }

  /* «Сегодня» + плитки: single column (grid columns collapse) */
  #home-body .home-center-row {
    display: flex;
    flex-direction: column;
    gap: 12px;
  }

  /* Календарь + агенда: stack; calendar shows ONE month (the second is a
     desktop luxury — the «1/2 месяца» setting still governs desktop). */
  .home-calendar-block { flex-direction: column; }
  .home-calendar__month:nth-child(n+2) { display: none; }

  /* Drop the ISO week-number gutter and let 7 day columns fill the width. */
  .home-calendar__week-no-header, .home-calendar__week-no { display: none; }
  .home-calendar__grid {
    grid-template-columns: repeat(7, 1fr);
    width: 100%;
  }
  .home-calendar, .home-agenda { width: 100%; }
}

/* ── Mobile modals (slice D, 260723): detail + form dialogs go full-screen ──
   Mini dialogs are EXEMPT: the pay/editor mini-modals (.subs-pay-modal) stay
   centered, the «Ещё» sheet keeps its bottom-sheet styling. */
@media (max-width: 767px) {
  dialog.modal-detail,
  dialog.modal-form:not(.subs-pay-modal) {
    width: 100vw;
    max-width: 100vw;
    height: 100dvh;
    max-height: 100dvh;
    margin: 0;
    padding: 0;
    inset: 0;
    border: none;
    border-radius: 0;
  }
  dialog.modal-detail > article,
  dialog.modal-form:not(.subs-pay-modal) > article {
    width: 100%;
    max-width: 100%;
    height: 100dvh;
    max-height: 100dvh;
    margin: 0;
    border-radius: 0;
    box-shadow: none;
    animation: none;
  }
  dialog.modal-detail > article { padding: 0 16px 0; }
  dialog.modal-form:not(.subs-pay-modal) > article { padding: 0 16px 20px; }

  /* Detail-modal internals breathe at 16px side padding: the sticky header
     and the flat footer both span edge-to-edge via their own negative
     margins tuned for 32/24px — retune to 16px. */
  dialog.modal-form > article > header { margin-left: -16px; margin-right: -16px; padding-left: 16px; padding-right: 16px; }

  /* Detail tiles: 2×2 instead of a squeezed 4-across row. */
  .deal-detail-tiles, .subs-detail-tiles { grid-template-columns: 1fr 1fr; }

  /* 2-col info grids collapse to one column inside modals. */
  .deal-detail-grid, .deal-form-row-2col { grid-template-columns: 1fr; }
}

/* ── Mobile Платежи (slice E, 260723) ── */
@media (max-width: 767px) {
  /* 375px can't fit name + category chip + ≈conversion + day mark + controls:
     the flexible name collapsed to zero. The NAME wins — the chip and the
     ≈equivalent are desktop luxuries (both live in the detail anyway). */
  .subs-row--compact .subs-cat-chip,
  .subs-row--compact .subs-row__fx-equiv { display: none; }
  .subs-row__name { min-width: 60px; }
}

/* ── Mobile Аналитика (slice E, 260723): the topbar (title + period
   segmented control + toggles, ~660px in a row) forced the layout viewport
   to 725px and the whole page zoomed out. Wrap it instead. ── */
@media (max-width: 767px) {
  .analytics-topbar, .analytics-topbar__left {
    flex-wrap: wrap;
    row-gap: 8px;
    max-width: 100%;
  }
}

/* ── Mobile hotfix F (260723, owner phone feedback) ── */
@media (max-width: 767px) {
  /* Никакого горизонтального листания страницы — жёсткая страховка. */
  html, body, .main-content { overflow-x: hidden; }

  /* Сделки: шапка в ОДНУ строку — «Настроить виджеты» становится
     иконкой (font-size:0 прячет текстовый узел, svg восстанавливается),
     «Добавить сделку» компактнее. */
  .header-actions { flex-wrap: nowrap; gap: 8px; }
  .widget-edit-btn { font-size: 0; gap: 0; padding: 10px 12px; flex: none; }
  .widget-edit-btn svg { width: 18px; height: 18px; }
  .header-actions__right { flex: none; margin-left: auto; }

  /* План/Факт: график ВСЕГДА последним, на всю ширину, со своим
     внутренним скроллом — никогда не зажимается сбоку от плиток. */
  .plan-fact-body { flex-wrap: wrap; }
  .plan-fact-gauge-col { flex: 1 1 auto; display: flex; justify-content: center; }
  .plan-fact-tiles { flex: 1 1 100%; }
  .plan-fact-chart {
    order: 99;
    flex: 1 1 100%;
    min-width: 0;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .plan-fact-chart::-webkit-scrollbar { display: none; }

  /* Аналитика: селектор месяца и правая группа не тянут страницу вбок. */
  .analytics-topbar > *, .analytics-topbar__left > * { max-width: 100%; min-width: 0; }
}

/* ── Mobile hotfix G (260723, phone round 2) ── */
@media (max-width: 767px) {
  /* Подписки: чип «осталось N оплат» тоже прячем в компакт-строке — он
     наезжал на сумму (инфа живёт в деталке, как и категория/конверсия). */
  .subs-row--compact .subs-term-badge { display: none; }

  /* Аналитика: чипы периода своим рядом, ниже ОДНА строка
     [‹ Июль 2026 › | ⚙ | ↻]. Grid + display:contents расплющивает
     .analytics-topbar__left, чтобы refresh (прямой ребёнок топбара)
     встал в тот же ряд, что и кнопка настроек из __left. */
  .analytics-topbar {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    gap: 8px;
    align-items: stretch;
  }
  .analytics-topbar__left { display: contents; }
  .analytics-topbar .segmented-period { grid-column: 1 / -1; }
  .analytics-topbar .period-nav { grid-column: 1; min-width: 0; }
  .analytics-topbar .widget-edit-btn { grid-column: 2; margin: 0; }
  .analytics-topbar > .refresh-btn { grid-column: 3; margin: 0; }
}

/* ── Mobile Настройки (260723): full-screen + polished chip nav ── */
@media (max-width: 767px) {
  dialog.settings-modal {
    width: 100vw;
    max-width: 100vw;
    height: 100dvh;
    max-height: 100dvh;
    margin: 0;
    padding: 0;
    inset: 0;
    border: none;
  }
  dialog.settings-modal > article {
    width: 100vw;
    height: 100dvh;
    max-height: 100dvh;
    margin: 0;
    border-radius: 0;
    border: none;
    box-shadow: none;
  }
  /* Existing ≤760px strip nav: hide its scrollbar, keep row height tight,
     leave room for the pinned ×. */
  .settings-modal .settings-nav {
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    padding: 12px 48px 10px 14px;
  }
  .settings-modal .settings-nav::-webkit-scrollbar { display: none; }
  /* Nav items keep their VERTICAL-sidebar sizing in row mode and blow up
     into giant tiles — pin them down to compact pill chips. */
  .settings-modal .settings-nav { align-items: center; max-height: 58px; overflow-y: hidden; }
  .settings-modal .settings-shell { grid-template-rows: auto 1fr; }
  .settings-modal .settings-nav__item {
    width: auto;
    height: 34px;
    min-height: 34px;
    margin: 0;
    padding: 0 12px;
    font-size: 12.5px;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
  }
  .settings-modal .settings-nav__icon svg { width: 14px; height: 14px; }
  .settings-modal .settings-content {
    padding-bottom: calc(20px + env(safe-area-inset-bottom));
  }
}

/* ═══════════════════════════════════════════════════════════════════
   260723: Passkeys — Touch ID / Face ID (login button + settings card)
   ═══════════════════════════════════════════════════════════════════ */

.passkeys-list {
  list-style: none;
  margin: 0 0 12px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.passkeys-item {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding: 10px 12px;
  border: 1px solid var(--pico-muted-border-color);
  border-radius: var(--radius-button, 12px);
  list-style: none;
}
.passkeys-item__icon { display: inline-flex; color: var(--pico-muted-color); }
.passkeys-item__label { font-size: 14px; font-weight: 600; }
.passkeys-item__date {
  margin-left: auto;
  font-size: 12.5px;
  color: var(--pico-muted-color);
  white-space: nowrap;
}
.passkeys-item__delete {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin: 0; /* Pico default margin-bottom guard */
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 8px;
  color: var(--pico-muted-color);
  cursor: pointer;
}
.passkeys-item__delete:hover {
  color: var(--pico-del-color, var(--c-red-2));
  background: color-mix(in srgb, var(--pico-del-color, var(--c-red-2)) 10%, transparent);
}
.passkeys-item__delete:focus:not(:focus-visible) { outline: none; box-shadow: none; }

/* ═══════════════════════════════════════════════════════════════════
   260723: 2FA-карточка в Настройки → Аккаунт
   ═══════════════════════════════════════════════════════════════════ */

.totp-setup {
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 0 0 12px;
}
.totp-setup__qr {
  flex: none;
  border-radius: 12px;
  background: #fff; /* QR обязан быть тёмным-на-светлом для сканера */
  padding: 8px;
}
.totp-setup__secret {
  margin: 0;
  font-size: 13px;
  color: var(--pico-muted-color);
  line-height: 1.5;
  overflow-wrap: anywhere;
}
.totp-setup__secret code {
  font-size: 12.5px;
  letter-spacing: .06em;
}

.totp-inline-form {
  display: flex;
  gap: 10px;
  align-items: center;
}
.totp-inline-form .totp-code-field {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0; /* Pico default margin-bottom guard */
}
.totp-inline-form .deal-submit-pill { flex: none; margin: 0; }
.totp-inline-form + .totp-inline-form { margin-top: 10px; }

.totp-danger-pill {
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--pico-del-color, #FF453A) 45%, transparent);
  color: var(--pico-del-color, #FF453A);
}
.totp-danger-pill:hover {
  background: color-mix(in srgb, var(--pico-del-color, #FF453A) 12%, transparent);
}

.totp-recovery-list {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin: 0 0 14px;
  padding: 0;
}
.totp-recovery-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 14px;
  letter-spacing: .08em;
  text-align: center;
  padding: 8px 10px;
  border: 1px dashed var(--pico-muted-border-color);
  border-radius: 10px;
  list-style: none;
  margin: 0;
}

@media (max-width: 480px) {
  .totp-setup { flex-direction: column; align-items: flex-start; }
  .totp-inline-form { flex-wrap: wrap; }
}

/* ═══════════════════════════════════════════════════════════════════
   260723: Инвайт-ссылки в карточке «Пользователи»
   ═══════════════════════════════════════════════════════════════════ */

.invites-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0 0 12px;
}
.invite-row {
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: 11px 12px;
  border: 1px solid var(--pico-muted-border-color);
  border-radius: var(--radius-button, 12px);
}
.invite-row--used, .invite-row--expired { opacity: 0.55; }

/* строка 1: подпись + пилюля статуса + мелкая корзина справа */
.invite-row__head {
  display: flex;
  align-items: center;
  gap: 8px;
}
.invite-row__label {
  min-width: 0;
  font-size: 13.5px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.invite-row__status {
  flex: none;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .02em;
  padding: 2px 8px;
  border-radius: var(--radius-pill, 999px);
  white-space: nowrap;
}
.invite-row__status--active {
  color: var(--status-completed, #30D158);
  background: color-mix(in srgb, var(--status-completed, #30D158) 15%, transparent);
}
.invite-row__status--used {
  color: var(--pico-muted-color);
  background: color-mix(in srgb, var(--pico-muted-color, #98989D) 15%, transparent);
}
.invite-row__status--expired {
  color: var(--status-awaiting_payment, #FFB340);
  background: color-mix(in srgb, var(--status-awaiting_payment, #FFB340) 15%, transparent);
}
.invite-row__revoke {
  flex: none;
  margin: 0 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 8px;
  color: var(--pico-muted-color);
  cursor: pointer;
}
.invite-row__revoke svg { width: 15px; height: 15px; }
.invite-row__revoke:hover {
  color: var(--pico-del-color, #FF453A);
  background: color-mix(in srgb, var(--pico-del-color, #FF453A) 12%, transparent);
}

/* строка 2: ссылка + кнопка копирования */
.invite-row__linkrow {
  display: flex;
  gap: 6px;
  align-items: center;
  min-width: 0;
}
.invite-row__url {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  padding: 8px 10px;
  font-size: 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--pico-color);
  background: rgba(10, 15, 26, .5);
  border: 1px solid var(--pico-muted-border-color);
  border-radius: 8px;
}
.invite-row__copy {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  margin: 0;
  padding: 0;
  background: transparent;
  border: 1px solid var(--pico-muted-border-color);
  border-radius: 8px;
  color: var(--pico-muted-color);
  cursor: pointer;
}
.invite-row__copy svg { width: 15px; height: 15px; }
.invite-row__copy:hover { color: var(--accent); border-color: var(--accent); }
.invite-row__copy:focus:not(:focus-visible),
.invite-row__revoke:focus:not(:focus-visible) { outline: none; box-shadow: none; }

.invites-create { display: flex; gap: 10px; align-items: center; }
.invites-create .deal-form-input { flex: 1 1 auto; min-width: 0; margin: 0; }
.invites-create .deal-submit-pill { flex: none; margin: 0; }

@media (max-width: 480px) {
  .invites-create { flex-wrap: wrap; }
}

/* =============================================================================
   РАСХОДЫ (/expenses) — Slice 1: основные цифры + донат + богатая легенда + список
   Палитра «Вариант 2 · Приглушённый». Цвета категорий — как CSS-переменные,
   чтобы SVG-stroke брал var() и не хардкодить hex по месту.
   ============================================================================= */
:root {
  --cat-1: #70a38b;   /* пыльно-синий */
  --cat-2: #6fa58c;   /* шалфей       */
  --cat-3: #909d97;   /* сланец       */
  --cat-4: #c0895c;   /* терракот     */
  --cat-5: #b0925a;   /* золото       */
  --cat-6: #a57b9a;   /* мокко        */
  --cat-7: #7a9e9a;   /* бирюза       */
  --cat-muted: #72817a;   /* «Без категории» / «Прочее» */
  --exp-up:   #cf6b5e;    /* трата выросла — мягкий красный (для расхода это «хуже») */
  --exp-down: #4fb477;    /* трата упала  — мягкий зелёный (сэкономил) */
}

.exp-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.exp-head__title { display: flex; align-items: center; gap: 10px; font-size: 22px; font-weight: 700; color: var(--text-primary); }
.exp-head__title svg { color: var(--text-muted); }

.exp-top { display: grid; grid-template-columns: 1fr; gap: 14px; margin-bottom: 4px; }
.exp-nums { display: flex; flex-direction: column; gap: 12px; }
.exp-period { display: flex; align-items: center; gap: 12px; font-size: 15px; font-weight: 600; color: var(--text-primary); }
.exp-nums__big { font-size: 30px; font-weight: 800; color: var(--text-primary); letter-spacing: -.02em; }
.exp-nums__row { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.exp-trend { font-size: 13px; font-weight: 600; padding: 3px 9px; border-radius: var(--radius-pill); }
.exp-trend--down { color: var(--exp-down); background: color-mix(in srgb, var(--exp-down) 15%, transparent); }
.exp-trend--up   { color: var(--exp-up);   background: color-mix(in srgb, var(--exp-up) 15%, transparent); }
.exp-trend--flat { color: var(--text-muted); background: var(--surface-row); }
.exp-day { font-size: 13px; color: var(--text-muted); }
.exp-split { display: flex; gap: 18px; flex-wrap: wrap; font-size: 12.5px; color: var(--text-muted); }
.exp-split b { color: var(--text-primary); font-weight: 700; }
.exp-spark { display: flex; align-items: flex-end; gap: 5px; height: 30px; }
.exp-spark__b { width: 8px; border-radius: 3px 3px 0 0; background: color-mix(in srgb, var(--text-muted) 26%, transparent); }
.exp-spark__b--cur { background: var(--text-muted); }

.exp-section-title { font-size: 12px; letter-spacing: .09em; text-transform: uppercase; color: var(--text-muted); margin: 26px 2px 10px; font-weight: 700; }

/* донат + богатая легенда */
.exp-donut-card { display: grid; grid-template-columns: 220px 1fr; gap: 30px; align-items: center; }
.donut-wrap { position: relative; width: 200px; height: 200px; margin: 0 auto; }
.donut-svg { width: 200px; height: 200px; display: block; }
.donut-seg { fill: none; stroke-width: 20; cursor: pointer; transition: stroke-width .12s, opacity .12s; }
.donut-center { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; pointer-events: none; }
.donut-center__val { font-size: 24px; font-weight: 800; color: var(--text-primary); }
.donut-center__cap { font-size: 11.5px; color: var(--text-muted); }

.exp-legend { display: flex; flex-direction: column; }
.exp-leg { display: grid; grid-template-columns: 14px 1fr 62px 70px 56px; align-items: center; gap: 10px; padding: 8px 6px; border-bottom: 1px solid color-mix(in srgb, var(--pico-muted-border-color) 55%, transparent); cursor: pointer; border-radius: 8px; }
.exp-leg:last-child { border-bottom: none; }
.exp-leg.is-hi { background: color-mix(in srgb, var(--text-muted) 10%, transparent); }
.exp-leg__dot { width: 11px; height: 11px; border-radius: 3px; margin-left: 4px; }
.exp-leg__name { font-size: 14px; color: var(--text-primary); }
.exp-leg__pct { font-size: 12.5px; color: var(--text-muted); text-align: right; }
.exp-leg__val { font-size: 14px; font-weight: 600; color: var(--text-primary); text-align: right; }
.exp-leg__chg { font-size: 11.5px; font-weight: 600; text-align: right; color: var(--text-muted); }
.exp-leg__chg--up { color: var(--exp-up); }
.exp-leg__chg--down { color: var(--exp-down); }

/* список трат */
.exp-cat-chip { font-size: 12px; padding: 2px 9px; border-radius: var(--radius-pill); background: color-mix(in srgb, var(--text-muted) 12%, transparent); color: var(--text-primary); display: inline-flex; align-items: center; gap: 6px; }
.exp-cat-chip i { width: 8px; height: 8px; border-radius: 2px; }
.exp-src { font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: var(--radius-pill); }
.exp-src--once  { color: var(--text-muted); background: var(--surface-row); }
.exp-src--recur { color: var(--cat-1); background: color-mix(in srgb, var(--cat-1) 16%, transparent); }

.exp-empty { text-align: center; padding: 48px 20px; color: var(--text-muted); }
.exp-empty__big { font-size: 16px; color: var(--text-primary); margin-bottom: 6px; }

@media (max-width: 720px) {
  .exp-donut-card { grid-template-columns: 1fr; gap: 16px; }
  .exp-leg { grid-template-columns: 14px 1fr 48px 62px 50px; gap: 6px; }
}

.exp-leg[hx-get] { cursor: pointer; }
.exp-leg.is-sel { box-shadow: inset 2px 0 0 var(--accent); }

/* drill-down по категории */
.drill { display: grid; grid-template-columns: 300px 1fr; gap: 26px; }
.drill__head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.drill__dot { width: 12px; height: 12px; border-radius: 3px; background: var(--accent); }
.drill__name { font-size: 16px; font-weight: 700; color: var(--text-primary); }
.drill__sum { margin-left: auto; font-size: 16px; font-weight: 700; color: var(--text-primary); }
.drill__trend { display: flex; align-items: flex-end; gap: 8px; height: 90px; padding: 6px 2px; margin-bottom: 22px; }
.drill__bar { flex: 1; border-radius: 4px 4px 0 0; background: color-mix(in srgb, var(--cat-1) 35%, transparent); position: relative; min-height: 3px; }
.drill__bar--cur { background: var(--cat-1); }
.drill__bar span { position: absolute; bottom: -18px; left: 0; right: 0; text-align: center; font-size: 10px; color: var(--text-muted); }
.drill__ops { min-width: 0; }
.drill__op { display: grid; grid-template-columns: 60px 1fr auto; gap: 12px; padding: 8px 0; border-bottom: 1px solid color-mix(in srgb, var(--pico-muted-border-color) 50%, transparent); font-size: 13.5px; color: var(--text-primary); }
.drill__op:last-child { border-bottom: none; }
.drill__op time { color: var(--text-muted); }
.drill__op b { font-weight: 600; color: var(--text-primary); text-align: right; }
.drill__empty { color: var(--text-muted); padding: 12px 0; }

@media (max-width: 720px) {
  .drill { grid-template-columns: 1fr; gap: 16px; }
}

/* ── Банк/казна — главная страница Froks (Task 7) ─────────────────────────── */

.bank-page {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.hero {
  position: relative;
  text-align: left;
  padding: 30px 34px 26px;
  max-width: none;
  margin: 0 0 16px;
  border-radius: 20px;
  background: linear-gradient(140deg, #18271e 0%, #101814 55%, #0f1713 100%);
  border: 1px solid rgba(124, 192, 132, 0.16);
  overflow: hidden;
}
.hero::after {
  content: "";
  position: absolute;
  top: -90px;
  right: -60px;
  width: 340px;
  height: 280px;
  background: radial-gradient(closest-side, rgba(92, 180, 115, 0.16), transparent 70%);
  pointer-events: none;
}

.bank-refresh-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  position: absolute;
  top: 20px;
  right: 20px;
  height: 34px;
  padding: 0 14px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-primary);
  border: 1px solid var(--wa-08);
  border-radius: 10px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  line-height: 1;
  transition: background var(--transition-fast), opacity var(--transition-fast);
}
.bank-refresh-btn:hover { background: rgba(255, 255, 255, 0.1); }
.bank-refresh-btn svg { display: block; flex-shrink: 0; color: var(--accent); }

/* Блокировка повторного клика на время запроса — тот же канонический приём,
   что у .refresh-btn.htmx-request выше: без hx-indicator htmx сам добавляет
   класс htmx-request элементу-триггеру (см. app/static/vendor/htmx-2.0.3.min.js,
   функция addRequestClass), поэтому CSS-правила достаточно. Переиспользует
   @keyframes refresh-spin, уже определённый там же. */
.bank-refresh-btn.htmx-request {
  pointer-events: none;
  opacity: .6;
}
.bank-refresh-btn.htmx-request svg {
  animation: refresh-spin 0.8s linear infinite;
}

.hero__label {
  margin: 0 0 4px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.bal {
  margin: 0;
  font-size: 48px;
  font-weight: 700;
  color: var(--text-primary);
  line-height: 1.1;
}

.bal--unknown {
  font-size: 22px;
  font-weight: 600;
  color: var(--text-muted);
}

.hero__rub {
  margin: 4px 0 0;
  font-size: 15px;
  color: var(--text-muted);
}

/* Предупреждение о неизвестных курсах (поправки к брифу, §2). Намеренно
   заметное и сразу под итогом: без курса суммы посчитаны по фолбэку 1:1 и
   выглядят правдоподобно, будучи неверными. */
.rates-warning {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 14px 0 0;
  padding: 10px 14px;
  max-width: 460px;
  text-align: left;
  border: 1px solid var(--c-amber-a45);
  border-radius: var(--radius-card);
  background: var(--c-amber-a08);
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--text-primary);
}
.rates-warning__icon { display: flex; flex-shrink: 0; color: var(--c-amber); }
.rates-warning__icon svg { display: block; }
.rates-warning a { color: var(--c-amber); white-space: nowrap; }

.deltas {
  display: flex;
  justify-content: flex-start;
  flex-wrap: wrap;
  gap: 10px;
  margin: 14px 0 0;
}

.delta {
  font-size: 13px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--surface-tile);
}
.delta--up { color: var(--c-green); }
.delta--down { color: var(--c-red); }
.delta--na { color: var(--text-muted); }

/* Оговорки к ROI (поправки к брифу, §3): показатель считает зависшие деньги
   своими и дрейфует вслед за курсами — без подписи цифра выглядит точнее,
   чем она есть. */
.roi-note {
  margin: 10px 0 0;
  max-width: 560px;
  font-size: 11.5px;
  line-height: 1.4;
  color: var(--text-muted);
}

.stuck {
  display: inline-flex;
  margin: 14px 0 0;
  padding: 6px 14px;
  border-radius: 999px;
  background: var(--c-red-a08);
  color: var(--c-red);
  font-size: 13px;
  font-weight: 600;
}

/* ── Матрица по валютам ────────────────────────────────────────────────────── */
.mx-wrap {
  overflow-x: auto;
  background: var(--surface-card);
  border: 1px solid var(--wa-07);
  border-radius: var(--radius-card);
  padding: 18px 22px;
  margin-bottom: 16px;
}

.mx {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
}

.mx th {
  text-align: right;
  padding: 8px 12px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  border-bottom: 1px solid var(--wa-08);
  white-space: nowrap;
}
.mx th:first-child, .mx td:first-child { text-align: left; }

.mx td {
  padding: 8px 12px;
  text-align: right;
  color: var(--text-primary);
  border-bottom: 1px solid var(--wa-07);
  white-space: nowrap;
}

.mx__ccy { font-weight: 600; }
.mx__wallets { color: var(--c-blue); }
.mx__accounts { color: var(--c-green); }
.mx__stuck { color: var(--c-red); }
.mx__transit { color: var(--c-amber); }
.mx__empty { text-align: center; color: var(--text-muted); }

.mx tfoot td {
  border-bottom: none;
  font-weight: 600;
  color: var(--text-primary);
}

/* ── Курсы валют / История баланса ───────────────────────────────────────── */
.bank-boxes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
@media (max-width: 720px) {
  .bank-boxes { grid-template-columns: 1fr; }
}

.box {
  background: var(--surface-card);
  border: 1px solid var(--wa-08);
  border-radius: var(--radius-card);
  padding: 16px 18px;
}

.box__title {
  margin: 0 0 10px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
}

.box__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
/* Pico задаёт list-style-type на самом li, и это перебивает none у списка:
   у строк маркер не виден только потому, что они flex, а у .box__empty
   (обычный list-item) вылезает квадрат. Гасим на элементах, а не на ul. */
.box__list li { list-style: none; }

.box__row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
}

.box__ccy { font-weight: 600; color: var(--text-primary); min-width: 44px; }
.box__rate { color: var(--text-primary); }
.box__source {
  margin-left: auto;
  font-size: 11px;
  color: var(--text-muted);
}

.box__date { color: var(--text-muted); min-width: 96px; }
.box__value { font-weight: 600; color: var(--text-primary); }
.box__delta { margin-left: auto; font-size: 12px; }
.box__delta--up { color: var(--c-green); }
.box__delta--down { color: var(--c-red); }
.box__empty { color: var(--text-muted); padding: 4px 0; }

/* ── Дропы — список (Task 8a, часть 2) ─────────────────────────────────────
   Первая CRUD-страница проекта («Банк» выше — не список). Разметка и классы
   здесь — образец для следующих списков (аккаунты, платёжки, настройки):
   .drops-table-wrap/.drops-table — по образцу .mx-wrap/.mx у «Банка»;
   .drops-toggle-archived переиспользует уже существующий .settings-switch
   (см. ниже #settings-switch в этом файле) вместо новой реализации тумблера.
   ────────────────────────────────────────────────────────────────────────── */

.drops-page {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.drops-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

/* Счётчик + переключатель архива группируются слева, кнопка «Добавить» —
   справа (Task 8a, часть 3): без обёртки justify-content:space-between на
   ТРЁХ прямых потомках растащило бы их в 0/50/100%, разорвав счётчик и
   переключатель на разные концы строки. */
.drops-toolbar__meta {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

.drops-toolbar__count {
  margin: 0;
  font-size: 13px;
  color: var(--text-muted);
}

.drops-toggle-archived {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Текст ТЕПЕРЬ внутри <label class="settings-switch"> (M-8 ревью Task 8a:
   раньше был соседом — клик по нему не переключал чекбокс, у поля не было
   ни id/for, ни своей подписи). margin-left вместо gap на родителе — gap
   .drops-toggle-archived по-прежнему разделяет <label> и соседний
   .drops-count-archived-note (карточка почт), но track и текст теперь оба
   внутри самого .settings-switch, где gap не задан. */
.drops-toggle-archived__label {
  margin-left: 8px;
  font-size: 13px;
  color: var(--text-muted);
}

@media (max-width: 640px) {
  .drops-toolbar { flex-direction: column; align-items: flex-start; }
}

/* Первичное действие тулбара («Добавить дроп» / «Добавить почту» на карточке)
   — залитая акцентом пилюля, в отличие от нейтральных .drops-action-btn
   строк таблицы (та же визуальная иерархия, что .bank-refresh-btn у «Банка»:
   заливка = единственное главное действие поверхности, обводка = действие
   над конкретной строкой). */
.drops-add-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 16px;
  border: none;
  border-radius: var(--radius-pill);
  background: var(--c-blue);
  color: var(--text-2);
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  transition: opacity var(--transition-fast);
  flex-shrink: 0;
}
.drops-add-btn:hover { opacity: .88; }
.drops-add-btn svg { display: block; flex-shrink: 0; }
.drops-add-btn:focus:not(:focus-visible) { outline: none; }
.drops-add-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--c-blue-a35);
}

/* ── Таблица — обёртка со скроллом, как .mx-wrap: узкий экран не ломает вёрстку. */
.drops-table-wrap {
  overflow-x: auto;
}

.drops-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
}

.drops-table th {
  padding: 8px 12px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  border-bottom: 1px solid var(--wa-08);
  white-space: nowrap;
}
/* Выравнивание по классу (review I-5, task-8-review-fixes-a2), не по номеру
   колонки: th:nth-child(3)/(4)/(5) молча уехал бы, вставь следующая задача
   новую колонку между «Телефон» и «Почты» — ячейки ЭТИХ ЖЕ колонок уже
   выравниваются по классу (.drops-row__emails/__accounts/__wallets), а не
   по позиции. .col-right — общий класс c .acc-table (тот же язык для обеих
   таблиц, задел на будущую таблицу платёжек Task 11). */
.drops-table th.col-right {
  text-align: right;
}

.drops-table td {
  padding: 10px 12px;
  color: var(--text-primary);
  border-bottom: 1px solid var(--wa-07);
  white-space: nowrap;
}

.drops-row:hover { background: var(--surface-row); }

/* Архивная строка визуально отличима: приглушена целиком И несёт текстовый
   бейдж (drops-badge--archived) — одной приглушённости мало (M-3-класс
   риска: тонкое отличие легко не заметить на живой странице). */
.drops-row--archived { opacity: 0.6; }

/* Имя дропа ведёт на карточку. Без подчёркивания ссылка неотличима от
   обычного текста: цвет тот же, что у соседних ячеек, и узнать о переходе
   можно только случайно наведя курсор. Приглушённое подчёркивание видно в
   покое, при наведении становится полным и синим. */
.drops-row__name a {
  color: var(--text-primary);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: var(--c-blue-a35);
  text-underline-offset: 3px;
  border-radius: 4px;
}
.drops-row__name a:hover { color: var(--c-blue); text-decoration-color: currentColor; }
.drops-row__name a:focus:not(:focus-visible) { outline: none; }
.drops-row__name a:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--c-blue-a35);
}

.drops-badge {
  display: inline-block;
  margin-left: 8px;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  font-size: 11px;
  font-weight: 500;
  background: var(--surface-row);
  color: var(--text-muted);
}

.drops-row__emails, .drops-row__accounts, .drops-row__wallets {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
/* Ноль — приглушённым цветом (семантика: где у дропа реально ЕСТЬ данные),
   не отдельная колонка, не жирный шрифт — тот же язык, что is-active/is-sel
   у других state-модификаторов в этом файле. */
.drops-table td.is-zero { color: var(--text-muted); }

/* Приписка «в архиве» у числа (review Task 8a, I-2) — общая для ячейки
   «Почты» списка (drops/_list_body.html: «1 (1 в архиве)») и подписи
   тумблера архива на карточке (drops/_card_emails.html: «ещё 1 в архиве»).
   Мельче и приглушённее самого числа НАРОЧНО — приписка не должна читаться
   как второе число той же природы, только как аннотация к уже показанному. */
.drops-count-archived-note {
  font-size: 11px;
  color: var(--text-muted);
  font-weight: 400;
}

/* Раскладка кнопок живёт на внутренней обёртке, а НЕ на самой ячейке:
   display:flex на <td> выбивает ячейку из табличной раскладки, она перестаёт
   тянуться до высоты строки, и её нижняя граница рисуется выше, чем у
   соседей. На списке дропов это незаметно (все ячейки одной высоты), а на
   карточке почт строка с паролем выше — и линия под строкой шла в два
   уровня. */
.drops-row__actions {
  vertical-align: middle;
}
.drops-row__actions-inner {
  display: flex;
  align-items: center;
  gap: 8px;
}

.drops-action-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 28px;
  padding: 0 12px;
  border: 1px solid var(--wa-08);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-primary);
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  transition: background var(--transition-fast), border-color var(--transition-fast),
    color var(--transition-fast);
}
.drops-action-btn svg { display: block; flex-shrink: 0; }
.drops-action-btn:focus:not(:focus-visible) { outline: none; }
.drops-action-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--c-blue-a35);
}

.drops-action-btn--archive:hover,
.drops-action-btn--edit:hover,
.drops-action-btn--unarchive:hover {
  background: var(--surface-row);
  border-color: color-mix(in srgb, var(--c-blue) 35%, transparent);
  color: var(--c-blue);
}

.drops-action-btn--delete {
  color: var(--c-red);
  border-color: color-mix(in srgb, var(--c-red) 35%, transparent);
}
.drops-action-btn--delete:hover {
  background: var(--c-red-a08);
}

/* ── Отказ удаления по связям — понятная причина под строкой, не тост
   (бриф: «отказ → сообщение в интерфейсе, без тоста»). Амбер — предупреждение,
   не ошибка: дроп цел, ссылки не тронуты, это ожидаемый отказ. ─────────────── */
.drops-row__error-row td {
  border-bottom: 1px solid var(--wa-07);
}
/* Специфичность .drops-table td (0,1,1) перебивала бы голый .drops-row__error
   (0,1,0) — цвет молча откатывался на --text-primary при живой проверке
   страницы (текст оставался читаемым, но переставал читаться как
   предупреждение). .drops-table td.drops-row__error поднимает специфичность
   до 0,2,1, однозначно выше конкурента. */
.drops-table td.drops-row__error {
  padding: 8px 12px 14px;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--c-amber);
  white-space: normal;
  background: var(--c-amber-a08);
}

/* Та же специфичность-ловушка, что у .acc-empty (review I-2, task-8-review-
   fixes-a2, см. её комментарий у .acc-table td.acc-empty ниже по файлу) —
   .drops-table td (0,1,1) перебивала бы голый .drops-empty (0,1,0). */
.drops-table td.drops-empty {
  text-align: center;
  padding: 32px 12px;
  color: var(--text-muted);
  white-space: normal;
}

/* ── Дроп — карточка (Task 8a, часть 3) ─────────────────────────────────────
   Список почт на карточке переиспользует .drops-table-wrap/.drops-table/
   .drops-toolbar целиком (тот же визуальный язык, что список дропов) — ни
   одного нового табличного класса здесь нет, только сами поля дропа. ────── */

.drop-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

.drop-card-title {
  margin: 0;
  font-size: 22px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 10px;
}

.drop-card-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
  margin: 0 0 28px;
}

.drop-card-field dt {
  margin: 0 0 4px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.drop-card-field dd {
  margin: 0;
  font-size: 15px;
  color: var(--text-primary);
  overflow-wrap: anywhere;
}

.drop-card-section-title {
  margin: 0 0 12px;
  font-size: 16px;
  font-weight: 600;
}

/* ── Аккаунты — список (Task 8, часть 2) ─────────────────────────────────────
   Продолжает визуальный язык списка дропов (.drops-table-wrap/.drops-table,
   .drops-toggle-archived, .drops-action-btn, .drops-row__error) — вторая
   CRUD-страница проекта, не заводит параллельных решений там, где образец
   уже есть. Новое здесь: .acc-filters (поиск/букмекер/валюта, у дропов таких
   фильтров нет), .status-def-badge/.status-def-badge--* (статусный бейдж по
   StatusDef.color) и
   .acc-pagination (у дропов пагинации нет — список аккаунтов постраничный).
   ────────────────────────────────────────────────────────────────────────── */

.acc-page {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* justify-content: space-between (не flex-end, как раньше) — review I-4
   добавляет счётчик совпадений слева, тумблер архива остаётся справа, тот же
   приём, что .drops-toolbar применяет к своим счётчику+тумблеру. */
.acc-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

/* Группирует счётчик+тумблер слева (Task 9, часть 2, зеркало
   .drops-toolbar__meta) — кнопка «Добавить аккаунт» остаётся третьим прямым
   потомком .acc-toolbar и уезжает вправо через justify-content:
   space-between родителя; без этой обёртки на трёх прямых потомках счётчик
   и тумблер разъехались бы по разным концам строки. */
.acc-toolbar__meta {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

/* Число совпадений (review I-4) — тот же визуальный вес, что
   .drops-toolbar__count: приглушённый мелкий текст, не второй заголовок. */
.acc-toolbar__count {
  margin: 0;
  font-size: 13px;
  color: var(--text-muted);
}

.acc-toggle-archived__label {
  margin-left: 8px;
  font-size: 13px;
  color: var(--text-muted);
}

.acc-filters {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.acc-filter-input {
  flex: 1 1 260px;
  margin-bottom: 0;
}

.acc-filter-select {
  flex: 0 1 200px;
  margin-bottom: 0;
}

.acc-status-chips {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

@media (max-width: 640px) {
  .acc-filters { flex-direction: column; }
  .acc-filter-select { flex-basis: auto; width: 100%; }
}

/* ── Таблица — обёртка со скроллом, как .drops-table-wrap/.mx-wrap. ────────── */
.acc-table-wrap {
  overflow-x: auto;
}

.acc-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
}

.acc-table th {
  padding: 8px 12px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  border-bottom: 1px solid var(--wa-08);
  white-space: nowrap;
}
/* Выравнивание по классу (review I-5, task-8-review-fixes-a2), не по номеру
   колонки — тот же приём и то же обоснование, что у .drops-table th.col-right
   чуть выше по файлу: th:nth-child(6)/(7) молча уехал бы при вставке новой
   колонки, а ячейки (.acc-row__balance/.acc-row__transit) уже выравниваются
   по классу. */
.acc-table th.col-right {
  text-align: right;
}

.acc-table td {
  padding: 10px 12px;
  color: var(--text-primary);
  border-bottom: 1px solid var(--wa-07);
  white-space: nowrap;
}

.acc-row:hover { background: var(--surface-row); }

/* Архивная строка — приглушена целиком И несёт текстовый бейдж (тот же
   приём, что .drops-row--archived: одной приглушённости мало — тонкое
   отличие легко не заметить на живой странице). */
.acc-row--archived { opacity: 0.6; }

/* Букмекер/логин/дроп/событие переносятся по слову (white-space: normal +
   overflow-wrap: anywhere) — обнаружено живым осмотром (task-8-part2-report.md):
   без этого один необычно длинный букмекер или составная фамилия дропа
   (двойные русские фамилии через дефис — реалистичный, не надуманный случай)
   раздували ВСЮ таблицу по горизонтали через .acc-table td { white-space:
   nowrap } по умолчанию, вынуждая скроллить вбок ради одной длинной ячейки,
   хотя остальные колонки прекрасно помещались. max-width держит перенос в
   разумных границах, не давая текстовой колонке доминировать над числовыми.
   Селектор ОБЯЗАН включать .acc-table td — голый .acc-row__bookmaker (0,1,0)
   проигрывает специфичности .acc-table td (0,1,1) и white-space: normal
   молча не применяется (та же ловушка, что уже описана ниже для .is-zero и
   .acc-row__error; здесь на неё наступили при первом проходе и поймали
   только живым осмотром — DOM показывал white-space: nowrap, хотя правило
   ниже в файле). */
/* `anywhere` вместо `break-word` здесь опасен: он влияет на минимальную
   ширину содержимого, поэтому под горизонтальным давлением браузер вправе
   сжать колонку до одного символа — и «Тимофеев-Ресовский Владимир
   (2_Тимофеев-Ресовский)» разваливается на два десятка строк по два-три
   знака, а строка таблицы вырастает на пол-экрана (видно на узком окне).
   `break-word` переносит по словам и на минимальную ширину не влияет;
   `min-width` не даёт колонке схлопнуться, а горизонтальную прокрутку берёт
   на себя обёртка таблицы. */
.acc-table td.acc-row__bookmaker, .acc-table td.acc-row__drop {
  min-width: 140px;
  max-width: 260px;
  overflow-wrap: break-word;
  white-space: normal;
}

.acc-row__bookmaker a {
  color: var(--text-primary);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: var(--c-blue-a35);
  text-underline-offset: 3px;
  border-radius: 4px;
}
.acc-row__bookmaker a:hover { color: var(--c-blue); text-decoration-color: currentColor; }
.acc-row__bookmaker a:focus:not(:focus-visible) { outline: none; }
.acc-row__bookmaker a:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--c-blue-a35);
}

.acc-table td.acc-row__login, .acc-table td.acc-row__event {
  min-width: 120px;
  max-width: 260px;
  color: var(--text-muted);
  overflow-wrap: break-word;
  white-space: normal;
}

.acc-row__balance, .acc-row__transit {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
/* Ноль — приглушённым цветом (брифом: «Баланс — money_cur; ноль
   приглушён»), тот же приём и та же причина повышенной специфичности, что
   .drops-table td.is-zero (перебивает голый .acc-table td). */
.acc-table td.is-zero { color: var(--text-muted); font-weight: 400; }

.acc-badge {
  display: inline-block;
  margin-left: 8px;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  font-size: 11px;
  font-weight: 500;
  background: var(--surface-row);
  color: var(--text-muted);
}

/* Раскладка кнопок — на внутренней обёртке, НЕ на самой ячейке (правило
   брифа): display:flex на <td> выбивает ячейку из табличной раскладки, её
   нижняя граница рисуется выше соседей (тот же приём и та же причина, что
   .drops-row__actions/.drops-row__actions-inner). */
.acc-row__actions {
  vertical-align: middle;
}
.acc-row__actions-inner {
  display: flex;
  align-items: center;
  gap: 8px;
}

.acc-action-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 28px;
  padding: 0 12px;
  border: 1px solid var(--wa-08);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-primary);
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--transition-fast), border-color var(--transition-fast),
    color var(--transition-fast);
}
.acc-action-btn svg { display: block; flex-shrink: 0; }
.acc-action-btn:focus:not(:focus-visible) { outline: none; }
.acc-action-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--c-blue-a35);
}

.acc-action-btn--edit:hover,
.acc-action-btn--archive:hover,
.acc-action-btn--unarchive:hover {
  background: var(--surface-row);
  border-color: color-mix(in srgb, var(--c-blue) 35%, transparent);
  color: var(--c-blue);
}

.acc-action-btn--delete {
  color: var(--c-red);
  border-color: color-mix(in srgb, var(--c-red) 35%, transparent);
}
.acc-action-btn--delete:hover {
  background: var(--c-red-a08);
}

/* ── Отказ удаления по связям — понятная причина под строкой, не тост
   (правило брифа: «отказ → сообщение в интерфейсе, без тоста»). Амбер —
   предупреждение, не ошибка: аккаунт цел, связи не тронуты, это ожидаемый
   отказ (тот же приём, что .drops-row__error). ─────────────────────────── */
.acc-row__error-row td {
  border-bottom: 1px solid var(--wa-07);
}
.acc-table td.acc-row__error {
  padding: 8px 12px 14px;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--c-amber);
  white-space: normal;
  background: var(--c-amber-a08);
}

/* Специфичность .acc-table td (0,1,1) перебивала бы голый .acc-empty (0,1,0)
   — white-space/padding/color молча откатывались бы на правило td (review
   I-2, task-8-review-fixes-a2: четвёртый случай той же ловушки в файле, три
   предыдущих — .acc-row__bookmaker/.acc-row__drop, .acc-row__login/
   .acc-row__event, .is-zero, .acc-row__error — уже исправлены тем же
   приёмом чуть выше). .acc-table td.acc-empty поднимает специфичность до
   (0,2,1), однозначно выше конкурента. */
.acc-table td.acc-empty {
  text-align: center;
  padding: 32px 12px;
  color: var(--text-muted);
  white-space: normal;
}

/* ── Пагинация — у списка дропов её нет (список не постраничный), аккаунты и
   платёжки постраничны (app/pagination.py::PAGE_SIZE — единственный
   источник размера страницы для обоих роутеров, I-8 финального ревью). ── */
.acc-pagination {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 16px;
  flex-wrap: wrap;
}

.acc-page-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 28px;
  height: 28px;
  padding: 0 8px;
  border: 1px solid var(--wa-08);
  border-radius: var(--radius-button);
  background: transparent;
  color: var(--text-primary);
  font-size: 12.5px;
  cursor: pointer;
  transition: background var(--transition-fast), border-color var(--transition-fast),
    color var(--transition-fast);
}
.acc-page-btn:hover {
  background: var(--surface-row);
  border-color: color-mix(in srgb, var(--c-blue) 35%, transparent);
}
.acc-page-btn--active {
  background: var(--c-blue);
  border-color: var(--c-blue);
  color: var(--text-2);
  font-weight: 600;
  cursor: default;
}
.acc-page-ellipsis {
  color: var(--text-muted);
  font-size: 12.5px;
  padding: 0 4px;
}

/* ── Экспорт CSV (Task 8, часть 2) — тот же outline-стиль веса, что
   .acc-action-btn, но страничное действие, не строчное: чуть крупнее,
   собственный отступ сверху отделяет его от таблицы. ─────────────────────── */
.acc-export {
  display: flex;
  justify-content: flex-end;
  margin-top: 12px;
}
.acc-export-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 14px;
  border: 1px solid var(--wa-08);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-primary);
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--transition-fast), border-color var(--transition-fast),
    color var(--transition-fast);
}
.acc-export-btn:hover {
  background: var(--surface-row);
  border-color: color-mix(in srgb, var(--c-blue) 35%, transparent);
  color: var(--c-blue);
}
.acc-export-btn:focus:not(:focus-visible) { outline: none; }
.acc-export-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--c-blue-a35);
}

/* ── Статусный бейдж — StatusDef.color -> .status-def-badge--<color> (8
   токенов, app/constants.py::STATUS_COLORS). Имя класса (review M-9, task-8-
   review-fixes-a2): раньше двухбуквенный `.st`/`.st--*` — глобальный класс в
   общем файле стилей, различимого имени не несёт и легко столкнуться с
   чем-то ещё; ниже по алфавиту в этом же файле уже есть НЕСВЯЗАННЫЙ
   `.status-badge` (fin-наследие, пилюли статуса СДЕЛКИ по фиксированному
   имени — .status-pending и т.д., НЕ по StatusDef.color) — `status-def-badge`
   выбран НАРОЧНО отличным от него текстом, чтобы не читаться как опечатка
   одного и того же класса. Тот же приём «тонированный фон + насыщенный
   текст», что .chip--<status> (fin-наследие) уже применяет к статусам
   сделок, но с другим набором цветов: у StatusDef 8 своих (зелёный/
   оранжевый/жёлтый/бирюзовый/красный/серый/пурпурный/тёмный), выбираемых
   владельцем в настройках, не фиксированных по имени статуса. green/orange/
   red/magenta переиспользуют уже существующие токены палитры (--c-green/
   --c-amber/--c-red/--c-violet-2); yellow/teal у палитры своих токенов нет —
   отдельные литералы, тем же приёмом «тонированный фон», что и у остальных;
   gray/dark — нейтральные --wa-*/--text-* токены, приглушённее друг друга
   (у "написан"/dark меньше визуального веса, чем у "порезан"/gray). ───────── */
.status-def-badge {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.4;
  white-space: nowrap;
}
.status-def-badge--green { background: color-mix(in srgb, var(--c-green) 16%, transparent); color: var(--c-green); }
.status-def-badge--orange { background: color-mix(in srgb, var(--c-amber) 16%, transparent); color: var(--c-amber); }
.status-def-badge--red { background: color-mix(in srgb, var(--c-red) 16%, transparent); color: var(--c-red); }
.status-def-badge--magenta { background: color-mix(in srgb, var(--c-violet-2) 16%, transparent); color: var(--c-violet-2); }
.status-def-badge--yellow { background: rgba(232, 210, 74, 0.16); color: #e8d24a; }
.status-def-badge--teal { background: rgba(78, 205, 196, 0.16); color: #4ecdc4; }
.status-def-badge--gray { background: var(--wa-08); color: var(--text-muted); }
.status-def-badge--dark { background: var(--wa-05); color: var(--text-6); }

/* ── Аккаунт — карточка, только просмотр (Task 9, часть 1) ──────────────────
   Переиспользует .drop-card-header/.drop-card-title/.drop-card-fields/
   .drop-card-field/.drop-card-section-title (Task 8a) — та же карточная
   раскладка, что у дропа, третья почти одинаковая карточка не заводит
   параллельного набора классов. Новое здесь: .acc-card-* (подзаголовок с
   ID/статусом, денежные плашки и зарезервированный контейнер под действия
   части 2 — у карточки дропа аналога нет) и .acc-ops-table/.acc-events-list
   (лента операций/событий — своя у аккаунта). ──────────────────────────────── */

.acc-card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

.acc-card-title {
  margin: 0 0 4px;
  font-size: 22px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 10px;
}

.acc-card-subtitle {
  margin: 0;
  font-size: 13px;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Кнопки правки/архивации/удаления (Task 9, часть 2) — переиспользуют
   .acc-action-btn* строки списка (accounts/_list_body.html) как есть, без
   отдельного набора классов под карточку: тот же визуальный вес и hover/
   focus-состояния, раскладка (flex-строка, gap 8px) была задана уже в Part 1,
   чтобы Part 2 только вставила кнопки, не занимаясь раскладкой. */
.acc-card-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* ── Отказ удаления по связям — карточка (Task 9, часть 2). Карточка одной
   сущности, не таблица: .acc-row__error/.acc-row__error-row (список) висят
   на <td>/<tr> своей строки и здесь не подходят буквально. Тот же смысл
   («предупреждение, не ошибка» — аккаунт цел, связи не тронуты), тот же
   амбер-приём и те же токены, что .rates-warning (_bank_body.html) —
   единственный существующий в проекте блочный (не табличный) образец. ──── */
.acc-card-delete-error {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0 0 20px;
  padding: 10px 14px;
  border: 1px solid var(--c-amber-a45);
  border-radius: var(--radius-card);
  background: var(--c-amber-a08);
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--text-primary);
}
.acc-card-delete-error__icon { display: flex; flex-shrink: 0; color: var(--c-amber); }
.acc-card-delete-error__icon svg { display: block; }

.acc-card-tiles {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 0 0 24px;
}

.acc-card-tile {
  flex: 1 1 160px;
  background: var(--surface-card);
  border: 1px solid var(--wa-08);
  border-radius: var(--radius-card);
  padding: 14px 16px;
}

.acc-card-tile__label {
  display: block;
  margin: 0 0 4px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.acc-card-tile__value {
  display: block;
  font-size: 20px;
  font-weight: 700;
  color: var(--text-primary);
}

.acc-card-tile__sub {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  color: var(--text-muted);
}

.acc-ops-table-wrap { overflow-x: auto; }

.acc-ops-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
  margin-bottom: 24px;
}
.acc-ops-table th {
  text-align: left;
  padding: 8px 12px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  border-bottom: 1px solid var(--wa-08);
}
.acc-ops-table td {
  padding: 8px 12px;
  border-bottom: 1px solid var(--wa-07);
  color: var(--text-primary);
}
/* .acc-ops-table td (0,1,1) перебивала бы голый .acc-ops-table__empty (0,1,0)
   — та же специфичность-ловушка, что у .acc-table td.acc-empty/.drops-table
   td.drops-empty (review I-2, task-8-review-fixes-a2). */
.acc-ops-table td.acc-ops-table__empty {
  text-align: center;
  color: var(--text-muted);
  padding: 24px 12px;
}

.acc-events-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 13px;
  color: var(--text-primary);
}
/* Pico задаёт list-style-type на самом li и перебивает none у списка (тот же
   приём, что .box__list li/.drops-table td.drops-empty выше по файлу) — марker
   виден только потому, что li не flex здесь; гасим на элементах, не на ul. */
.acc-events-list li { list-style: none; }

/* ── Форма аккаунта — создание/правка (Task 9, часть 2) ──────────────────────
   dialog.modal-form + голые <label>/<input>/<select>/<textarea> без нового
   класса под сам инпут (тот же приём, что drops/_drop_form.html/
   _email_form.html — компактный вид уже даёт dialog.modal-form :is(input,
   select, textarea) выше по файлу). Пароль — .password-field (тот же
   компонент, что у почты дропа). Новое здесь ровно два класса: сетка «два
   поля в ряд» (полей у аккаунта много больше, чем у дропа/почты — плотнее
   вертикально) и маркер обязательности (task-9-corrections.md §5: «сейчас
   человек узнаёт об обязательности только после отправки»). ──────────────── */
.acc-form-hint {
  margin: 0 0 12px;
  font-size: 12px;
  color: var(--text-muted);
}

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

.acc-form-row-2col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 12px;
}

@media (max-width: 640px) {
  .acc-form-row-2col { grid-template-columns: 1fr; }
}
.acc-events-list__empty { color: var(--text-muted); }

/* ── Операции по аккаунту (Task 10) — депозит/выигрыш/проигрыш/вывод,
   разрешение висящих запросов. Переиспользует .acc-action-btn (Task 8/9) как
   базовый класс кнопки — тот же визуальный вес и hover/focus-поведение, что у
   Редактировать/Архивировать/Удалить в .acc-card-actions; новое здесь — ровно
   цветовые модификаторы (семантика: зелёный — деньги прибывают, красный —
   убывают/отменяют, синий — нейтральный запрос) и .acc-badge--pending
   (та же база .acc-badge, что и --archived, — амбер вместо приглушённого
   серого: заявка ждёт действия, а не просто лежит в архиве).
   .acc-row__actions/.acc-row__actions-inner (Task 8, список аккаунтов)
   переиспользуются буквально для Подтвердить/Отмена в таблице операций —
   третьего набора layout-классов под то же самое не заводим. ──────────────── */
.acc-ops-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 0 0 20px;
}

.acc-action-btn--deposit:hover,
.acc-action-btn--win:hover,
.acc-action-btn--confirm:hover {
  background: var(--c-green-a08);
  border-color: color-mix(in srgb, var(--c-green) 35%, transparent);
  color: var(--c-green);
}

.acc-action-btn--loss:hover,
.acc-action-btn--cancel:hover {
  background: var(--c-red-a08);
  border-color: color-mix(in srgb, var(--c-red) 35%, transparent);
  color: var(--c-red);
}

.acc-action-btn--withdraw:hover {
  background: var(--surface-row);
  border-color: color-mix(in srgb, var(--c-blue) 35%, transparent);
  color: var(--c-blue);
}

.acc-badge--pending {
  background: var(--c-amber-a08);
  color: var(--c-amber);
}

/* Сводка запрошенной суммы/платёжки в форме подтверждения (Task 10) —
   тонированный блок, тот же приём «фон var(--surface-row)», что уже держат
   .acc-row:hover/#account-card-body для второстепенного, не тревожного
   контекста (в отличие от амбер-предупреждений acc-card-delete-error). */
.acc-op-summary {
  margin: 0 0 16px;
  padding: 10px 14px;
  border-radius: var(--radius-card);
  background: var(--surface-row);
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-primary);
}

/* ── Платёжки — список (Task 11, блок «список») ───────────────────────────
   Продолжает визуальный язык списка аккаунтов (.acc-table-wrap/.acc-table,
   .acc-toggle-archived, .status-def-badge) — четвёртая CRUD-страница
   проекта, не заводит параллельных решений там, где образец уже есть.
   Новое здесь: .wal-usd (курс в USD рядом с нативным балансом — список
   платёжек умеет показывать «Итого по выборке» через валюты, у аккаунтов
   такого сводного футера нет) и колонка «Аккаунт» (Wallet.account_id —
   поправка №2 §2, у Account такой обратной ссылки в списке нет). ─────────── */

.wal-page {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.wal-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.wal-toolbar__meta {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

.wal-toolbar__count {
  margin: 0;
  font-size: 13px;
  color: var(--text-muted);
}

.wal-toggle-archived__label {
  margin-left: 8px;
  font-size: 13px;
  color: var(--text-muted);
}

.wal-filters {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.wal-filter-input {
  flex: 1 1 260px;
  margin-bottom: 0;
}

.wal-filter-select {
  flex: 0 1 200px;
  margin-bottom: 0;
}

.wal-status-chips {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

@media (max-width: 640px) {
  .wal-filters { flex-direction: column; }
  .wal-filter-select { flex-basis: auto; width: 100%; }
}

.wal-table-wrap {
  overflow-x: auto;
}

.wal-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
}

.wal-table th {
  padding: 8px 12px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  border-bottom: 1px solid var(--wa-08);
  white-space: nowrap;
}
/* Выравнивание по классу, не по номеру колонки — тот же приём и то же
   обоснование, что .acc-table th.col-right (review I-5, task-8-review-
   fixes-a2): вставка новой колонки между «Валюта» и «Статус» не должна
   молча сдвинуть выравнивание. */
.wal-table th.col-right {
  text-align: right;
}

.wal-table td {
  padding: 10px 12px;
  color: var(--text-primary);
  border-bottom: 1px solid var(--wa-07);
  white-space: nowrap;
}

.wal-row:hover { background: var(--surface-row); }

/* Архивная строка — приглушена целиком И несёт текстовый бейдж (тот же
   приём, что .acc-row--archived: одной приглушённости мало). */
.wal-row--archived { opacity: 0.6; }

/* Тип/логин/дроп/аккаунт переносятся по слову (white-space: normal +
   overflow-wrap: break-word, НЕ anywhere — см. обоснование у
   .acc-row__bookmaker/.acc-row__drop: `anywhere` может схлопнуть колонку до
   одного символа под горизонтальным давлением, `break-word` переносит по
   словам и не трогает минимальную ширину). Селектор ОБЯЗАН включать
   .wal-table td — голый класс (0,1,0) проигрывает специфичности .wal-table
   td (0,1,1), и white-space: normal молча не применился бы (та же ловушка,
   что уже задокументирована для .acc-row__bookmaker/.is-zero/.acc-row__error). */
.wal-table td.wal-row__kind,
.wal-table td.wal-row__drop,
.wal-table td.wal-row__account {
  min-width: 120px;
  max-width: 220px;
  overflow-wrap: break-word;
  white-space: normal;
}

.wal-table td.wal-row__login {
  min-width: 120px;
  max-width: 260px;
  color: var(--text-muted);
  overflow-wrap: break-word;
  white-space: normal;
}

.wal-row__balance {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
.wal-table td.is-zero { color: var(--text-muted); font-weight: 400; }

.wal-usd {
  opacity: 0.65;
  font-size: 0.85em;
  margin-left: 6px;
  font-weight: 400;
}

.wal-badge {
  display: inline-block;
  margin-left: 8px;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  font-size: 11px;
  font-weight: 500;
  background: var(--surface-row);
  color: var(--text-muted);
}

/* Специфичность .wal-table td (0,1,1) перебивала бы голый .wal-empty
   (0,1,0) — та же ловушка, что .acc-table td.acc-empty (review I-2,
   task-8-review-fixes-a2). .wal-table td.wal-empty поднимает специфичность
   до (0,2,1), однозначно выше конкурента. */
.wal-table td.wal-empty {
  text-align: center;
  padding: 32px 12px;
  color: var(--text-muted);
  white-space: normal;
}

.wal-pagination {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 16px;
  flex-wrap: wrap;
}

.wal-page-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 28px;
  height: 28px;
  padding: 0 8px;
  border: 1px solid var(--wa-08);
  border-radius: var(--radius-button);
  background: transparent;
  color: var(--text-primary);
  font-size: 12.5px;
  cursor: pointer;
  transition: background var(--transition-fast), border-color var(--transition-fast),
    color var(--transition-fast);
}
.wal-page-btn:hover {
  background: var(--surface-row);
  border-color: color-mix(in srgb, var(--c-blue) 35%, transparent);
}
.wal-page-btn--active {
  background: var(--c-blue);
  border-color: var(--c-blue);
  color: var(--text-2);
  font-weight: 600;
  cursor: default;
}
.wal-page-ellipsis {
  color: var(--text-muted);
  font-size: 12.5px;
  padding: 0 4px;
}

/* ── Платёжки — карточка и CRUD (Task 11, блок «карточка и CRUD») ────────
   Продолжает визуальный язык аккаунтов (.acc-add-pill/.drops-add-btn ->
   .wal-add-btn, .acc-action-btn -> .wal-action-btn, .acc-card-* ->
   .wal-detail-*) — та же карточная раскладка, что у аккаунта/дропа
   (.drop-card-fields/.drop-card-field/.drop-card-section-title
   переиспользуются буквально, не копируются). ─────────────────────────── */

.wal-add-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 16px;
  border: none;
  border-radius: var(--radius-pill);
  background: var(--c-blue);
  color: var(--text-2);
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  transition: opacity var(--transition-fast);
  flex-shrink: 0;
}
.wal-add-btn:hover { opacity: .88; }
.wal-add-btn svg { display: block; flex-shrink: 0; }
.wal-add-btn:focus:not(:focus-visible) { outline: none; }
.wal-add-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--c-blue-a35);
}

/* Тип платёжки — кликабельная кнопка, открывающая детальную модалку, а не
   <a href>: GET /wallets/{id} всегда отдаёт фрагмент модалки, а не
   полноценную страницу (в отличие от аккаунтов, у платёжки нет отдельного
   /wallets/{id} как полной навигации) — <a> без JS привёл бы на голый
   фрагмент без <html>. Кнопка сброшена до вида ссылки (тот же визуальный
   язык, что .acc-row__bookmaker a). */
.wal-row__kind-link {
  border: none;
  background: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: var(--text-primary);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: var(--c-blue-a35);
  text-underline-offset: 3px;
  border-radius: 4px;
  cursor: pointer;
}
.wal-row__kind-link:hover { color: var(--c-blue); text-decoration-color: currentColor; }
.wal-row__kind-link:focus:not(:focus-visible) { outline: none; }
.wal-row__kind-link:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--c-blue-a35);
}

/* Раскладка кнопок — на внутренней обёртке, НЕ на самой ячейке (тот же
   приём и та же причина, что .acc-row__actions/.acc-row__actions-inner). */
.wal-row__actions {
  vertical-align: middle;
}
.wal-row__actions-inner {
  display: flex;
  align-items: center;
  gap: 8px;
}

.wal-action-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 28px;
  padding: 0 12px;
  border: 1px solid var(--wa-08);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-primary);
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--transition-fast), border-color var(--transition-fast),
    color var(--transition-fast);
}
.wal-action-btn svg { display: block; flex-shrink: 0; }
.wal-action-btn:focus:not(:focus-visible) { outline: none; }
.wal-action-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--c-blue-a35);
}

.wal-action-btn--edit:hover,
.wal-action-btn--archive:hover,
.wal-action-btn--unarchive:hover {
  background: var(--surface-row);
  border-color: color-mix(in srgb, var(--c-blue) 35%, transparent);
  color: var(--c-blue);
}

.wal-action-btn--delete {
  color: var(--c-red);
  border-color: color-mix(in srgb, var(--c-red) 35%, transparent);
}
.wal-action-btn--delete:hover {
  background: var(--c-red-a08);
}

/* ── Отказ удаления по связям — понятная причина под строкой, не тост
   (тот же приём, что accounts/_list_body.html::.acc-row__error). ────────── */
.wal-row__error-row td {
  border-bottom: 1px solid var(--wa-07);
}
.wal-table td.wal-row__error {
  padding: 8px 12px 14px;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--c-amber);
  white-space: normal;
  background: var(--c-amber-a08);
}

/* ── Форма платёжки — создание/правка ──────────────────────────────────── */
.wal-form-hint {
  margin: 0 0 12px;
  font-size: 12px;
  color: var(--text-muted);
}

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

.wal-form-row-2col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 12px;
}

@media (max-width: 640px) {
  .wal-form-row-2col { grid-template-columns: 1fr; }
}

/* ── Детальная модалка платёжки ────────────────────────────────────────── */
.wal-detail-title {
  margin: 0;
  font-size: 20px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 10px;
}

.wal-detail-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 0 0 16px;
}

.wal-detail-delete-error {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0 0 20px;
  padding: 10px 14px;
  border: 1px solid var(--c-amber-a45);
  border-radius: var(--radius-card);
  background: var(--c-amber-a08);
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--text-primary);
}
.wal-detail-delete-error__icon { display: flex; flex-shrink: 0; color: var(--c-amber); }
.wal-detail-delete-error__icon svg { display: block; }

.wal-detail-tiles {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 0 0 24px;
}

.wal-detail-tile {
  flex: 1 1 140px;
  background: var(--surface-card);
  border: 1px solid var(--wa-08);
  border-radius: var(--radius-card);
  padding: 14px 16px;
}

.wal-detail-tile__label {
  display: block;
  margin: 0 0 4px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.wal-detail-tile__value {
  display: block;
  font-size: 20px;
  font-weight: 700;
  color: var(--text-primary);
}

.wal-detail-tile__sub {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  color: var(--text-muted);
}

.wal-ops-table-wrap { overflow-x: auto; }

.wal-ops-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
  margin-bottom: 24px;
}
.wal-ops-table th {
  text-align: left;
  padding: 8px 12px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  border-bottom: 1px solid var(--wa-08);
}
.wal-ops-table td {
  padding: 8px 12px;
  border-bottom: 1px solid var(--wa-07);
  color: var(--text-primary);
}
.wal-ops-table td.wal-ops-table__empty {
  text-align: center;
  color: var(--text-muted);
  padding: 24px 12px;
}

.wal-events-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 13px;
  color: var(--text-primary);
}
.wal-events-list li { list-style: none; }
.wal-events-list__empty { color: var(--text-muted); }

/* ── Операции по платёжке (Task 11, блок «операции») ──────────────────────
   wallet_in/wallet_out/transfer/fee — все первичные, форма инлайн внутри
   уже открытой детальной модалки (не отдельный dialog, в отличие от
   аккаунтовых операций — см. app/templates/wallets/_op_form.html). ──────── */
.wal-op-chips {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin: 0 0 16px;
}

.wal-op-form {
  margin: 0 0 20px;
}
/* Форма не задаёт себе display:flex/grid (в отличие от черновика брифа) —
   голые <div>-обёртки полей стекаются друг под другом дефолтным block той
   же плотностью, что и в wallets/_wallet_form.html (без параллельного
   набора layout-правил под то же самое). Раз собственного display нет,
   переопределять [hidden] не нужно — правило браузера по умолчанию
   ([hidden] { display: none }) уже действует без конкурента. */

/* .wal-form-row-2col (wallets/_wallet_form.html) переиспользуется буквально
   для поля-приёмника перевода — но ЗДЕСЬ она условно скрыта [hidden], а сама
   несёт собственный display:grid (см. её объявление выше по файлу), поэтому
   явный override обязателен (CLAUDE.md: hidden + собственный display) —
   иначе специфичность класса (0,1,0) перебивает атрибутный селектор
   браузера по умолчанию ([hidden], тоже 0,1,0, но позже в каскаде UA-стилей
   проигрывает автору), и поля перевода остаются видны для wallet_in/
   wallet_out/fee, где им не место. */
.wal-form-row-2col[hidden] { display: none; }

.wal-op-fee-field {
  margin: 0 0 12px;
}

/* ── Экспорт CSV (Task 11, блок «экспорт») — тот же outline-стиль веса, что
   .wal-action-btn/.acc-export-btn, но страничное действие, не
   строчное: чуть крупнее, собственный отступ сверху отделяет его от
   таблицы (тот же приём, что accounts/_list_body.html::.acc-export). ────── */
.wal-export {
  display: flex;
  justify-content: flex-end;
  margin-top: 12px;
}
.wal-export-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 14px;
  border: 1px solid var(--wa-08);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-primary);
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--transition-fast), border-color var(--transition-fast),
    color var(--transition-fast);
}
.wal-export-btn:hover {
  background: var(--surface-row);
  border-color: color-mix(in srgb, var(--c-blue) 35%, transparent);
  color: var(--c-blue);
}
.wal-export-btn:focus:not(:focus-visible) { outline: none; }
.wal-export-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--c-blue-a35);
}

/* ── Акцент поверх вендора (перекраска 2026-08-03) ─────────────────────────
   Pico в тёмной схеме задаёт --pico-primary селектором
   :root:not([data-theme]) (специфичность 0,2,0), который перебивает наш
   :root (0,1,0) — активный чип фильтра оставался вендорно-голубым #01aaff
   при полностью зелёной теме. Дублируем с той же специфичностью в конце
   файла; значение — ссылка на токен, а не вторая копия числа. */
:root:not([data-theme]),
[data-theme="dark"] {
  --pico-primary: var(--c-blue);
  /* Расширение 2026-08-04 (унификация окон занесения): Pico v2 читает не
     --pico-primary, а целую семью токенов — кнопка [type=submit] красится
     --pico-primary-background (#0172ad, вендорная лазурь — «синий „Создать“»),
     карточка модалки --pico-card-background-color (#181c25, навы), инпуты
     --pico-form-element-background-color (rgb(28,33,43.5), навы). Переводим
     всю семью на наши токены, чтобы ЛЮБАЯ форма красилась темой без
     точечных правок по шаблонам. */
  --pico-background-color: #0e1512;
  --pico-primary-background: var(--accent);
  --pico-primary-hover-background: var(--accent-hover);
  --pico-primary-focus: rgba(81, 184, 110, .35);
  --pico-primary-inverse: #fff;
  --pico-card-background-color: var(--surface-card);
  --pico-card-sectioning-background-color: var(--surface-tile);
  --pico-form-element-background-color: #0f1712;
  --pico-form-element-active-background-color: #0d1410;
  --pico-form-element-border-color: var(--wa-12);
  --pico-form-element-active-border-color: var(--accent);
  --pico-form-element-focus-color: rgba(81, 184, 110, .35);
  --pico-form-element-placeholder-color: var(--text-muted);
  --pico-muted-border-color: #1f2a24;
  --pico-secondary: var(--text-muted);
  --pico-secondary-background: #24312a;
  --pico-secondary-hover-background: #2c3b33;
  --pico-secondary-focus: rgba(133, 152, 143, .25);
}

/* ── Настройки — статусы + курсы валют (Task 12) ───────────────────────────
   Заголовок страницы переиспользует .settings-page-header/.settings-page-
   title* (определены выше в этом файле, унаследованы из fin — узкая
   центрированная колонка 860px, уже используется этой же разметкой в
   app/templates/settings.html). Классы НИЖЕ — новые, с префиксом .set-
   (тот же короткий префикс на страницу, что .acc-/.wal-/.bank- у соседних
   разделов) и НЕ связаны с fin-овским .settings-shell/.settings-card/
   .deal-form-input — той двухпанельной системой с разделами dashboard/
   calendar/presets, которой во Froks просто нет; переиспользовать её классы
   здесь означало бы утащить в разметку flatten-правила и pinning-правила,
   написанные для СОВСЕМ другой структуры (см. .settings-content .settings-
   card{...} выше — сработает только внутри .settings-content, которого
   здесь нет и не будет). Бейдж статуса переиспользует канонический
   .status-def-badge (тот же макрос, что уже красит статусы в списках
   аккаунтов/платёжек) — своей копии палитры цветов не заводим. */

/* Одна колонка, а не 1fr 1fr: min-content таблицы статусов (~940px, шесть
   колонок с инпутами) шире половины контейнера при любой ширине ≤1280
   (кап .main-content > *), т.е. вторая колонка гарантированно выдавливалась
   за правый край (grid blowout — headless-замер: scrollWidth 1527 при
   innerWidth 1280). Карточки складываются в столбец; min-width:0 у детей —
   страховка, чтобы .set-table-wrap{overflow-x:auto} реально скроллил
   таблицу внутри карточки на узких окнах, а не распирал сетку. */
.set-cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
  align-items: start;
}
.set-cards > * { min-width: 0; }

/* Карточка курсов — три узкие колонки; на всю ширину контейнера она
   растягивается в пустое полотно, кап держит её компактной. */
#set-rates-card { max-width: 640px; }

.set-card {
  background: var(--surface-card);
  border: 1px solid var(--wa-08);
  border-radius: var(--radius-card);
  padding: 18px 20px 20px;
}

.set-card h2 {
  margin: 0 0 4px;
  font-size: 15px;
  font-weight: 600;
  color: var(--text-primary);
}

.set-card__hint {
  margin: 0 0 14px;
  font-size: 12px;
  color: var(--text-muted);
}

.set-card h3 {
  margin: 18px 0 8px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.set-card h3:first-of-type { margin-top: 4px; }

.set-table-wrap { overflow-x: auto; }

.set-status-table,
.set-rates-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  margin-bottom: 4px;
}
.set-status-table th,
.set-rates-table th {
  text-align: left;
  padding: 6px 8px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  border-bottom: 1px solid var(--wa-08);
  white-space: nowrap;
}
.set-status-table td,
.set-rates-table td {
  padding: 7px 8px;
  border-bottom: 1px solid var(--wa-07);
  vertical-align: middle;
}
.set-status-table tr:last-child td,
.set-rates-table tr:last-child td {
  border-bottom: none;
}
.set-status-table__new-row { background: var(--wa-02); }

.set-input,
.set-select {
  width: 100%;
  min-width: 8rem;
  height: 32px;
}
.set-status-table .set-input,
.set-status-table .set-select {
  min-width: 6rem;
}

.set-num { width: 4.5rem; min-width: 0; }

.set-key-input {
  color: var(--text-muted);
  background: transparent;
}

.set-fixed-note {
  font-size: 12px;
  color: var(--text-muted);
}

/* ── Курсы: «1 валюта = X USD» — подпись обязана быть явной (task-12-
   corrections.md §3): перепутанное направление (рубли-за-доллар вместо
   доллара-за-рубль) двигает итоги казны на порядки. ───────────────────── */
.set-rate-row__eq {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  font-size: 13px;
  white-space: nowrap;
}

.set-rate-row__input { width: 6rem; min-width: 0; }

.set-rate-forms {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
}

.set-source {
  display: inline-block;
  font-size: 11px;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: var(--wa-08);
  color: var(--text-muted);
  white-space: nowrap;
}
.set-source--manual {
  background: color-mix(in srgb, var(--c-blue) 16%, transparent);
  color: var(--c-blue);
}
.set-source--fixed {
  background: var(--wa-08);
  color: var(--text-muted);
}
.set-source--missing {
  background: color-mix(in srgb, var(--c-amber) 16%, transparent);
  color: var(--c-amber);
}

.set-form-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 10px;
}

.set-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 12px;
  border: 1px solid var(--wa-08);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-primary);
  font-size: 12.5px;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--transition-fast), border-color var(--transition-fast),
    color var(--transition-fast);
}
.set-btn:hover {
  background: var(--surface-row);
  border-color: color-mix(in srgb, var(--c-blue) 35%, transparent);
  color: var(--c-blue);
}
.set-btn:focus:not(:focus-visible) { outline: none; }
.set-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--c-blue-a35);
}
.set-btn--primary {
  border-color: color-mix(in srgb, var(--c-blue) 45%, transparent);
  color: var(--c-blue);
}
.set-btn--ghost {
  border-color: transparent;
  color: var(--text-muted);
}

@media (max-width: 640px) {
  .set-rate-forms { width: 100%; }
  .set-rate-row__eq { width: 100%; }
  .set-rate-row__input { flex: 1 1 auto; width: auto; }
}

/* ── Подвал списка платёжек: оговорка «курс неизвестен» (Task 11, review
   C-1) — заменяет число в <td>, когда хоть одна валюта текущей страницы не
   имеет курса в БД. Тот же амбер-приём («предупреждение, не ошибка»), что
   .rates-warning/.acc-card-delete-error, но БЕЗ рамки/фона — ячейка таблицы
   уже несёт собственный паддинг, второй бокс внутри нёс бы лишний слой. ─── */
.wal-footer-unpriced {
  color: var(--c-amber);
  font-size: 12.5px;
  line-height: 1.4;
}


/* ── Лента показателей под героем (редизайн, вариант B) ──────────────────── */
.bank-kpis {
  display: flex;
  background: var(--surface-card);
  border: 1px solid var(--wa-07);
  border-radius: var(--radius-card);
  margin-bottom: 16px;
}
.bank-kpi {
  flex: 1;
  padding: 16px 22px;
  border-right: 1px solid var(--wa-05);
}
.bank-kpi:last-child { border-right: none; }
.bank-kpi__label {
  font-size: 11px;
  font-weight: 650;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.bank-kpi__value {
  font-size: 20px;
  font-weight: 720;
  letter-spacing: -0.3px;
  margin-top: 4px;
  font-variant-numeric: tabular-nums;
}
.bank-kpi__value.is-zero { color: var(--text-muted); }
@media (max-width: 720px) {
  .bank-kpis { flex-wrap: wrap; }
  .bank-kpi { flex: 1 1 45%; border-bottom: 1px solid var(--wa-05); }
}
