/* A5 CRM — pipe.css (screen «Сделки»: воронка + Канбан / Список / Прогноз, «Не сделки»). Owned by screens/pipe.js
   Stripe Dashboard language (DESIGN-STRIPE.md §6.1): a filter row under the page header, grey lanes with white raised
   cards (the kanban is [E], built from Stripe's edit-mode overview), a Stripe list table, the same lanes for the forecast.
   Every colour is a token of base.css; no theme selectors here (§7.2.8).
   Calm colour pass (DESIGN-CALM.md §4 G2, Attio treatment): per-card signals are status marks (coloured glyph + neutral text),
   attention counters are soft tints, focus and flashes are 1 px, drop targets = accent wash + 3 px top line. */

.pipe{position:relative;display:grid;grid-template-rows:auto minmax(0,1fr);grid-template-columns:minmax(0,1fr);min-height:0;overflow:hidden}
.pipe > .tb{grid-row:1}
.pipe > .pv-body{grid-row:2}

/* ── toolbar (pipe.js toolbar(); the owner's pick «Воронки вкладками», DESIGN-CALM §13): the pipelines as underline tabs
   with their counts over a full-width hairline; under them views · «Все / Мои» · «Фильтр» + set pills … сумма ── */
.pipe > .tb{display:grid;gap:16px;min-width:0;padding:0 var(--page-pad) 16px}
.pipe .tb-row{display:flex;flex-wrap:wrap;align-items:center;gap:8px;min-width:0}
.pipe .pp-sp{flex:1 1 0;min-width:0}
.pipe .tb-sum{display:block;flex:none;height:var(--control-h);
  font:var(--t-body);line-height:var(--control-h);color:var(--text-3);white-space:nowrap;font-variant-numeric:tabular-nums}
.pipe .tb-sum b{font-weight:600;color:var(--text-strong)}
.pipe .tb-sum > * + *{margin-left:4px}

/* «Все / Мои» stands apart from the views (and their extras) by a 1 px rule, as the tasks bar */
.pipe .tb-row > .pp-who{position:relative;margin-left:13px}
.pipe .tb-row > .pp-who:first-child{margin-left:0}
.pipe .tb-row > .pp-who:not(:first-child)::before{content:"";position:absolute;left:-13px;top:6px;bottom:6px;width:1px;background:var(--border)}
.pipe .seg.pv button{justify-content:center}

/* «Фильтр»: one control button with the number of active filters; each active filter = a pressed pill with its own ×
   (the manager — «Мои» is the switch — channel, «Ждут ответа», «Просроченные задачи», «Без следующего шага») */
.pipe .pp-flt{display:flex;flex-wrap:wrap;align-items:center;gap:8px;min-width:0}
.pipe .btn.pp-fb{gap:6px}
.pipe .btn.pp-fb .ic{width:16px;height:16px;stroke-width:2;color:var(--icon)}
.pipe .pp-fbn{display:inline-grid;place-items:center;min-width:18px;height:18px;padding:0 5px;border-radius:999px;background:var(--surface-pressed);font:var(--t-caption-strong);color:var(--text-strong);font-variant-numeric:tabular-nums;animation:pp-pop 180ms var(--ease-out)}
@keyframes pp-pop{from{transform:scale(.6);opacity:0}to{transform:none;opacity:1}}
.pipe .pp-fc{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 4px 0 10px;border-radius:999px;background:var(--surface-pressed);box-shadow:0 0 0 1px var(--border);font:var(--t-body-medium);color:var(--text-strong);white-space:nowrap}
.pipe .pp-fc .av{width:18px;height:18px;font-size:9px}
.pipe .pp-fc button{width:20px;height:20px;display:grid;place-items:center;border-radius:50%;color:var(--icon);transition:background-color var(--dur-1) linear,color var(--dur-1) linear}
.pipe .pp-fc button:hover{background:var(--surface-hover);color:var(--text-strong)}
.pipe .pp-fc button:focus-visible{box-shadow:var(--focus-ring)}
.pipe .pp-fc button .ic{width:12px;height:12px;stroke-width:2.4}
.pipe .pp-reset{flex:none;height:28px;padding:0 4px;border-radius:var(--radius-xs);font:var(--t-body-strong);color:var(--text-3);white-space:nowrap;transition:color var(--dur-1) linear}
.pipe .pp-reset:hover{color:var(--text-strong)}

/* the pipeline tabs: the shared .tabs (its hairline under the whole row), the ink as the tab's own 2 px line; they scroll
   sideways when the screen is narrow */
.pipe .tb .tabs{gap:24px;min-width:0;overflow-x:auto;overflow-y:hidden;scrollbar-width:none}
.pipe .tb .tabs::-webkit-scrollbar{display:none}
.pipe .tb .tab{flex:none;display:inline-flex;align-items:center;gap:6px;height:36px;padding:0}
.pipe .tb .tab .ic{width:14px;height:14px;stroke-width:2;color:var(--icon)}
.pipe .tb .tab.on .ic{color:var(--text-strong)}
.pipe .tb .tab.on::after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;border-radius:1px;background:var(--tab-ink)}
.pipe .tb .tab .n{margin-left:0;font-variant-numeric:tabular-nums}
.pipe .tb .tab:focus-visible{outline:var(--focus-outline);outline-offset:-2px}
/* «Не сделки» sits apart at the right end */
.pipe .tb .pp-pt .tab.pp-non{margin-left:auto;color:var(--text-3)}
.pipe .tb .pp-pt .tab.pp-non.on,.pipe .tb .pp-pt .tab.pp-non:hover{color:var(--text-strong)}
/* list status switch + forecast navigation in the view extras */
.pipe .ls-status .n{font-variant-numeric:tabular-nums}
.pipe .fc-nav{display:flex;align-items:center;gap:8px}
.pipe .fc-range{margin-left:4px;font:var(--t-body-strong);color:var(--text-strong);white-space:nowrap}
.pipe .fc-out{font:var(--t-body);color:var(--text-3);white-space:nowrap}

/* converted from the old viewport queries (§4.6: N − 56, down to a multiple of 20) */
@container view (max-width:1440px){.pipe .fc-range{display:none}}
@container view (max-width:1260px){
  .pipe .seg.pv button span{display:none}
  .pipe .seg.pv button{width:var(--control-h);padding:0}
  .pipe .seg.pv button .ic{width:16px;height:16px;stroke-width:2}
}
@container view (max-width:1120px){.pipe .tb-sum,.pipe .fc-out{display:none}}

/* ── body + view switch animation ── */
.pv-body{position:relative;display:grid;grid-template-rows:minmax(0,1fr);grid-template-columns:minmax(0,1fr);min-height:0;min-width:0}
.pv-body.pv-enter > *{animation:pp-view 220ms var(--ease-out) both}
@keyframes pp-view{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@keyframes pp-fade{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
/* no-results notice: a raised card floating over the lanes, centred in the board (clear of the lanes' dashed boxes);
   centred with the translate property so the entry animation's transform does not shift it */
.pv-none{position:absolute;left:50%;top:50%;z-index:3;translate:-50% -50%;display:flex;align-items:center;gap:12px;padding:8px 8px 8px 12px;
  border-radius:var(--radius-m);background:var(--surface-raised);box-shadow:var(--shadow-3);font:var(--t-body);color:var(--text);white-space:nowrap;animation:pp-fade 200ms var(--ease-out)}
.pv-none > .ic{width:16px;height:16px;color:var(--icon)}

/* ── board / lanes (grey lane + white raised cards, Stripe edit-mode overview) ── */
.pipe .board{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(256px,1fr);gap:12px;padding:0 var(--page-pad) 24px;overflow-x:auto;overflow-y:hidden;min-height:0;scroll-padding-inline:var(--page-pad)}
.pipe .board.is-panning,.pipe .board.is-panning *{cursor:grabbing!important}
.pipe .col{position:relative;display:grid;grid-template-rows:auto minmax(0,1fr);min-height:0;min-width:0;border-radius:var(--radius-m);background:var(--surface-offset);
  transition:background var(--dur-2) var(--ease-out),box-shadow var(--dur-2) var(--ease-out)}
/* header → first card = 8 px in kanban and forecast alike (§6.1: 12 12 8 + 0 8 8, split 4 + 4 so the first card's focus ring is not clipped) */
.pipe .col-h{position:relative;padding:12px 12px 4px;-webkit-user-select:none;user-select:none}
.pipe .col-t{display:flex;align-items:center;gap:8px;min-width:0;height:24px}
.pipe .col-t .stg-ring{margin-right:-2px}
.pipe .col-t b{min-width:0;font:var(--t-body-strong);color:var(--text-strong);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* lane count = neutral .count (§5.10); its fill is one step above the lane (--surface-offset) so it reads in dark too */
.pipe .col-n{flex:none;display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;padding:0 6px;border-radius:999px;
  background:var(--surface-offset-hover);color:var(--badge-neutral-text);box-shadow:inset 0 0 0 1px var(--badge-neutral-border);
  font:var(--t-caption-strong);font-variant-numeric:tabular-nums;transition:color var(--dur-2) var(--ease-out),background var(--dur-2) var(--ease-out),box-shadow var(--dur-2) var(--ease-out)}
/* lane actions: 24×24 ghost icon buttons on the offset surface */
.pipe .col-a{flex:none;width:24px;height:24px;display:grid;place-items:center;border-radius:var(--radius-s);color:var(--icon);opacity:0;
  transition:opacity var(--dur-2) var(--ease-out),background var(--dur-1),color var(--dur-1)}
.pipe .col-t .col-a:first-of-type{margin-left:auto}
.pipe .col-t .col-a + .col-a{margin-left:-4px}
.pipe .col:hover .col-a,.pipe .col-a:focus-visible,.pipe .col-a[aria-expanded="true"]{opacity:1}
.pipe .col-a:hover,.pipe .col-a[aria-expanded="true"]{background:var(--surface-offset-hover);color:var(--text-strong)}
.pipe .col-a .ic{width:16px;height:16px;stroke-width:2}
/* lane sums: 12/16 --text-3, the sum 600 --text-2 */
.pipe .col-s{display:flex;align-items:baseline;gap:4px;min-width:0;margin-top:2px;font:var(--t-caption);color:var(--text-3);font-variant-numeric:tabular-nums;white-space:nowrap}
.pipe .col-s .sum{font-weight:600;color:var(--text-2);transition:color var(--dur-2) var(--ease-out)}
.pipe .col-s .sum.is-zero{font-weight:400;color:var(--text-3)}   /* «AED 0» steps back: an empty lane or a pipeline without sums */
.pipe .col-s .lbl{font:var(--t-caption);color:var(--text-3);cursor:help}
.pipe .col-s .lbl::before{content:"·";margin-right:4px}
/* live drag preview of the target / source lane: the sum in neutral strong text, the count as a soft-tint attention counter (DESIGN-CALM §3.6) */
.pipe .col-s .is-pv{color:var(--text-strong)!important}
.pipe .col-n.is-pv{background:var(--accent-bg-2);color:var(--accent-soft-text);box-shadow:none}
/* drop target: accent wash + a 3 px accent line on top (DESIGN-CALM §3.14, Attio kanban-drag). The line is a straight rounded
   bar inset 8 px (= --radius-m) from the lane edges, as Attio's, so it does not bend round the lane's rounded corners the way
   an inset shadow does; the forecast's current month uses the same bar as a 2 px grey ink */
.pipe .col::after{content:"";position:absolute;top:0;left:8px;right:8px;height:3px;border-radius:0 0 2px 2px;background:var(--accent);opacity:0;pointer-events:none;
  transition:opacity var(--dur-2) var(--ease-out)}
.pipe .col.is-over{background:var(--accent-bg)}
.pipe .col.is-over::after{opacity:1}
/* on the wash the lane count keeps its pill: the neutral count takes the card fill (as the cards on the wash), the preview
   count a tint one step deeper than --accent-bg-2, which in light is the wash itself */
.pipe .col.is-over .col-n{background:var(--surface-card)}
.pipe .col.is-over .col-n.is-pv{background:color-mix(in srgb,var(--accent-bg-2),var(--accent) 10%)}
.pipe .cards{position:relative;display:flex;flex-direction:column;gap:8px;padding:4px 8px 8px;overflow-y:auto;overflow-x:hidden;min-height:0;scrollbar-width:thin;overscroll-behavior:contain}

/* ── deal card (raised card, §5.14) ── */
.dc{position:relative;flex:none;display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:8px;padding:12px;border-radius:var(--radius-m);
  background:var(--surface-card);box-shadow:var(--shadow-1);color:var(--text);cursor:pointer;-webkit-user-select:none;user-select:none;touch-action:manipulation;
  transition:box-shadow var(--dur-1) var(--ease-out)}
/* speed (2026-10-23, «воронка с большим колвом лидов подгружается с дилеем»): a card below the visible part of its column is
   not styled, laid out or painted until it scrolls near (306 partners = 9 700 elements: ~0.25 s a board, and the sidebar
   slide laid them all out). 'auto' keeps each card's last real height, so the column's scroll stays true */
.pipe .cards > .dc{content-visibility:auto;contain-intrinsic-size:auto 66px}   /* the content box of a usual card (90 px with its 12 px padding): a lane drawn anew keeps its height */
/* a card icon not drawn yet (screens/pipe.js lic / lqa) holds the icon's place, so nothing moves when it comes */
.pipe .fc-col .cards > .dc{contain-intrinsic-size:auto 102px}   /* a forecast card carries the close date and the odds: ~126 px */
.dc i.lic{display:inline-block;flex:none;width:12px;height:12px}
.dc-qa i.lic{width:16px;height:16px}
.dc:hover{box-shadow:var(--shadow-hover)}
.dc:focus-visible{outline:0;box-shadow:inset 0 0 0 1px var(--focus-color),var(--shadow-1)}   /* the card's own hairline turns accent (painted over --shadow-1's inset), no second line outside (§3.9) */
.dc-t{grid-column:1;font:var(--t-body-strong);color:var(--text-strong);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.dc-sub{grid-column:1;margin-top:2px;font:var(--t-caption);color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-variant-numeric:tabular-nums}
.dc-ft{grid-column:1/3;display:flex;align-items:center;gap:8px;min-width:0;margin-top:8px;font:var(--t-body)}
.dc-ft .p{font-weight:600;color:var(--text-strong);font-variant-numeric:tabular-nums;white-space:nowrap}
/* no sum: the age of the last message («3 д назад»), a quiet caption with the message glyph */
.dc-ft .dc-lm{display:inline-flex;align-items:center;gap:4px;min-width:0;font:var(--t-caption);color:var(--text-3);white-space:nowrap;font-variant-numeric:tabular-nums}
.dc-ft .dc-lm .ic{flex:none;width:12px;height:12px;color:var(--icon)}
.dc-ft .ch{margin-left:auto;display:grid;color:var(--icon)}
.dc-ft .ch .ic{width:12px;height:12px}
.dc-ft .ch.wa{color:var(--wa)}
/* stale on the stage «12 дн.»: pipe.js renders it only past the stage's reminder days, i.e. the stage is overdue →
   status mark (DESIGN-CALM §3.7): a red clock glyph + neutral 12/16 text, no badge */
.dc-ft .stk{display:inline-flex;align-items:center;gap:4px;height:auto;padding:0;border-radius:0;white-space:nowrap;
  font:var(--t-caption);background:none;color:var(--text-3);box-shadow:none;font-variant-numeric:tabular-nums}
.dc-ft .stk .ic{width:12px;height:12px;stroke-width:2.4;color:var(--danger)}
/* ✦ pipeline / stage / kind set by the AI pilot (the glyph stays text, §6.1 «AI mark») */
.pipe .pp-ai{flex:none;font-size:12px;line-height:1;color:var(--ai-text);cursor:help}
/* the partner who brought the client / a partner's own clients: ppl + a short name, quiet like the age of the last message */
.dc-ft .dc-pt{display:inline-flex;align-items:center;gap:4px;min-width:0;font:var(--t-caption);color:var(--text-2);white-space:nowrap}
.dc-ft .dc-pt > span{overflow:hidden;text-overflow:ellipsis}
.dc-ft .dc-pt .ic{flex:none;width:12px;height:12px;color:var(--icon)}
.dc-ft .pp-ai{margin-left:auto}
.dc-ft .pp-ai + .ch{margin-left:0}
/* unread: Stripe's 6 px blue dot at the top-left */
.dc.is-unread::before{content:"";position:absolute;left:4px;top:8px;width:6px;height:6px;border-radius:50%;background:var(--info)}

/* activity status: a 20 px slot with the glyph only (no tinted circle, DESIGN-CALM §4 G2) — overdue ›, nothing planned ⚠, planned ✓ */
.dc .st{grid-row:1/3;grid-column:2;align-self:start;width:20px;height:20px;border-radius:50%;display:grid;place-items:center;transition:opacity var(--dur-2) var(--ease-out)}
.dc .st .ic{width:12px;height:12px;stroke-width:2.4}
.dc .st.over{background:transparent;color:var(--danger)}
.dc .st.warn{background:transparent;color:var(--text-3)}   /* nothing planned: neutral, so a lane of fresh leads is not a wall of amber; overdue stays red */
.dc .st.ok{background:transparent;color:var(--success)}

/* waiting for a reply: a full-width status-mark row (DESIGN-CALM §3.7): amber clock glyph + neutral text with the live timer */
.dc .wbar{grid-column:1/3;display:flex;align-items:center;gap:4px;min-width:0;height:auto;margin-top:8px;padding:0;border-radius:0;white-space:nowrap;
  font:var(--t-caption-strong);background:none;color:var(--text-2);box-shadow:none}
.dc .wbar .ic{width:12px;height:12px;stroke-width:2.4;flex:none;color:var(--warning)}
.dc .wbar .tm{font-variant-numeric:tabular-nums}
.dc .wbar .tm::before{content:"·";margin-right:4px}
/* … or in the footer, in place of a missing sum (pipe.js waitIn): the same mark, inline, the text clipped first */
.dc .dc-ft .dc-wt{grid-column:auto;min-width:0;margin-top:0}
.dc .dc-ft .dc-wt > span:not(.tm){overflow:hidden;text-overflow:ellipsis}

/* hover quick actions: 24×24 ghost icon buttons on a raised pill, top-right */
.dc-qa{position:absolute;top:8px;right:8px;z-index:2;display:flex;gap:0;padding:2px;border-radius:var(--radius-s);background:var(--surface-card);box-shadow:var(--shadow-1);
  opacity:0;transform:translateX(4px);pointer-events:none;transition:opacity var(--dur-2) var(--ease-out),transform var(--dur-2) var(--ease-out)}
.dc:hover .dc-qa,.dc:focus-within .dc-qa{opacity:1;transform:none;pointer-events:auto;transition-delay:60ms}
.dc:hover .st,.dc:focus-within .st{opacity:0}
.dc-qa button{width:24px;height:24px;display:grid;place-items:center;border-radius:var(--radius-xs);color:var(--icon-strong);transition:background var(--dur-1),color var(--dur-1)}
.dc-qa button:hover,.dc-qa button[aria-expanded="true"]{background:var(--surface-hover);color:var(--text-strong)}
.dc-qa .ic{width:16px;height:16px;stroke-width:2}
body.is-dragging .dc-qa{display:none}

/* new / moved card: accent wash + 1 px accent keyline fading over 1.5 s (ends on the card surface, never a literal white; DESIGN-CALM §3.14) */
.dc.is-new{animation:pp-in 320ms var(--ease-out) both,pp-flash 1500ms var(--ease-out)}
@keyframes pp-in{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
@keyframes pp-flash{0%,25%{background:var(--accent-bg);box-shadow:inset 0 0 0 1px var(--accent),var(--shadow-1)}100%{background:var(--surface-card);box-shadow:inset 0 0 0 1px transparent,var(--shadow-1)}}

/* forecast bits on cards */
.dc .fc-m{grid-column:1/3;display:flex;align-items:center;gap:8px;min-width:0;margin-top:8px;font:var(--t-caption);color:var(--text-3)}
.dc .fc-m .lbl{min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font:var(--t-caption);color:var(--text-3)}
.dc .fc-d{margin-left:auto;flex:none;font:var(--t-caption);color:var(--text-3);font-variant-numeric:tabular-nums;white-space:nowrap}
.dc .fc-d.red{color:var(--danger);font-weight:400}   /* late date: muted red text, no extra weight (as the overdue task date, DESIGN-CALM §4 G6) */
.dc .fc-p{grid-column:1/3;display:block;height:4px;margin-top:8px;border-radius:2px;background:var(--border-soft);overflow:hidden}
.dc .fc-p b{display:block;height:100%;border-radius:2px;background:var(--meter);transition:width var(--dur-5) var(--ease-out)}   /* neutral meter (DESIGN-CALM §3.14) */

/* add row (ghost action revealed on lane hover, DESIGN-CALM §3.10 «+ Добавить …»: --text-3, icon --icon, hover --text-strong) + empty lane (dashed box, §5.24) */
.pipe .addc{flex:none;display:flex;align-items:center;gap:4px;height:28px;padding:0 12px;border-radius:var(--radius-s);font:var(--t-body-strong);color:var(--text-3);opacity:0;
  transition:opacity var(--dur-2) var(--ease-out),background var(--dur-1),color var(--dur-1)}
.pipe .col:hover .addc,.pipe .addc:focus-visible{opacity:1}
.pipe .addc:hover{background:var(--surface-offset-hover);color:var(--text-strong)}
.pipe .addc .ic{width:12px;height:12px;stroke-width:2.4;color:var(--icon);transition:color var(--dur-1)}
.pipe .addc:hover .ic{color:var(--text-strong)}
/* empty lane (Attio / Pipedrive): no dashed box, «+ Сделка» stays visible at the top; while dragging the lane's wash and the
   placeholder show the drop. .col-empty is only the drop anchor */
.pipe .col-empty{display:none}
.pipe .cards.is-empty > .addc{opacity:1}
body.is-dragging .pipe .addc{visibility:hidden}

/* ── drag & drop ── */
.dc.is-src{display:none}
.dc-ph{flex:none;border:1px dashed var(--border);border-radius:var(--radius-m);background:transparent}
.drag-ghost{position:fixed;left:0;top:0;z-index:80;pointer-events:none;will-change:transform}
.drag-ghost > .dc{transform-origin:50% 40%;transition:transform var(--dur-2) var(--ease-out),box-shadow var(--dur-2) var(--ease-out),opacity 200ms var(--ease-in)}
.drag-ghost > .dc.is-lifted{transform:rotate(1deg) scale(1.02);box-shadow:var(--shadow-3)}
.drag-ghost > .dc.is-lifted.over-zone{transform:rotate(0deg) scale(.96);opacity:.92}
.drag-ghost.is-settling{transition:transform 220ms var(--ease-out)}
.drag-ghost.is-settling > .dc{transition-duration:220ms}
.drag-ghost.is-into{transition:transform 200ms var(--ease-in)}
.drag-ghost.is-into > .dc{transform:scale(.8);opacity:0;transition:transform 200ms var(--ease-in),opacity 200ms var(--ease-in)}

/* bottom drop bar: slides up while dragging */
.dz{position:absolute;left:0;right:0;bottom:0;z-index:20;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;height:64px;padding:8px var(--page-pad) 12px;
  border-radius:var(--radius-m) var(--radius-m) 0 0;background:var(--surface-raised);box-shadow:var(--shadow-3);
  transform:translateY(calc(100% + 40px));pointer-events:none;transition:transform 140ms var(--ease-in)}
/* «Партнёры»: no «Выиграна» (the goal is the stage «Создали кабинет»), so two zones */
.pipe[data-pipe="partners"] .dz{grid-template-columns:repeat(2,minmax(0,1fr))}
.pipe[data-pipe="partners"] .dz-z.won{display:none}
.pipe.is-dragging .dz{transform:none;pointer-events:auto;transition:transform 180ms var(--ease-out)}
/* «Отказались»: we wrote first after the refusal */
.ls-wf{display:inline-flex;align-items:center;gap:4px;margin-left:8px;font:var(--t-caption);font-weight:600;color:var(--badge-danger-text);white-space:nowrap}
.ls-wf .ic{width:12px;height:12px;color:var(--danger)}
.dz-z{display:flex;align-items:center;justify-content:center;gap:8px;border:1px dashed var(--border);border-radius:var(--radius-m);background:transparent;
  font:var(--t-body-strong);color:var(--text-2);
  transition:background var(--dur-2) var(--ease-out),color var(--dur-2) var(--ease-out),border-color var(--dur-2) var(--ease-out)}
.dz-z .ic{width:16px;height:16px}
/* the dashed keyline is the midpoint of the badge border and the status colour: ≈ 3:1 on --surface-raised in both themes
   (the dark badge borders alone are ≈ 1.3:1, so the zones lost their box) */
.dz-z.lost{border-color:color-mix(in srgb,var(--badge-danger-border),var(--danger));color:var(--badge-danger-text)}
.dz-z.won{border-color:color-mix(in srgb,var(--badge-success-border),var(--success));color:var(--badge-success-text)}
/* «Удалить» = the same recipe with the neutral pair (grey tag border + --icon): ≈ 2.3:1 light / 2.9:1 dark, beside 2.5 / 3 for
   the two status zones; the hot state keeps that keyline (solid) as they do */
.dz-z.del{border-color:color-mix(in srgb,var(--badge-neutral-border),var(--icon))}
.dz-z.is-hot{border-style:solid}
.dz-z.del.is-hot{background:var(--surface-hover-raised);color:var(--text-strong)}
.dz-z.lost.is-hot{background:var(--badge-danger-bg)}
.dz-z.won.is-hot{background:var(--badge-success-bg)}

/* ── forecast lanes ── */
/* current month: a 2 px grey ink on top, as the active tab (DESIGN-CALM §3.2), drawn with the lane's straight bar (.col::after);
   as a drop target it takes the accent drop look (the 3 px accent bar on the wash) */
.pipe .fc-col.is-cur::after{height:2px;background:var(--tab-ink);opacity:1}
.pipe .fc-col.is-cur.is-over::after{height:3px;background:var(--accent)}
.pipe .fc-now{flex:none;display:inline-flex;align-items:center;height:20px;padding:0 6px;border-radius:var(--radius-xs);font:var(--t-caption-strong);
  background:var(--badge-info-bg);color:var(--badge-info-text);box-shadow:inset 0 0 0 1px var(--badge-info-border)}
.pipe .fc-w{display:flex;align-items:baseline;justify-content:space-between;gap:8px;margin-top:2px;font:var(--t-caption);color:var(--text-3)}
.pipe .fc-w b{font-weight:600;color:var(--text-2);font-variant-numeric:tabular-nums}
/* won in the month: status mark (DESIGN-CALM §3.7) — green glyph, neutral text */
.pipe .fc-won{display:flex;align-items:center;gap:4px;margin-top:4px;font:var(--t-caption-strong);color:var(--text-2);font-variant-numeric:tabular-nums}
.pipe .fc-won .ic{width:12px;height:12px;stroke-width:2.4;color:var(--success)}

/* ── list view: the Stripe table (§5.12) with two-line rows of 56 ── */
.pipe .lst{overflow:auto;min-height:0;padding:0 var(--page-pad) 24px;scrollbar-width:thin}
/* a sticky bottom footer sticks to the scroller's padding edge: no bottom padding, so it sits flush with the list's bottom */
.pipe .lst:has(> .lt > tfoot){padding-bottom:0}
.pipe .lt{width:100%;min-width:1120px;border-collapse:separate;border-spacing:0;font:var(--t-body);color:var(--text-2)}
.pipe .lt th{position:sticky;top:0;z-index:2;height:var(--row-h);padding:0 6px;background:var(--bg);text-align:left;white-space:nowrap;
  font:var(--t-caption-strong);color:var(--text-strong);box-shadow:inset 0 1px 0 var(--border),inset 0 -1px 0 var(--border-soft);
  cursor:pointer;-webkit-user-select:none;user-select:none}
.pipe .lt th.num{text-align:right}
/* sort: stacked 6×8 chevrons 6 px after the label; the active sort keeps one chevron in --text-strong */
.pipe .lt th .srt{display:inline-block;width:6px;height:8px;margin-left:6px;vertical-align:0;color:var(--text-3);stroke-width:1.25}
.pipe .lt th:hover .srt{color:var(--text-2)}
.pipe .lt th[aria-sort="ascending"] .srt{color:var(--text-strong);clip-path:inset(0 0 50% 0);transform:translateY(2px)}
.pipe .lt th[aria-sort="descending"] .srt{color:var(--text-strong);clip-path:inset(50% 0 0 0);transform:translateY(-2px)}
.pipe .lt th:focus-visible{outline:var(--focus-outline);outline-offset:-1px}
.pipe .lt th.c-qa{cursor:default}
.pipe .lt .num{text-align:right;font-variant-numeric:tabular-nums}
.pipe .lt td{height:var(--row-h-2);padding:0 6px;border-bottom:1px solid var(--border-soft);white-space:nowrap;vertical-align:middle;background:var(--surface);
  transition:background var(--dur-1) var(--ease-out)}
.pipe .lt tbody:last-of-type tr:last-child td{border-bottom-color:var(--border)}
.pipe .lt tbody:not(:last-of-type) tr:last-child td{border-bottom-color:transparent}   /* «Не сделки»: the next group row draws the rule */
.pipe .lt:has(tfoot) tbody tr:last-child td{border-bottom-color:transparent}
.pipe .lt td.num{font-weight:600;color:var(--text-strong)}
.pipe .lt td.num .muted{font-weight:400}
.pipe .lt .empty-v{color:var(--text-3)}   /* «—» (§5.12): an empty value is information, so --text-3 like the shared .tbl .empty-v (5.07 / 6.22); --text-disabled stays for disabled controls */
.pipe .lt tr.row{cursor:pointer}
.pipe .lt tr.row:hover td{background:var(--surface-hover)}
.pipe .lt tr.row:focus-visible{outline:var(--focus-outline);outline-offset:-1px;box-shadow:none}
/* the TR outline is painted under the sticky actions cell (z-index 1): that cell redraws the 1 px ring (top inset, right inset,
   and its bottom border in the ring colour so that edge stays 1 px) and keeps the two gutter masks, as .tbl td.row-act (§3.9) */
.pipe .lt tr.row:focus-visible > td.c-qa{border-bottom-color:var(--focus-color);
  box-shadow:inset 0 1px 0 var(--focus-color),inset -1px 0 0 var(--focus-color),36px 0 0 var(--bg),var(--page-pad) 0 0 var(--bg)}
.pipe .lt tr.row.is-new td{animation:pp-rowflash 1500ms var(--ease-out)}
@keyframes pp-rowflash{0%,25%{background:var(--accent-bg);box-shadow:inset 0 1px 0 var(--accent),inset 0 -1px 0 var(--accent)}100%{background:var(--surface);box-shadow:inset 0 1px 0 transparent,inset 0 -1px 0 transparent}}
/* the sticky actions cell flashes with its two gutter masks kept, so the right gutter never shows the table during the flash */
.pipe .lt tr.row.is-new td.c-qa{animation-name:pp-rowflash-qa}
@keyframes pp-rowflash-qa{0%,25%{background:var(--accent-bg);box-shadow:inset 0 1px 0 var(--accent),inset 0 -1px 0 var(--accent),36px 0 0 var(--bg),var(--page-pad) 0 0 var(--bg)}100%{background:var(--surface);box-shadow:inset 0 1px 0 transparent,inset 0 -1px 0 transparent,36px 0 0 var(--bg),var(--page-pad) 0 0 var(--bg)}}
.pipe .lt .c-title{min-width:210px;max-width:250px}
.pipe .lt .ttl{display:flex;align-items:center;gap:8px;min-width:0;max-width:250px}
.pipe .lt .ttl b{font-weight:600;color:var(--text-strong);overflow:hidden;text-overflow:ellipsis}
.pipe .lt .udot{flex:none;width:6px;height:6px;border-radius:50%;background:var(--info)}
/* stage cell: the 7-segment 3 px stage bar + the stage name */
.pipe .ls-st{display:flex;align-items:center;gap:8px;min-width:0;color:var(--text-2)}
.pipe .ls-bars{display:flex;gap:2px;flex:none}
.pipe .ls-bars i{width:7px;height:3px;border-radius:1px;background:var(--step-future)}
.pipe .ls-bars i.p{background:var(--step-done)}
.pipe .ls-bars i.c{background:var(--step-current)}
/* won / lost: the badge, and the lost reason as the cell's second line (12/16 --text-3), so the column keeps its open-view width */
.pipe .ls-st:has(> .ls-why){flex-direction:column;align-items:flex-start;justify-content:center;gap:2px}
.pipe .ls-why{min-width:0;max-width:180px;overflow:hidden;text-overflow:ellipsis;font:var(--t-caption);color:var(--text-3)}
.pipe .lt .c-cl{min-width:160px;max-width:200px}
.pipe .lt .c2{display:grid;min-width:0;max-width:200px;color:var(--text)}
.pipe .lt .c2 > span,.pipe .lt .c2 small{overflow:hidden;text-overflow:ellipsis}
.pipe .lt .c2 small{font:var(--t-caption);color:var(--text-3);font-variant-numeric:tabular-nums}
.pipe .lt .own{display:inline-flex;align-items:center;gap:8px;color:var(--text)}
.pipe .lt .c-last{min-width:220px;max-width:270px}
.pipe .lt .lm{display:flex;align-items:center;gap:8px;min-width:0;max-width:270px}
.pipe .lt .lm .ic{color:var(--icon)}
.pipe .lt .lm .ic.wa{color:var(--wa)}
.pipe .lt .lm-t{min-width:0;overflow:hidden;text-overflow:ellipsis;color:var(--text-2)}
.pipe .lt .lm-d{margin-left:auto;padding-left:8px;flex:none;font:var(--t-caption);color:var(--text-3);font-variant-numeric:tabular-nums}
/* «Ждёт ответа» cell: status mark (DESIGN-CALM §3.7): amber clock glyph + neutral live timer, no badge */
.pipe .lt .lw{display:inline-flex;align-items:center;gap:4px;height:auto;padding:0;border-radius:0;white-space:nowrap;
  font:var(--t-caption-strong);background:none;color:var(--text-2);box-shadow:none;font-variant-numeric:tabular-nums}
.pipe .lt .lw .ic{width:12px;height:12px;stroke-width:2.4;color:var(--warning)}
/* sticky actions column (§5.12): 36 wide, sticky right:0 at the content edge, one 24×24 ghost «…» (Написать / Задача stay in
   that menu and on the cards); the 10 px fade shows while columns scroll under it. Two flat --bg shadows mask the 40 px right
   gutter beside every header / row / footer cell, so a table wider than the view never shows in the gutter */
.pipe .lt .c-qa{position:sticky;right:0;z-index:1;width:36px;min-width:36px;padding:0 6px;text-align:right;
  box-shadow:36px 0 0 var(--bg),var(--page-pad) 0 0 var(--bg)}
.pipe .lt th.c-qa{z-index:3;box-shadow:inset 0 1px 0 var(--border),inset 0 -1px 0 var(--border-soft),36px 0 0 var(--bg),var(--page-pad) 0 0 var(--bg)}
.pipe .lt tfoot td.c-qa{z-index:3;box-shadow:inset 0 1px 0 var(--border),36px 0 0 var(--bg),var(--page-pad) 0 0 var(--bg)}
.pipe .lt .c-qa::before{content:"";position:absolute;top:0;bottom:0;left:-10px;width:10px;background:linear-gradient(to left,var(--fade-shadow),transparent);opacity:0;pointer-events:none;transition:opacity var(--dur-1)}
.pipe .lst.is-scrolled .lt .c-qa::before{opacity:1}
.pipe .lt .qa{display:inline-flex;vertical-align:middle;opacity:0;pointer-events:none;transition:opacity var(--dur-1)}
.pipe .lt .qa [data-qa="write"],.pipe .lt .qa [data-qa="task"]{display:none}
.pipe .lt tr.row:is(:hover,:focus-within,:focus-visible) .qa,.pipe .lt .qa:has([aria-expanded="true"]){opacity:1;pointer-events:auto}
.pipe .lt .qa button{width:24px;height:24px;display:grid;place-items:center;border-radius:var(--radius-xs);color:var(--icon-strong);transition:background var(--dur-1),color var(--dur-1)}
.pipe .lt .qa button:hover,.pipe .lt .qa button[aria-expanded="true"]{background:var(--surface-hover)}
/* on a hovered row (already --surface-hover) the button's own hover steps to the offset-hover fill so it stays visible [E, as .tbl .row-act] */
.pipe .lt tr.row:hover .qa button:is(:hover,[aria-expanded="true"]){background:var(--surface-offset-hover)}
.pipe .lt .qa .ic{width:16px;height:16px;stroke-width:2;color:var(--icon-strong)}
/* totals footer (§5.12): 36 px, rule on top, labels --text-3, numbers 600 --text-strong */
.pipe .lt tfoot td{position:sticky;bottom:0;z-index:2;height:var(--row-h);background:var(--bg);border-bottom:0;box-shadow:inset 0 1px 0 var(--border);
  font:var(--t-body);color:var(--text-3);font-variant-numeric:tabular-nums}
.pipe .lt tfoot b{font-weight:600;color:var(--text-strong)}
.pipe .lt tfoot .muted{color:var(--text-3)}

/* ── «Не сделки»: one table, a group header row per contact kind ── */
.pipe .pnd-note{display:flex;align-items:center;gap:8px;margin:0 0 12px;font:var(--t-body);color:var(--text-3)}
.pipe .pnd-note .ic{width:12px;height:12px;stroke-width:2.4;color:var(--ai-text)}
.pipe .lt.pnd-t{min-width:0;table-layout:fixed}
.pipe .pnd-t .w-cl{width:22%}
.pipe .pnd-t .w-last{width:28%}
.pipe .pnd-t .w-yes{width:148px}
.pipe .pnd-t td{overflow:hidden}
.pipe .lt.pnd-t .c-cl,.pipe .lt.pnd-t .c-last{min-width:0;max-width:none}
.pipe .lt.pnd-t .c2,.pipe .lt.pnd-t .lm{max-width:100%}
.pipe .pnd-t .pnd-n{display:flex;align-items:center;gap:8px;min-width:0}
.pipe .pnd-t .pnd-n b{min-width:0;font-weight:600;color:var(--text-strong);overflow:hidden;text-overflow:ellipsis}
.pipe .pnd-gh td{position:sticky;top:0;z-index:2;height:var(--row-h);padding:0 12px;background:var(--surface-offset);border-bottom:0;
  box-shadow:inset 0 1px 0 var(--border-soft),inset 0 -1px 0 var(--border-soft);vertical-align:middle;cursor:default}
.pipe .pnd-g:first-of-type .pnd-gh td{box-shadow:inset 0 1px 0 var(--border),inset 0 -1px 0 var(--border-soft)}
.pipe .pnd-gt{display:flex;align-items:center;gap:8px;min-width:0}
.pipe .pnd-gt b{font:var(--t-body-strong);color:var(--text-strong)}
.pipe .pnd-gt .muted{min-width:0;overflow:hidden;text-overflow:ellipsis;font:var(--t-body);color:var(--text-3)}
/* first line of the AI summary: 12/16 --text-3 with ✦ in --ai-text */
.pipe .pnd-sm{display:flex;align-items:center;gap:8px;   /* one ✦ per row: the kind mark by the name; the summary is plain text */
  min-width:0;font:var(--t-caption);color:var(--text-3)}
.pipe .pnd-sm .t{min-width:0;overflow:hidden;text-overflow:ellipsis}
.pipe .pnd-t .c-yes{text-align:right}
.pipe .lt .ttl .pp-ai{margin-left:-2px}

/* ── «Что добавить» 3 and 4 (2026-10-23, DESIGN-CALM §23) ── */
/* «ждём клиента · 2» under a card's footer (pastel purple badge, the tooltip names the items) */
.dc .dc-wf{grid-column:1/3;display:flex;min-width:0;margin-top:8px}
.dc .dc-wf .badge{cursor:help}
/* «ИИ: Договор?» beside it (DESIGN-CALM §26): an AI tag = the neutral tag, the ✦ in --ai-text (§3.7); a long stage name clips */
.dc .dc-wf{flex-wrap:wrap;gap:4px}
.dc .dc-sg{min-width:0;max-width:100%}
.dc .dc-sg > span{min-width:0;overflow:hidden;text-overflow:ellipsis}
.dc .dc-sg i{flex:none;font-style:normal;font-size:12px;line-height:1;color:var(--ai-text)}
/* «Список»: a checkbox column (the «Клиенты» box, list blue), the ticked rows on the selected grey */
.pipe .lt .c-ck{width:36px;min-width:36px;padding:0 0 0 12px}
.pipe .lt td.c-ck{cursor:default}
.pipe .lt .c-ck .cl-cb{opacity:0;transition:opacity var(--dur-2) var(--ease-out),box-shadow var(--dur-1)}
.pipe .lt tr.row:hover .c-ck .cl-cb,.pipe .lt .c-ck .cl-cb:focus-visible,.pipe .lt .c-ck .cl-cb[aria-checked="true"],.pipe .lt.has-sel .c-ck .cl-cb,.pipe .lt th.c-ck .cl-cb{opacity:1}
.pipe .lt tr.row.sel td{background:var(--row-selected)}
.pipe .lt tr.row.sel:hover td{background:var(--row-selected-hover)}
/* the bulk bar (as on «Клиенты», §5.13): replaces «Все / Мои», «Фильтр» and the sum while rows are ticked */
.pipe .pp-bulk{display:flex;align-items:center;flex-wrap:wrap;gap:8px;min-height:var(--control-h);animation:pp-bulk-in var(--dur-2) var(--ease-out)}
@keyframes pp-bulk-in{from{opacity:0;transform:translateY(2px)}to{opacity:1;transform:none}}
.pipe .pp-bulk .pill{display:inline-flex;align-items:center;margin-right:4px;font:var(--t-body);color:var(--text-2);white-space:nowrap;font-variant-numeric:tabular-nums}
.pipe .pp-bulk .pill b{font-weight:600;color:var(--text-strong)}
.pipe .pp-bulk .pill .w::after{content:"";display:inline-block;width:1px;height:20px;margin:0 12px;vertical-align:middle;background:var(--border)}
.pipe .pp-bulk .pill button{height:24px;padding:0 2px;border-radius:var(--radius-xs);font:var(--t-body-strong);color:var(--text-strong);white-space:nowrap;text-decoration:underline dashed var(--text-3);text-underline-offset:3px;transition:text-decoration-color var(--dur-1)}
.pipe .pp-bulk .pill button:hover{text-decoration-color:var(--text-strong)}

/* hand-off from «Отчёты»: the stage that was clicked in the funnel flashes once */
.pipe .col.is-hint{animation:pp-colhint 600ms var(--ease-out)}
@keyframes pp-colhint{0%,40%{background:var(--accent-bg)}100%{background:var(--surface-offset)}}

/* the list keeps min-width 1120 (§4.6); on narrower views only the text columns get tighter (was @media max-width:1400px) */
@container view (max-width:1340px){
  .pipe .lt .c-title{min-width:180px;max-width:210px}
  .pipe .lt .ttl{max-width:210px}
  .pipe .lt .c-cl{min-width:140px;max-width:170px}
  .pipe .lt .c2{max-width:170px}
  .pipe .lt .c-last{min-width:170px;max-width:200px}
  .pipe .lt .lm{max-width:200px}
}

@media (prefers-reduced-motion: reduce){
  .drag-ghost > .dc,.drag-ghost > .dc.is-lifted,.drag-ghost.is-into > .dc{transform:none!important}
  .dc-qa{transform:none!important}
  .dc.is-new{animation:pp-flash 1ms}
  .pipe .fcount{animation:none}
  .dz{transition:opacity 100ms linear}
  .pipe.is-dragging .dz{transform:none}
  .dz{transform:none;opacity:0}
  .pipe.is-dragging .dz{opacity:1}
  .pipe .col.is-hint{animation:none}
  .pipe .col.is-hint::after{opacity:1}
  .pipe .pp-bulk{animation:none}
}
