/* A5 CRM — assistant.css: the top bar's «ИИ-помощник» chat (js/assistant.js). DESIGN-STRIPE.md §6.10, colours = tokens only.
   Every class is prefixed asst- (the top-bar button owns .ai, the deal page .aix-* / .aic-* / .as-*, the pilot screen .aip-*).
   Stripe's 320 px app drawer: docked under the top bar next to the page header and the view. From 1440 px up it pushes
   them (html.asst-on gives .main a second column, the top bar spans both); below it overlays the view with --shadow-3
   (and slides out while a board card is dragged). The top-bar button's open look lives in base.css (G1, §4.3).
   AI = the muted violet ✦ glyph and the --ai-* tint (DESIGN-CALM §3.13), prompt box = Sigma's (--shadow-prompt) with the
   1 px accent keyline on focus, working = the grey working pill, deal names = record links (§3.10). */

/* ── layout (§6.10 exact grid: rows 1 top bar, 2 .phead, 3 #view) ── */
html.asst-on .main{grid-template-columns:minmax(0,1fr) var(--asst-w)}          /* ≥1440 pushes; 320 */
html.asst-on .main > .top{grid-column:1 / -1;grid-row:1}
html.asst-on .main > .top > .wrap{max-width:none}                                /* the search starts at the gutter, as the page below it */
html.asst-on .main > .phead{grid-column:1;grid-row:2}
html.asst-on .main > #view{grid-column:1;grid-row:3}
.asst{position:relative;grid-column:2;grid-row:2 / 4;display:flex;flex-direction:column;min-width:0;min-height:0;background:var(--bg);color:var(--text);box-shadow:inset 1px 0 0 var(--border-soft)}
.asst.in{animation:asst-in var(--dur-4) var(--ease-out)}
@keyframes asst-in{from{opacity:0;transform:translateX(12px)}to{opacity:1;transform:none}}
@media (max-width:1439px){
  html.asst-on .main{grid-template-columns:minmax(0,1fr)}
  .asst{position:fixed;top:var(--topbar-h);right:0;bottom:0;width:min(var(--asst-w),100vw);z-index:25;box-shadow:var(--shadow-3);transition:transform 180ms var(--ease-out)}
  /* a board drag (screens/pipe.js sets body.is-dragging) needs the drop bar under the panel: it slides out and lets the
     pointer through (the drag hit-tests with elementFromPoint) until the card is dropped */
  body.is-dragging .asst{transform:translateX(calc(100% + 24px));pointer-events:none}
}

/* ── header: 38 px, spark + title, model tag, 24×24 ghost icon buttons ── */
.asst-h{flex:none;display:flex;align-items:center;gap:8px;height:38px;padding:0 16px;box-shadow:inset 0 -1px 0 var(--border-soft)}
.asst-t{display:flex;align-items:center;gap:8px;min-width:0;margin:0;font:var(--t-body-strong);color:var(--text-strong);white-space:nowrap}
.asst-t .ic{width:16px;height:16px;stroke-width:2;color:var(--ai-text)}
.asst-tag{display:inline-block;height:20px;padding:0 6px;border-radius:var(--radius-xs);font:var(--t-mono);line-height:20px;white-space:nowrap;cursor:default;
  background:var(--badge-neutral-bg);color:var(--badge-neutral-text);box-shadow:inset 0 0 0 1px var(--badge-neutral-border)}
.asst-sp0{flex:1}
.asst-hb{position:relative;flex:none;width:24px;height:24px;display:grid;place-items:center;padding:0;border-radius:var(--radius-s);color:var(--icon-strong);transition:background var(--dur-1),color var(--dur-1)}
.asst-hb + .asst-hb{margin-left:-4px}
.asst-hb:hover{background:var(--surface-hover);color:var(--text-strong)}
.asst-hb[disabled]{opacity:.5;pointer-events:none}
.asst-hb .ic{width:16px;height:16px;stroke-width:2}
/* «Новый чат» is an icon button; its label stays for screen readers (the tooltip shows «Начать новый чат») */
.asst-hb > span{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ── conversation ── */
.asst-log{flex:1 1 auto;display:flex;flex-direction:column;gap:16px;min-height:0;overflow:auto;overscroll-behavior:contain;padding:16px}
.asst-log:focus,.asst-log:focus-visible{outline:0;box-shadow:none}
.asst-m{display:flex;gap:8px;min-width:0;animation:asst-pop 180ms var(--ease-out)}
.asst-m.u{justify-content:flex-end}
.asst-b{max-width:86%;padding:8px 12px;border-radius:var(--radius-l);background:var(--surface-offset);font:var(--t-body);color:var(--text);overflow-wrap:anywhere}
/* AI avatar (§5.23): 20 px circle, --ai-bg with an --ai-border ring, ✦ in --ai-text */
.asst-av,.asst-sp{flex:none;width:20px;height:20px;display:grid;place-items:center;margin-top:1px;border-radius:50%;
  background:var(--ai-bg);box-shadow:inset 0 0 0 1px var(--ai-border);color:var(--ai-text);font-size:11px;line-height:1}
.asst-tx{flex:1;min-width:0;font:400 14px/22px var(--font-sans);color:var(--text);overflow-wrap:anywhere}
.asst-tx p{margin:0 0 8px}
.asst-tx ul,.asst-tx ol{margin:0 0 8px;padding-left:20px}
.asst-tx > :last-child{margin-bottom:0}
.asst-tx li{margin:2px 0;padding-left:2px}
.asst-tx li::marker{color:var(--text-3)}
.asst-tx b{font-weight:600;color:var(--text-strong)}
.asst-tx code{padding:0 4px;border-radius:var(--radius-xs);background:var(--surface-offset);font:var(--t-mono);color:var(--text-strong)}
.asst-tx .asst-hd{font-weight:600;color:var(--text-strong)}
/* a deal name = record link (DESIGN-CALM §3.10): near-black text with a light 1 px underline, never accent */
.asst-ln{font-weight:600;color:var(--text-strong);text-decoration:underline;text-decoration-color:var(--border-strong);text-decoration-thickness:1px;text-underline-offset:3px;transition:text-decoration-color var(--dur-1)}
.asst-ln:hover{text-decoration-color:var(--text-3)}
.asst-gone{color:var(--text-3);text-decoration:line-through}
@keyframes asst-pop{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}

/* steps of a turn: live list while working, then folded into «N шагов» */
.asst-sd{margin:-8px 0 0 28px}
.asst-sd summary{display:inline-flex;align-items:center;gap:4px;padding:2px 0;cursor:pointer;list-style:none;border-radius:var(--radius-xs);
  font:var(--t-caption-strong);color:var(--text-3);transition:color var(--dur-1)}
.asst-sd summary::-webkit-details-marker{display:none}
.asst-sd summary:hover{color:var(--text-strong)}
.asst-sd summary .ic{width:12px;height:12px;stroke-width:2.4;color:var(--ai-text)}
.asst-sd summary::after{content:"";width:5px;height:5px;margin:0 0 3px 4px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(45deg);transition:transform var(--dur-2) var(--ease-out)}
.asst-sd[open] summary::after{margin:3px 0 0 4px;transform:rotate(-135deg)}
.asst-steps{display:grid;gap:4px;margin:4px 0 0;padding:0;list-style:none}
.asst-steps.live{margin:-8px 0 0 28px}
.asst-steps.live li{animation:asst-pop 180ms var(--ease-out)}
.asst-steps li{display:flex;align-items:baseline;gap:6px;min-width:0;font:var(--t-caption);color:var(--text-2)}
.asst-steps li .ic{width:12px;height:12px;align-self:center;flex:none;color:var(--success);stroke-width:2.4}
/* a failed step: the ✗ and its «ошибка: …» sum in --danger, the label stays --text-2 (DESIGN-CALM §1.6: the colour lives in the glyph) */
.asst-steps li.err .ic,.asst-steps li.err .s{color:var(--danger)}
.asst-steps .l{min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.asst-steps .s{flex:none;margin-left:auto;color:var(--text-3);font-variant-numeric:tabular-nums}

/* working: the AI avatar + the working pill «Думаю…» (DESIGN-CALM §3.13: grey pressed fill, grey spinner) */
.asst-work{display:flex;align-items:center;gap:8px}
.asst-wt{display:inline-flex;align-items:center;gap:6px;height:24px;padding:0 10px;border-radius:999px;background:var(--surface-pressed);color:var(--text-strong);box-shadow:none;font:600 12px/16px var(--font-sans);white-space:nowrap}
.asst-wt::after{content:"";width:12px;height:12px;flex:none;box-sizing:border-box;border:2px solid var(--border-strong);border-top-color:var(--text-2);border-radius:50%;animation:ui-spin .8s linear infinite}

.asst-note{align-self:center;font:var(--t-caption);color:var(--text-3);text-align:center}
/* errors = critical banner (+ «Повторить» below as a secondary .btn.sm) */
.asst-err{display:flex;align-items:flex-start;gap:8px;padding:12px 16px;border:1px solid var(--banner-critical-border);border-radius:var(--radius-s);
  background:var(--banner-critical-bg);font:var(--t-body);color:var(--badge-danger-text);overflow-wrap:anywhere}
.asst-err .ic{width:16px;height:16px;margin-top:2px;flex:none;color:currentColor}
.asst-retry{display:flex;margin-top:-8px}

/* ── confirmation card: bordered, r8; pending = the AI tint ── */
.asst-cf{border-radius:var(--radius-m);background:var(--surface);box-shadow:inset 0 0 0 1px var(--border);animation:asst-pop 180ms var(--ease-out)}
.asst-cf.pending{background:var(--ai-bg);box-shadow:inset 0 0 0 1px var(--ai-border)}
.asst-cf-h{display:flex;align-items:center;gap:6px;padding:12px 12px 4px;font:var(--t-caption-strong);color:var(--text-2)}
.asst-cf-h .ic{width:12px;height:12px;stroke-width:2.4;color:var(--ai-text)}
.asst-cf-l{display:grid;margin:0;padding:0 4px;list-style:none}
.asst-cf-r{display:flex;align-items:flex-start;gap:8px;min-height:36px;padding:8px;border-radius:var(--radius-s)}
label.asst-cf-r{cursor:pointer;transition:background var(--dur-1)}
label.asst-cf-r:hover{background:var(--surface)}
.asst-cf-i.bad label.asst-cf-r{cursor:default}
.asst-cf-i.bad label.asst-cf-r:hover{background:transparent}
.asst-cb{margin-top:2px}
.asst-mk{flex:none;width:16px;height:16px;display:grid;place-items:center;margin-top:2px;font:var(--t-caption);color:var(--text-3)}
.asst-mk .ic{width:12px;height:12px;stroke-width:2.4}
.asst-cf-i.done .asst-mk{color:var(--success)}
.asst-cf-i.err .asst-mk{color:var(--danger)}
.asst-cf-b{flex:1;display:grid;gap:2px;min-width:0}
.asst-cf-t{font:var(--t-body);color:var(--text);overflow-wrap:anywhere}
.asst-cf-d{min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font:var(--t-caption);color:var(--text-3)}
.asst-cf-n{font:var(--t-caption);color:var(--text-3)}
.asst-cf-n.bad{color:var(--danger)}
.asst-cf-i:is(.bad,.skip,.undone) .asst-cf-t{color:var(--text-3)}
.asst-cf-i.undone .asst-cf-t{text-decoration:line-through}
/* a failed action: the title stays --text; only the ✗ (.asst-mk) and the one «Ошибка: …» note are --danger */
.asst-cf-i.done .asst-cf-n{color:var(--success)}
.asst-q{margin:4px 0 2px;max-height:150px;overflow:auto;padding:0 0 0 10px;border-left:2px solid var(--border);font:var(--t-body);color:var(--text-2);overflow-wrap:anywhere}
.asst-cf-f{display:flex;align-items:center;flex-wrap:wrap;gap:8px;padding:8px 12px 12px;box-shadow:inset 0 1px 0 var(--border-soft)}
.asst-cf.pending .asst-cf-f{box-shadow:inset 0 1px 0 var(--ai-border)}
/* the count inside the primary button: a keyline chip on the accent (§5.2) */
.asst-cf-c{display:inline-grid;place-items:center;min-width:16px;height:16px;margin-left:2px;padding:0 4px;border-radius:var(--radius-xs);
  background:transparent;box-shadow:inset 0 0 0 1px var(--kbd-on-accent-ring);color:var(--on-accent);font:600 11px/16px var(--font-sans);font-variant-numeric:tabular-nums}
.asst-cf-s{margin-right:auto;font:var(--t-caption);color:var(--text-3)}
/* quiet footer actions («Отмена», «Отменить») = the secondary button, as Stripe's dialog and card footers (§5.2 «Who uses what») */
.asst-cf-f .btn.q{background:var(--btn-bg);color:var(--btn-text);box-shadow:var(--shadow-control),0 0 0 1px var(--border)}
.asst-cf-f .btn.q:hover{background:var(--btn-bg-hover);box-shadow:var(--shadow-control),0 0 0 1px var(--border-strong)}
.asst-cf-f .btn.q:active{background:var(--surface-hover)}
.asst-cf-f .btn.q:focus-visible{box-shadow:var(--shadow-control),var(--focus-ring)}
/* one primary per panel (DESIGN-CALM §3.4): once the owner types, the send arrow turns accent and «Выполнить выбранное»
   steps down to secondary (the «demote primary» recipe; sending declines the card anyway, js/assistant.js send()).
   While a turn runs the arrow is hidden behind «Стоп», so the card keeps its primary then. */
.asst:not(.busy):has(.asst-in textarea:not(:placeholder-shown)) .asst-cf-f .btn.g{background:var(--btn-bg);color:var(--btn-text);box-shadow:var(--shadow-control),0 0 0 1px var(--border)}
.asst:not(.busy):has(.asst-in textarea:not(:placeholder-shown)) .asst-cf-f .btn.g:hover{background:var(--btn-bg-hover);box-shadow:var(--shadow-control),0 0 0 1px var(--border-strong)}
.asst:not(.busy):has(.asst-in textarea:not(:placeholder-shown)) .asst-cf-f .btn.g:active{background:var(--surface-hover)}
.asst:not(.busy):has(.asst-in textarea:not(:placeholder-shown)) .asst-cf-f .btn.g:focus-visible{outline:none;box-shadow:var(--shadow-control),var(--focus-ring)}
.asst:not(.busy):has(.asst-in textarea:not(:placeholder-shown)) .asst-cf-f .btn.g .asst-cf-c{background:var(--kbd-bg);box-shadow:none;color:var(--kbd-text)}

/* ── empty state ── */
.asst-empty{display:grid;grid-template-columns:minmax(0,1fr);gap:8px;align-content:start}
.asst-hi{margin:0 0 8px;font:var(--t-body);color:var(--text-2)}
.asst-hi b{display:block;margin-bottom:4px;font:var(--t-heading-s);color:var(--text-strong)}
.asst-dg{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-bottom:8px}
/* stat tiles = grey info cards */
.asst-st{display:grid;gap:2px;align-content:start;min-width:0;padding:12px;border-radius:var(--radius-m);background:var(--surface-offset);text-align:left;transition:background var(--dur-1)}
.asst-st:hover{background:var(--surface-offset-hover)}
.asst-st b{font:700 20px/28px var(--font-sans);color:var(--text-strong);font-variant-numeric:tabular-nums}
/* overdue / waiting: the number stays --text-strong, an 8 px status dot leads the label (DESIGN-CALM §3.7, as G7 .rp-kpi.alert) */
.asst-st:is(.red,.warn) span::before{content:"";display:inline-block;width:8px;height:8px;margin-right:6px;border-radius:50%;vertical-align:0;background:var(--dot-red)}
.asst-st.warn span::before{background:var(--dot-orange)}
.asst-st span{font:var(--t-caption);color:var(--text-3)}
/* suggestion chips = filter pills with a 12 px spark */
.asst-sg{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}
/* §5.11 .fpill: one 24 px line, full pill, grey leading icon; a prompt longer than the panel ellipsizes (a long one carries
   its full text as a data-tip; it also shows in the user's bubble once sent) */
.asst-chip{display:inline-flex;align-items:center;gap:6px;max-width:100%;height:24px;padding:0 8px 0 6px;border:1px dashed var(--border);border-radius:var(--radius-pill);text-align:left;
  background:transparent;font:var(--t-caption-strong);color:var(--text-2);white-space:nowrap;transition:background var(--dur-1)}
.asst-chip span{min-width:0;overflow:hidden;text-overflow:ellipsis}
.asst-chip .ic{flex:none;width:12px;height:12px;stroke-width:2.4;color:var(--icon)}
.asst-chip:hover{border-style:solid;background:var(--surface-hover)}
.asst-chip:focus-visible{border-style:solid;border-color:var(--focus-color);box-shadow:none}   /* the 1 px accent keyline in place of the dashed grey one (§3.9) */
.asst-fine{margin:0;font:var(--t-caption);color:var(--text-3)}

/* ── composer: Sigma's prompt box ── */
.asst-f{flex:none;display:grid;gap:8px;padding:8px 16px 12px}
.asst-ctx{display:flex;align-items:center;gap:6px;min-width:0;font:var(--t-caption);color:var(--text-3)}
.asst-ctx .ic{flex:none;width:12px;height:12px;stroke-width:2.4;color:var(--icon)}
.asst-ctx span{min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.asst-ctx b{font-weight:600;color:var(--text-2)}
/* the box keeps --shadow-prompt at rest and takes the focus ring on focus-within (components.css rule 2) */
.asst-in{position:relative;display:flex;align-items:flex-start;gap:8px;min-height:44px;padding:10px 40px 10px 12px;border-radius:var(--radius-l);background:var(--surface);box-shadow:var(--shadow-prompt);cursor:text}
/* the keyline means «typing here»: focus on «Стоп» or the send arrow inside the box keeps the rest shadow, so their own
   1 px ring is the only blue (components.css rule 2 alone would light both) */
.asst-in:focus-within:not(:has(textarea:focus)){box-shadow:var(--shadow-prompt)}
.asst.busy .asst-in{padding-right:76px}
.asst-in > .ic{flex:none;width:16px;height:16px;margin-top:2px;stroke-width:2;color:var(--icon)}
.asst-in textarea{flex:1;min-width:0;height:20px;min-height:20px;max-height:160px;padding:0;border:0;outline:0;resize:none;background:transparent;box-shadow:none;font:var(--t-body);color:var(--text)}
/* one-line prompt box (Sigma, 44 px): the placeholder never wraps, so the box does not jump on the first keystroke */
.asst-in textarea::placeholder{color:var(--text-4);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.asst-in textarea:placeholder-shown{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}   /* Chrome draws the ellipsis only with both rules */
.asst-send{position:absolute;right:8px;bottom:8px;width:28px;height:28px;display:grid;place-items:center;border-radius:50%;background:var(--accent);color:var(--on-accent);transition:background var(--dur-1),box-shadow var(--dur-1),color var(--dur-1)}
.asst-send:hover{background:var(--accent-hover);box-shadow:0 0 0 1px var(--accent-ring-hover)}
.asst-send .ic{width:12px;height:12px;stroke-width:2.6}
.asst-send:focus-visible{outline:var(--focus-outline);outline-offset:2px}   /* a filled control: the 1 px ring sits 2 px off the accent fill (DESIGN-CALM §3.9) */
/* disabled look: nothing typed yet (Enter / a click then does nothing, as before) */
.asst-send:disabled,.asst-in:has(textarea:placeholder-shown) .asst-send{background:var(--surface-pressed);color:var(--text-disabled);box-shadow:none;cursor:default}
/* «Стоп» = secondary .btn.sm inside the box */
.asst-stop{position:absolute;right:8px;bottom:10px;display:inline-flex;align-items:center;gap:4px;height:24px;padding:0 8px;border-radius:var(--radius-s);
  background:var(--btn-bg);color:var(--btn-text);font:var(--t-caption-strong);white-space:nowrap;box-shadow:var(--shadow-control),0 0 0 1px var(--border);transition:box-shadow var(--dur-1)}
.asst-stop:hover{box-shadow:var(--shadow-control),0 0 0 1px var(--border-strong)}
.asst-stop:focus-visible{box-shadow:var(--shadow-control),var(--focus-ring)}
.asst-stop .ic{width:12px;height:12px;stroke-width:2.4}   /* §5.2: 12 px icons in buttons */
/* disclaimer + keys (Sigma) */
.asst-hint{display:grid;gap:4px;font:var(--t-caption);color:var(--text-3)}
.asst-hint .kbd{margin:0 2px}
@media (max-height:640px){ .asst-hint{display:none} }

@media (prefers-reduced-motion: reduce){
  .asst.in,.asst-m,.asst-cf,.asst-steps.live li{animation:none}
  .asst{transition:none}
  .asst-wt::after{animation-duration:2s!important;animation-iteration-count:infinite!important}
}
