:root{
  color-scheme:light;
  --plane:#f1f4f7; --panel:#fff; --soft:#f6f8fa; --sunk:#eef2f5;
  --ink:#151d26; --ink-2:#5b6b7a; --ink-3:#66737f;
  --line:#e3e9ee; --line-2:#cfd8e0;
  --accent:#1f62b0; --accent-2:#17497f; --wash:#e9f1fb; --focus:#2a7fd4;
  --ok:#12833a; --ok-wash:#e7f5ec;
  --warn:#a56a00; --warn-wash:#fdf2e0;
  --crit:#c4362f; --crit-wash:#fdecea;
  --c1:#0e4f5c; --c2:#1a7d8e; --c3:#3fa3ae; --c4:#76b9c1;
  --c1t:#fff; --c2t:#fff; --c3t:#06222a; --c4t:#06222a;
  --r:10px; --r-s:7px;
  /* How wide the working area is. Written once because the header bar
     and the content under it have to line up: the logo sits over the
     first column of every table, and a page whose chrome and body are
     different widths reads as a mistake even when nothing is wrong. */
  --page:1440px;
  --mono:"IBM Plex Mono",ui-monospace,Menlo,monospace;
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  color-scheme:dark;
  --plane:#10161c; --panel:#18212a; --soft:#1d2831; --sunk:#131c23;
  --ink:#eaeff4; --ink-2:#a6b5c2; --ink-3:#7f8d9a;
  --line:#27333e; --line-2:#3a4854;
  --accent:#5a9ee0; --accent-2:#8fbdec; --wash:#16283a; --focus:#6fb0e8;
  --ok:#45bf65; --ok-wash:#142a1c; --warn:#d8a03a; --warn-wash:#2c2313;
  --crit:#e5675f; --crit-wash:#2c1a18;
  --c1:#8fd3db; --c2:#5fb4bf; --c3:#3c8d99; --c4:#286a75;
  --c1t:#06222a; --c2t:#06222a; --c3t:#fff; --c4t:#fff;
}}
[data-theme="dark"]{
  color-scheme:dark;
  --plane:#10161c; --panel:#18212a; --soft:#1d2831; --sunk:#131c23;
  --ink:#eaeff4; --ink-2:#a6b5c2; --ink-3:#7f8d9a;
  --line:#27333e; --line-2:#3a4854;
  --accent:#5a9ee0; --accent-2:#8fbdec; --wash:#16283a; --focus:#6fb0e8;
  --ok:#45bf65; --ok-wash:#142a1c; --warn:#d8a03a; --warn-wash:#2c2313;
  --crit:#e5675f; --crit-wash:#2c1a18;
  --c1:#8fd3db; --c2:#5fb4bf; --c3:#3c8d99; --c4:#286a75;
  --c1t:#06222a; --c2t:#06222a; --c3t:#fff; --c4t:#fff;
}
*,*::before,*::after{box-sizing:border-box}
/* hidden means hidden. A display rule on a class — .btn, .chip, .seg —
   used to win over the attribute, and a button told to go away stayed:
   "Start Sourcing" on every step of a deal long past sourcing. */
[hidden]{display:none!important}
body{margin:0;background:var(--plane);color:var(--ink);
  font:400 15px/1.5 "IBM Plex Sans",system-ui,sans-serif;-webkit-font-smoothing:antialiased}
:focus-visible{outline:2.5px solid var(--focus);outline-offset:2px;border-radius:5px}
/* A box already draws its own focus, and the ring above drew a second one
   around it — at a different radius, so the corners did not nest. One
   ring: the border takes the colour and a halo sits outside it, following
   the shape the box already has. */
.fld input:focus-visible,.fld select:focus-visible,.fld textarea:focus-visible,
.wbox:focus-visible{outline:none}
@media(prefers-reduced-motion:reduce){*{transition:none!important}}
h1,h2{margin:0;font-weight:600;letter-spacing:-.015em}
h1{font-size:23px} h2{font-size:17px}
p{margin:0 0 10px}
a{color:var(--accent);text-decoration:none;font-weight:500}
a:hover{text-decoration:underline}
.num{font-family:var(--mono);font-variant-numeric:tabular-nums;font-weight:500}
.muted{color:var(--ink-3)} .small{font-size:13px} .b{font-weight:600}

.top{position:sticky;top:0;z-index:30;background:var(--panel);border-bottom:1px solid var(--line)}
.top-in{max-width:var(--page);margin:0 auto;padding:11px 20px;display:flex;align-items:center;gap:12px;flex-wrap:wrap}
/* Navigation and actions are real links here.
   The prototype used <button> because it was a single page; in the
   application these move between pages, so middle-click, browser history
   and "open in a new tab" have to work. The selectors below cover both
   forms — nothing about the appearance changes. */
.logo{font-weight:600;font-size:16px;letter-spacing:-.02em;margin-right:6px;
  color:var(--ink);text-decoration:none}
.logo:hover{text-decoration:none}
.nav{display:flex;gap:4px;flex-wrap:wrap}
.nav button,.nav a{height:38px;padding:0 15px;border-radius:var(--r);cursor:pointer;border:0;
  font:500 15px/1 inherit;color:var(--ink-2);background:transparent;display:inline-flex;align-items:center;gap:7px;
  text-decoration:none;white-space:nowrap}
.nav button:hover,.nav a:hover{background:var(--soft);color:var(--ink);text-decoration:none}
.nav button[aria-current="true"],.nav a[aria-current="true"]{background:var(--wash);color:var(--accent-2)}
.pill{min-width:21px;height:21px;padding:0 6px;border-radius:11px;display:inline-flex;
  align-items:center;justify-content:center;font:600 12px/1 var(--mono);background:var(--accent);color:#fff}
.find{position:relative;min-width:180px;max-width:230px;margin-left:auto}
.find input{width:100%;height:38px;padding:0 12px 0 36px;font:500 14px/1 var(--mono);
  color:var(--ink);background:var(--sunk);border:1.5px solid transparent;border-radius:var(--r)}
.find input:focus{border-color:var(--focus);background:var(--panel)}
.find input::placeholder{font-family:"IBM Plex Sans",sans-serif;font-weight:400;color:var(--ink-3)}
.find svg{position:absolute;left:12px;top:11px;color:var(--ink-3)}
.ghost{width:38px;height:38px;border-radius:var(--r);cursor:pointer;background:transparent;
  border:0;color:var(--ink-2);font-size:16px}
.ghost:hover{background:var(--soft)}

.wrap{max-width:var(--page);margin:0 auto;padding:20px 20px 70px}
.screen{display:none} .screen.on{display:block}

.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);padding:20px}
.card+.card{margin-top:14px}
.ct{font-size:17px;font-weight:600;letter-spacing:-.015em;margin:0 0 3px}
.cs{color:var(--ink-2);font-size:14px;margin:0 0 16px}

.btn{height:44px;padding:0 20px;border-radius:var(--r);cursor:pointer;font:500 15px/1 inherit;
  display:inline-flex;align-items:center;gap:8px;background:var(--panel);color:var(--ink);
  border:1.5px solid var(--line-2)}
.btn:hover{background:var(--soft);text-decoration:none}
/* A button that can do nothing right now looks it, wherever it is. */
.btn:disabled{opacity:.5;cursor:default;pointer-events:none}
a.btn{text-decoration:none}
.btn-go{background:var(--accent);border-color:var(--accent);color:#fff}
.btn-go:hover{background:var(--accent-2);text-decoration:none}
.btn-ok{background:var(--ok);border-color:var(--ok);color:#fff}
.btn-s{height:36px;padding:0 14px;font-size:14px;border-radius:var(--r-s)}
.btn-q{border-color:transparent;background:transparent;color:var(--accent)}
.btn-q:hover{background:var(--wash);text-decoration:none}

/* ── command buttons ───────────────────────────────
   A .btn is a decision — save this, send this document, add this part —
   and it is sized like one. Reply, Reply All and Forward are not
   decisions: they are the commands a person runs forty times a morning,
   and forty 44-pixel buttons is a toolbar that has eaten the letter. So
   they are small, flat and labelled beside their icon, which is the shape
   every mail client has settled on and the one Outlook taught. */
.btn-cmd{height:28px;padding:0 7px;display:inline-flex;align-items:center;gap:5px;
  border:1px solid transparent;border-radius:var(--r-s);background:transparent;
  color:var(--ink);font:400 13px/1 inherit;cursor:pointer;white-space:nowrap}
.btn-cmd:hover{background:var(--sunk);border-color:var(--line);text-decoration:none}
.btn-cmd:disabled{opacity:.55;cursor:default;background:transparent;border-color:transparent}
.btn-cmd .i{width:15px;height:15px;flex-shrink:0;fill:none;stroke:currentColor;
  stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;opacity:.85}
.btn-cmd-go{background:var(--accent);border-color:var(--accent);color:#fff;font-weight:500}
.btn-cmd-go:hover{background:var(--accent-2);border-color:var(--accent-2);color:#fff}
.btn-cmd-go .i{opacity:1}
.row{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.bar{display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;margin-bottom:18px}
kbd{font:500 12px/1 var(--mono);padding:4px 6px;border-radius:5px;background:var(--sunk);
  border:1px solid var(--line);color:var(--ink-2)}

.cc{display:inline-flex;align-items:center;gap:6px;padding:4px 10px 4px 6px;border-radius:20px;
  font-size:13px;font-weight:500;background:var(--sunk);white-space:nowrap}
.cc i{padding:2px 6px;border-radius:20px;font:600 12px/1.35 var(--mono)}
.cc-1 i{background:var(--c1);color:var(--c1t)} .cc-2 i{background:var(--c2);color:var(--c2t)}
.cc-3 i{background:var(--c3);color:var(--c3t)} .cc-4 i{background:var(--c4);color:var(--c4t)}
.chip{display:inline-flex;align-items:center;gap:6px;padding:4px 11px;border-radius:20px;
  font-size:13px;font-weight:500;background:var(--sunk);color:var(--ink-2);white-space:nowrap}
.chip[hidden]{display:none}
.chip-ok{background:var(--ok-wash);color:var(--ok)}
.chip-w{background:var(--warn-wash);color:var(--warn)}
.chip-c{background:var(--crit-wash);color:var(--crit)}
.chip-a{background:var(--wash);color:var(--accent-2)}

.money{display:flex;align-items:center;gap:12px 26px;flex-wrap:wrap;padding:18px 20px;
  background:var(--ok-wash);border-radius:var(--r)}
.money.plain{background:var(--sunk)}
.m{display:flex;flex-direction:column;gap:2px}
.m span{font-size:13px;color:var(--ink-3)} .m b{font:600 21px/1.2 var(--mono)}
.big{font:600 29px/1 var(--mono);letter-spacing:-.02em;color:var(--ok)}
/* Three answers of equal weight, each saying what follows from it. A
   button per answer rather than one primary and two afterthoughts: the
   customer said one of three things, and none of them is the default. */
.choices{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}
.choice{display:flex;flex-direction:column;align-items:flex-start;gap:4px;text-align:left;
  padding:12px 14px;border:1.5px solid var(--line-2);border-left-width:5px;border-radius:var(--r);
  background:var(--sunk);cursor:pointer;font:inherit;color:var(--ink);transition:background .12s,border-color .12s}
.choice b{font-size:14.5px}
.choice span{font-size:12.5px;color:var(--ink-3);line-height:1.35}
/* Each answer wears its own colour on the edge and in its name, so the
   three read as three buttons and not as three notes: green for a yes,
   amber for a haggle, red for a no. */
.choice-yes{border-left-color:var(--ok)} .choice-yes b{color:var(--ok)}
.choice-maybe{border-left-color:var(--warn)} .choice-maybe b{color:var(--warn)}
.choice-no{border-left-color:var(--crit)} .choice-no b{color:var(--crit)}
.choice:hover{background:var(--panel);border-color:var(--ink-3)}
.choice-yes:hover{border-color:var(--ok);background:var(--ok-wash)}
.choice-maybe:hover{border-color:var(--warn);background:var(--warn-wash)}
.choice-no:hover{border-color:var(--crit);background:var(--crit-wash)}
.choice:disabled{opacity:.5;cursor:default;pointer-events:none}
@media(max-width:900px){.choices{grid-template-columns:minmax(0,1fr)}}
.arrow{color:var(--ink-3);font-size:20px}

.steps{display:flex;gap:6px;flex-wrap:wrap}
.steps button{padding:8px 15px;border-radius:20px;font:500 13.5px/1.2 inherit;cursor:pointer;
  background:var(--sunk);color:var(--ink-3);border:0}
.steps button:hover{color:var(--ink)}
.steps button.was{background:var(--wash);color:var(--accent-2)}
.steps button.is{background:var(--accent);color:#fff}

.scroll{overflow-x:auto;margin:0 -20px;padding:0 20px}
table{width:100%;border-collapse:collapse;font-size:14px}
th{text-align:left;white-space:nowrap;padding:0 24px 9px 0;font-size:13px;font-weight:500;color:var(--ink-3)}
td{padding:13px 24px 13px 0;border-top:1px solid var(--line);white-space:nowrap;vertical-align:middle}
th:last-child,td:last-child{padding-right:0}
th.r,td.r{text-align:right}
td.r{font-family:var(--mono);font-variant-numeric:tabular-nums;font-weight:500}
tr.pick td{background:var(--wash)}
tr.pick td:first-child{border-radius:var(--r-s) 0 0 var(--r-s)}
tr.pick td:last-child{border-radius:0 var(--r-s) var(--r-s) 0}
tr.go td{cursor:pointer}
tr.go:hover td{background:var(--soft)}

.facts{display:flex;flex-wrap:wrap;gap:20px 34px}
.fk{font-size:13px;color:var(--ink-3);margin-bottom:2px}
.fv{font-size:15px}
/* A long value — a delivery address on the quotation's terms — wraps
   within a measure instead of stretching the row or being cut. */
.facts>div{min-width:0;max-width:100%}
.fv.fv-long{white-space:pre-line;overflow-wrap:anywhere;max-width:46ch;line-height:1.4}

/* реквизиты — две колонки ключ/значение */
.req{display:grid;grid-template-columns:auto 1fr;gap:11px 20px;font-size:14.5px;align-items:baseline}
.req dt{color:var(--ink-3);font-size:13.5px;white-space:nowrap}
.req dd{margin:0}
.req .copy{margin-left:8px;font-size:12px;color:var(--accent);cursor:pointer;
  background:none;border:0;padding:0;font-family:inherit;opacity:0}
.req dd:hover .copy{opacity:1}

/* The aside grows with the page rather than staying put: left fixed, the
   working column would take the whole of the extra width and the two
   would no longer sit in the proportion the screens were drawn in. */
/* `minmax(0,1fr)` rather than `1fr`, which is short for `minmax(auto,1fr)`
   — and an automatic minimum is the content's minimum, so a column
   refuses to shrink below the widest thing in it and pushes the aside
   off the side of the window instead. The tables inside already scroll;
   letting the track shrink is what lets them.

   This was true before the page was widened and showed at other window
   sizes: at 1440 the old layout ran 110 px off the screen and the new
   one 56 px, which is why it read as a new fault. */
.cols{display:grid;grid-template-columns:minmax(0,1fr) 396px;gap:14px;align-items:start}
.cols2{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:14px;align-items:start}
@media(max-width:900px){.cols,.cols2{grid-template-columns:minmax(0,1fr)}}
/* A tablet at 1024 has 984 px of content, and a fixed 330 px aside
   leaves the working column too narrow for a table of parts. The aside
   holds figures and short lists, so it is the one that gives way. */
@media(min-width:901px) and (max-width:1080px){
  .cols{grid-template-columns:minmax(0,1fr) 280px}
  .wrap{padding-left:14px;padding-right:14px}
}

/* Prose in a table cell wraps; everything else does not.
   `td` is `nowrap` so that dates, part numbers and figures keep their
   shape — but a cell holding a sentence then widens the whole table
   until it runs out of the card, and the sentence is cut mid-word with
   nothing to say it was. Marked per cell rather than turned off wholesale,
   because the nowrap is right nearly everywhere. */
td.prose{white-space:normal}
/* A cell of buttons, allowed to fall onto a second line. Held on one line
   it decided the width of the whole table, and in a language whose words
   are longer than English the last of the three hung off the card. */
td.acts{white-space:normal}
td.acts>*{display:inline-flex;margin:2px 0 2px 6px}
td.prose .chip{white-space:normal;text-align:left}

.note{padding:14px 16px;border-radius:var(--r);background:var(--wash);color:var(--ink-2);
  font-size:14px;line-height:1.55}
.note b{color:var(--ink)}
.note-w{background:var(--warn-wash);color:var(--warn)} .note-w b{color:var(--warn)}

/* The track minimum decides how many fields sit on a line. Raised with
   the dialog rather than left alone: at the old minimum a wider dialog
   simply fits a fourth column, which makes every field narrower than it
   was — the opposite of what widening it is for. Three columns, each
   with the room the extra width bought. */
.form{display:grid;grid-template-columns:repeat(auto-fit,minmax(216px,1fr));gap:14px}
/* Three fields on a line, and their inputs on one line with each other.
   A label that wraps — "Юридическое наименование (необязательно)" does,
   where "Legal name (optional)" did not — used to push its own input a
   line lower than its neighbours', so a row of three boxes sat at three
   heights. `subgrid` lets every field share the parent's rows: label,
   control, hint, each aligned across the row rather than stacked inside
   its own cell. Reserving two lines for every label instead would put
   the gap on every dialog to fix the few that need it. */
.form>.fld{display:grid;grid-template-rows:subgrid;grid-row:span 3;
  align-content:start;gap:0}
.fld label{display:block;font-size:13px;color:var(--ink-2);margin-bottom:5px;font-weight:500}
.fld input,.fld select,.fld textarea{width:100%;height:44px;padding:0 13px;font:400 15px/1 inherit;
  color:var(--ink);background:var(--panel);border:1.5px solid var(--line-2);border-radius:var(--r-s)}
.fld textarea{height:80px;padding:11px 13px;line-height:1.5;resize:vertical;font-family:inherit}
.fld input.num{font-family:var(--mono);font-weight:500}
.fld input:focus,.fld select:focus,.fld textarea:focus{
  border-color:var(--focus);box-shadow:0 0 0 3px rgb(42 127 212/.22)}
/* A box nobody may fill in yet. Without this, the disabled "Contact"
   looked exactly like the one above it that was waiting to be used. */
.fld select:disabled,.fld input:disabled{
  background:var(--sunk);color:var(--ink-3);border-style:dashed;cursor:not-allowed}
.hint{font-size:12.5px;color:var(--ink-3);margin-top:5px}

/* A long explanation, folded away. The question mark sits with the label
   rather than under the box, because it belongs to the name of the thing
   and not to what has been typed into it. */
.lab-row{display:flex;align-items:baseline;gap:7px;margin-bottom:5px}
.lab-row label{margin:0}
.q{appearance:none;border:1px solid var(--line-2);background:var(--panel);
  width:17px;height:17px;border-radius:50%;padding:0;cursor:pointer;
  font:600 11px/1 inherit;color:var(--ink-3);display:grid;place-items:center;flex:none}
.q:hover{border-color:var(--accent);color:var(--accent)}
.q[aria-expanded="true"]{background:var(--wash);border-color:var(--accent);color:var(--accent)}
.note{margin:6px 0 0;padding:9px 11px;font-size:12.5px;line-height:1.5;
  color:var(--ink-2);background:var(--soft);
  border-left:2px solid var(--accent);border-radius:0 var(--r-s) var(--r-s) 0}
.note[hidden]{display:none}

/* An aircraft on the ground. Not a colour for decoration: this is the
   one value in the box that changes what everybody does next. */
.fld select.urgent{color:var(--crit);border-color:var(--crit);font-weight:600}

/* Column headings over the rows of parts. They existed only as
   aria-labels — a screen reader knew what the three boxes were and an
   eye did not. */
.line-head{display:grid;grid-template-columns:minmax(0,2fr) 80px minmax(0,1.4fr) 36px;
  gap:8px;margin-bottom:-4px}
.line-head span{font-size:12px;color:var(--ink-3);font-weight:500}

/* The other numbers a part answers to, under its own. */
.also{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 9px;margin-top:9px}
.also .pn{font:500 13px/1 var(--mono);background:var(--sunk);color:var(--ink-2);
  padding:5px 9px;border-radius:var(--r-s)}

/* More numbers for one part: subordinate to the number above, not equal
   to it. Ruled off on the left, a size smaller, no label of its own. */
.alts{margin-top:9px;padding-left:11px;border-left:2px solid var(--line);
  display:flex;flex-direction:column;gap:6px}
.alts[hidden]{display:none}
.alts-lab{font-size:12px;color:var(--ink-3);font-weight:500}
.alt-rows{display:flex;flex-direction:column;gap:6px}
.alt-row{display:grid;grid-template-columns:minmax(0,1fr) 30px;gap:6px}
.alt-row input{height:38px;font-size:14px;padding:0 11px}
.alt-x{height:38px;width:30px;padding:0;cursor:pointer;
  border:1.5px solid var(--line-2);border-radius:var(--r-s);
  background:var(--panel);color:var(--ink-3);font:400 16px/1 inherit;
  display:grid;place-items:center}
.alt-x:hover{border-color:var(--crit);color:var(--crit)}
.alts .hint{margin-top:1px}
.add-alt{appearance:none;background:transparent;border:0;padding:8px 0 0;
  cursor:pointer;font:500 13px/1.4 inherit;color:var(--accent);align-self:flex-start}
.add-alt:hover{text-decoration:underline}

/* What may be skipped, behind one fold and named once. */
.more{appearance:none;width:100%;text-align:left;cursor:pointer;
  background:transparent;border:0;border-top:1px solid var(--line);
  padding:14px 0 0;margin-top:16px;
  font:500 14px/1.4 inherit;color:var(--accent);
  display:flex;align-items:center;gap:8px}
.more .chev{transition:transform .15s}
.more[aria-expanded="true"] .chev{transform:rotate(90deg)}
.more .rest{color:var(--ink-3);font-weight:400;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.opt-zone{margin-top:16px}
.opt-zone[hidden]{display:none}
/* Softer to look at than what is required above it, without a word
   saying so on every box. */
.opt-zone input,.opt-zone select,.opt-zone textarea{background:var(--soft)}

.todo{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:11px}
.todo li{display:flex;gap:11px;align-items:flex-start;font-size:14.5px}
.todo .mk{width:20px;height:20px;border-radius:50%;flex:none;display:grid;place-items:center;
  font-size:12px;font-weight:600;margin-top:1px}
.todo .yes{background:var(--ok-wash);color:var(--ok)}
.todo .no{background:var(--crit-wash);color:var(--crit)}
.todo .wait{background:var(--sunk);color:var(--ink-3)}

.tl{list-style:none;margin:0;padding:0}
.tl li{display:flex;gap:12px;padding-bottom:16px;position:relative}
.tl li::before{content:"";width:11px;height:11px;border-radius:50%;flex:none;margin-top:5px;
  background:var(--accent);box-shadow:0 0 0 3px var(--wash)}
.tl li.w::before{background:var(--panel);box-shadow:inset 0 0 0 2px var(--line-2)}
.tl li:not(:last-child)::after{content:"";position:absolute;left:5px;top:20px;bottom:0;width:1.5px;background:var(--line)}
.tl .when{font-size:13px;color:var(--ink-3);margin-top:1px}
.tl li.w>div>span:first-child{color:var(--ink-3)}

.letter{background:var(--sunk);border-radius:var(--r);padding:16px 18px;font-size:14px}
.filters{display:flex;gap:7px;flex-wrap:wrap;margin-bottom:16px}
.filters button{height:36px;padding:0 15px;border-radius:20px;cursor:pointer;font:500 14px/1 inherit;
  color:var(--ink-2);background:var(--panel);border:1.5px solid var(--line)}
.filters button:hover{border-color:var(--line-2);color:var(--ink)}
.filters button[aria-pressed="true"]{background:var(--ink);border-color:var(--ink);color:var(--panel)}
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin-bottom:16px}
.kpi{padding:14px 16px;background:var(--sunk);border-radius:var(--r)}
.kpi b{display:block;font:600 24px/1.2 var(--mono);margin-top:3px}

/* аватар-инициалы */
.ava{width:44px;height:44px;border-radius:var(--r);flex:none;display:grid;place-items:center;
  font:600 15px/1 inherit;background:var(--wash);color:var(--accent-2)}
.ava-s{width:32px;height:32px;font-size:12.5px;border-radius:var(--r-s)}

/* контакты */
.people{display:flex;flex-direction:column;gap:14px}
.person{display:flex;gap:11px;align-items:flex-start}
/* A device calls itself whatever its browser says, which is one unbroken
   hundred-character word. A flex item will not shrink below its longest
   word unless it is allowed to, so the row grew until it pushed its own
   button off the side of the window — on the narrow aside, off the page
   entirely. */
.person>div{min-width:0}
.person .nm,.person .rl{overflow-wrap:anywhere}
.person .nm{font-weight:500}
.person .rl{font-size:13px;color:var(--ink-3)}
.person .ct2{font-size:13.5px;margin-top:3px}

/* калькулятор */
.stack{display:flex;gap:2px;height:12px;border-radius:6px;overflow:hidden}
.stack i{display:block;min-width:2px}
.legend{list-style:none;margin:10px 0 0;padding:0;display:flex;flex-direction:column;gap:6px}
.legend li{display:flex;align-items:center;gap:9px;font-size:13.5px}
.legend .sw{width:10px;height:10px;border-radius:3px;flex:none}
.legend .v{margin-left:auto;font-family:var(--mono);font-variant-numeric:tabular-nums;font-weight:500}
.legend .pc{color:var(--ink-3);font-size:12.5px;width:42px;text-align:right;
  font-family:var(--mono);font-variant-numeric:tabular-nums}

/* ── вход ─────────────────────────────────────── */
body[data-auth="out"] #app{display:none}
body[data-auth="in"]  #login{display:none}
#login{min-height:100vh;display:grid;place-items:center;padding:24px}
.login-box{width:100%;max-width:400px}
.login-card{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:30px}
.login-logo{font-weight:600;font-size:20px;letter-spacing:-.02em;margin-bottom:4px}
.demo{margin-top:22px;padding-top:20px;border-top:1px solid var(--line)}

/* ── роли ─────────────────────────────────────── */
body[data-role="mgr"]  .boss{display:none!important}
body[data-role="boss"] .mgr{display:none!important}

/* ── пользователь в шапке ─────────────────────── */
.who{display:flex;align-items:center;gap:9px;height:38px;padding:0 10px 0 6px;border:0;
  border-radius:var(--r);background:transparent;cursor:pointer;font:inherit;color:var(--ink);
  text-decoration:none;font-weight:400}
.who:hover{background:var(--soft);text-decoration:none}
.who .nm{font-size:13.5px;font-weight:500;line-height:1.2;text-align:left}
.who .rl{font-size:11.5px;color:var(--ink-3);line-height:1.2}

/* ── графики на CSS ───────────────────────────── */
.hbars{display:flex;flex-direction:column;gap:11px}
.hbar{display:grid;grid-template-columns:150px 1fr auto;gap:12px;align-items:center;font-size:14px}
.hbar .tr{display:block;height:26px;background:var(--sunk);border-radius:5px;overflow:hidden}
.hbar .fl{display:block;height:100%;border-radius:5px;background:var(--accent)}
.hbar .vl{font-family:var(--mono);font-variant-numeric:tabular-nums;font-weight:500;
  min-width:56px;text-align:right}
.hbar .nmm{color:var(--ink-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.vbars{display:flex;align-items:flex-end;gap:10px;height:170px;padding-top:22px}
.vb{flex:1;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;
  gap:7px;height:100%;position:relative}
.vb .col{width:100%;max-width:52px;background:var(--accent);border-radius:5px 5px 0 0;min-height:3px}
.vb .col.dim{background:var(--line-2)}
.vb .vv{position:absolute;top:-20px;font:500 12.5px/1 var(--mono);font-variant-numeric:tabular-nums}
.vb .lb{font-size:12.5px;color:var(--ink-3)}

.mini{display:block;height:6px;background:var(--sunk);border-radius:3px;overflow:hidden;min-width:70px}
.mini i{display:block;height:100%;background:var(--accent);border-radius:3px}
.mini i.ok{background:var(--ok)} .mini i.warn{background:var(--warn)} .mini i.crit{background:var(--crit)}

/* ── контроль ─────────────────────────────────── */
.ctrl{display:flex;align-items:center;gap:14px;flex-wrap:wrap;padding:13px 16px;
  background:var(--warn-wash);border-radius:var(--r);margin-bottom:14px}
.ctrl.calm{background:var(--sunk)}
.alerts{display:flex;flex-direction:column;gap:2px}
.alert{display:flex;gap:12px;align-items:flex-start;padding:12px 0;border-top:1px solid var(--line)}
.alert:first-child{border-top:0}
.alert .ic{width:24px;height:24px;border-radius:7px;flex:none;display:grid;place-items:center;
  font-size:13px;font-weight:600}
.alert .tt{font-size:14.5px}
.alert .ds{font-size:13px;color:var(--ink-3);margin-top:1px}
.alert .go2{margin-left:auto;flex:none}

.seg{display:inline-flex;background:var(--sunk);border-radius:var(--r);padding:3px;gap:2px}
.seg[hidden]{display:none}
.seg button{height:32px;padding:0 14px;border:0;border-radius:var(--r-s);cursor:pointer;
  font:500 13.5px/1 inherit;color:var(--ink-2);background:transparent}
.seg button:hover{color:var(--ink)}
.seg button[aria-pressed="true"]{background:var(--panel);color:var(--ink);
  box-shadow:0 1px 3px rgb(21 29 38/.10)}

.check{display:flex;align-items:center;gap:10px;font-size:14.5px;padding:7px 0;cursor:pointer}
.check input{width:18px;height:18px;accent-color:var(--accent);flex:none}

/* ── поиск детали внутри раздела ──────────────── */
#parts .find input{height:50px;padding:0 44px 0 44px;font-size:16px;
  border:1.5px solid var(--line-2);background:var(--panel)}
#parts .find input:focus{border-color:var(--focus)}
#parts .find svg{left:16px;top:17px}
.pclr{position:absolute;right:9px;top:9px;width:32px;height:32px;border:0;border-radius:50%;
  background:var(--sunk);color:var(--ink-2);cursor:pointer;font-size:17px;line-height:1}
.pclr:hover{background:var(--line-2)}
tr.hit td{background:var(--wash)}
mark{background:var(--wash);color:var(--accent-2);font-weight:600;border-radius:3px;padding:0 2px}

/* ── creation dialogs ──────────────────────────────
   Absent from the prototype, where every "+ New…" button is dead, and
   listed in the interface spec as still to be designed. Built from the
   same variables and the same form classes as the pricing panel, so
   adding a part reads like changing a price. */
.modal{width:min(816px,calc(100vw - 32px));max-height:calc(100vh - 64px);padding:0;
  border:1px solid var(--line);border-radius:var(--r);background:var(--panel);color:var(--ink);
  box-shadow:0 24px 60px rgb(21 29 38/.22)}
.modal::backdrop{background:rgb(21 29 38/.45)}
.modal form{display:flex;flex-direction:column;max-height:calc(100vh - 64px)}
.modal header{padding:20px 22px 14px;border-bottom:1px solid var(--line)}
.modal header h2{margin:0;font-size:19px;font-weight:600}
.modal header p{margin:4px 0 0;font-size:14px}
.modal-body{padding:20px 22px;overflow:auto}
.modal footer{display:flex;align-items:center;gap:10px;padding:14px 22px;
  border-top:1px solid var(--line);background:var(--soft);
  border-radius:0 0 var(--r) var(--r)}
.modal footer .keys{margin-right:auto;font-size:12.5px;color:var(--ink-3)}
.modal .fail{margin:0 0 16px;padding:11px 14px;border-radius:var(--r-s);
  background:var(--crit-wash);color:var(--crit);font-size:14px;line-height:1.5}
/* The release notes: prose, read once. */
.whatsnew{width:min(680px,calc(100vw - 32px))}
.whatsnew[open]{display:flex;flex-direction:column}
.whatsnew .modal-body{flex:1;min-height:0}
.whatsnew .modal-body:focus,.whatsnew .modal-body:focus-visible{outline:none}
.whatsnew .modal-body{font-size:14.5px;line-height:1.55}
.whatsnew .modal-body p{margin:0 0 14px}
.whatsnew h3{margin:18px 0 8px;font-size:15px;font-weight:600}
.whatsnew ul{margin:0;padding-left:20px}
.whatsnew li{margin:0 0 7px}
.fld-err{margin:5px 0 0;font-size:12.5px;color:var(--crit)}
.fld:has(.fld-err:not([hidden])) input,.fld:has(.fld-err:not([hidden])) select,
.fld:has(.fld-err:not([hidden])) textarea{border-color:var(--crit)}
.fld{position:relative}
.lookup{position:absolute;left:0;right:0;top:100%;z-index:2;margin:4px 0 0;padding:5px;
  list-style:none;max-height:232px;overflow:auto;background:var(--panel);
  border:1px solid var(--line-2);border-radius:var(--r-s);box-shadow:0 12px 28px rgb(21 29 38/.16)}
.lookup li{display:flex;gap:10px;align-items:baseline;padding:8px 10px;border-radius:var(--r-s);
  font:500 14px/1.3 var(--mono);cursor:pointer}
.lookup li span{font:400 13px/1.3 inherit;font-family:"IBM Plex Sans",sans-serif;
  margin-left:auto;text-align:right}
.lookup li:hover{background:var(--wash)}
/* No outline:none here — these are keyboard-reachable options, and the
   ring is the only thing telling somebody where they are. */
.lookup li:focus-visible{background:var(--wash)}
.lookup li.muted{cursor:default;font-family:inherit;font-weight:400}

/* Success and failure have to look different: "Saved" and "Not sent"
   reading the same defeats the message. The prototype has only .note-w. */
.note-ok{background:var(--ok-wash);color:var(--ok)} .note-ok b{color:var(--ok)}
.note-warn{background:var(--warn-wash);color:var(--warn)} .note-warn b{color:var(--warn)}
.note-crit{background:var(--crit-wash);color:var(--crit)} .note-crit b{color:var(--crit)}
/* Pinned to the window, not to the page.
   It used to sit at the top of the content and be scrolled to, so every
   saved dialog and every recorded answer threw the reader back to the top
   of a long screen in order to show them one sentence. */
.flash{position:fixed;top:16px;left:50%;transform:translateX(-50%);z-index:60;
  display:flex;align-items:flex-start;gap:12px;max-width:min(560px,calc(100vw - 28px));
  margin:0;box-shadow:0 10px 30px rgb(21 29 38/.18);
  border:1px solid var(--line);animation:flash-in .16s ease-out}
:root[data-theme="dark"] .flash{box-shadow:0 10px 30px rgb(0 0 0/.45)}
@media(prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .flash{box-shadow:0 10px 30px rgb(0 0 0/.45)}}
.flash-x{flex:none;margin:-2px -4px 0 auto;width:24px;height:24px;padding:0;
  border:0;border-radius:6px;background:none;color:inherit;opacity:.65;
  font:400 19px/1 var(--mono);cursor:pointer}
.flash-x:hover{opacity:1;background:rgb(0 0 0/.06)}
@keyframes flash-in{from{opacity:0;transform:translate(-50%,-6px)}
  to{opacity:1;transform:translate(-50%,0)}}
@media(prefers-reduced-motion:reduce){.flash{animation:none}}
/* Full width on a narrow screen, so the centring transform goes with it. */
@media(max-width:640px){.flash{left:14px;right:14px;transform:none;max-width:none;
  animation:none}}

/* Where the deal actually stands, when the reader is looking elsewhere.
   A ring rather than a fill: the filled pill means "this is what you are
   looking at", and two pills filled the same way would say nothing. */
.steps button[data-now]{box-shadow:inset 0 0 0 1.5px var(--accent);color:var(--accent-2)}

/* A row per part on the new-enquiry dialog. Four columns on a desktop,
   stacked below it — a part number squeezed into a quarter of a phone
   screen is unreadable, and the number is the whole point of the row. */
.lines{display:flex;flex-direction:column;gap:10px}
.line-row{display:grid;grid-template-columns:minmax(0,2fr) 80px minmax(0,1.4fr) 36px;
  gap:8px;align-items:start}
.line-row .fld{margin:0}
.line-row .btn{height:44px;padding:0;width:36px;display:grid;place-items:center;font-size:18px}
@media(max-width:640px){
  .line-row{grid-template-columns:1fr 1fr;align-items:end}
  .line-row .fld:first-child{grid-column:1/-1}
}

/* The paging control. Deliberately plain and at the foot of the card:
   it is a way out of a long list, not a thing to look at. */
.pager{display:flex;align-items:center;gap:10px;margin-top:14px;font-size:13.5px}
.pager .muted{margin-right:auto}
.pager button[disabled]{opacity:.45;cursor:default}
/* Filters in the table head: one control under each heading it narrows,
   drawn quieter than a form field so the head still reads as a head. */
.th-filters th{padding:4px 12px 10px 0;font-weight:400}
.th-filters input,.th-filters select{width:100%;height:32px;padding:0 8px;font:400 13px/1 inherit;
  color:var(--ink);background:var(--sunk);border:1px solid transparent;border-radius:7px;min-width:0}
.th-filters input:focus,.th-filters select:focus{outline:0;border-color:var(--accent);background:var(--panel)}
/* The consignment note, on a deal in transit: a mark until it is ticked. */
.waybill{display:inline-flex;align-items:center;gap:6px;margin-top:4px;padding:3px 9px;border-radius:20px;
  font-size:12px;font-weight:500;border:1px solid transparent;cursor:pointer;background:var(--warn-wash);color:var(--warn)}
.waybill:hover{border-color:var(--warn)}
.waybill.done{background:var(--ok-wash);color:var(--ok)}

/* ── loading state ─────────────────────────────────
   Skeletons rather than a spinner, as the interface spec asks: the shape
   of what is coming is itself information, and a list that arrives into
   a space the right size does not make the page jump.
   `prefers-reduced-motion` is honoured — a shimmer is decoration, and to
   some people it is worse than that. */
.skel{display:block;height:12px;border-radius:6px;background:var(--sunk);
  position:relative;overflow:hidden}
.skel::after{content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,rgb(255 255 255/.14),transparent);
  animation:skel 1.3s infinite}
:root[data-theme="dark"] .skel::after{background:linear-gradient(90deg,transparent,rgb(255 255 255/.06),transparent)}
@keyframes skel{100%{transform:translateX(100%)}}
@media(prefers-reduced-motion:reduce){.skel::after{animation:none}}
tr.skel-row td{padding:14px 12px}
tr.skel-row .skel{width:100%}
tr.skel-row td:nth-child(2) .skel{width:70%}
tr.skel-row td.r .skel{width:50%;margin-left:auto}

/* ── what needs you ────────────────────────────────
   A count, not a dot: "three things" is actionable and a coloured spot
   is not, and colour alone must never be the only carrier of meaning. */
.bell-wrap{position:relative}
#bell{position:relative}
.bell-count{position:absolute;top:2px;right:2px;min-width:16px;height:16px;padding:0 4px;
  border-radius:9px;background:var(--crit);color:#fff;font:600 11px/16px var(--mono);
  text-align:center}
.bell-panel{position:absolute;right:0;top:calc(100% + 8px);z-index:30;width:330px;
  max-height:70vh;overflow:auto;background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r);box-shadow:0 16px 40px rgb(21 29 38/.20)}
.bell-item{display:block;padding:12px 14px;border-bottom:1px solid var(--line);
  color:var(--ink);text-decoration:none}
.bell-item:last-child{border-bottom:0}
.bell-item:hover{background:var(--soft);text-decoration:none}
@media(max-width:640px){.bell-panel{width:calc(100vw - 28px);right:-8px}}

/* ── the sourcing tree ─────────────────────────────
   A deal is parts first and suppliers second; the screen used to say the
   opposite — one part at a time, chosen from a strip in the header that
   hid itself whenever there was only one line to choose from. So a part
   nobody had been asked about looked exactly like a part not currently
   selected, and that is the one part worth seeing. */
.tree{margin:0;padding:0;list-style:none}
.tree>li{border-top:1px solid var(--line)}
.tree>li:first-child{border-top:0}
.tree-part{display:flex;align-items:center;gap:10px;width:100%;padding:11px 12px;
  border:0;background:var(--soft);color:var(--ink);font:inherit;text-align:left;
  cursor:pointer}
.tree-part:hover{background:var(--sunk)}
.tree-part[aria-pressed="true"]{background:var(--wash)}
.tree-part .pn{font:600 14px/1.4 var(--mono)}
.tree-count{margin-left:auto;white-space:nowrap}
.tree-rows{margin:0;padding:0;list-style:none}
/* A row and the action at the end of it, on two fixed tracks.
   It was a flex line: the row took whatever the trailing button left,
   so its width changed with the button's — present on an answered offer,
   absent on a quiet one, wider still for "Remove". The caption above had
   no button at all and so was wider than every row under it, which is
   exactly how the headings came to sit beside their figures instead of
   over them. The slot is now always there, whether or not it is filled. */
.tree-line{display:grid;grid-template-columns:1fr;align-items:center;
  column-gap:8px;padding-right:12px;border-top:1px solid var(--line)}
/* Only where the rows in that list actually carry one. Reserved
   everywhere it left a dead strip down the right of the lists that do
   not, and squeezed their figures to make room for nothing. */
.tree.has-actions .tree-line{grid-template-columns:1fr 104px}
.tree-line>.btn{justify-self:end}
/* Columns, not a run of words.
   These rows were a flex line with a gap, so nothing lined up between one
   supplier and the next: a reader comparing three offers had to find the
   price in a different place on each line. Fixed tracks put the same fact
   in the same column all the way down, which is the whole reason to show
   several of them at once. */
.tree-row{display:grid;align-items:center;column-gap:14px;row-gap:2px;min-width:0;
  padding:9px 4px 9px 30px;border:0;background:none;color:var(--ink);
  font:inherit;text-align:left;cursor:pointer}
.tree-row:hover{background:var(--soft)}
.tree-row[aria-pressed="true"]{background:var(--wash);box-shadow:inset 3px 0 0 var(--accent)}
.tree-row>*{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tree-row .who{font-weight:600}
.tree-row .num{font:400 13px/1.4 var(--mono);text-align:right}
.tree-row .cc,.tree-row .chip{justify-self:start}
/* Short of what was asked for. The one fact on the row that changes what
   happens next — the rest has to be found somewhere else — so it is the
   one that gets a colour. */
.tree-row .short{color:var(--warn);font-weight:600}

/* Every track but the first is a definite width, and that is the whole
   point rather than a stylistic choice.
   The caption and the rows under it are separate grids. A track sized
   from its contents — `auto`, `max-content`, or an `fr` sharing space
   with one — is measured against *that grid's* contents, so "Price each"
   and "4,200.00 USD" size their columns differently and the two can only
   line up by accident. Fixed columns plus one flexible first column give
   both grids the same tracks by construction. */
/* Who was asked, and what came back. */
.tree-row.asked{grid-template-columns:1fr 108px 124px 96px 124px 84px 104px}
/* An offer being priced on. No "answered" column: every row here is one. */
.tree-row.offer{grid-template-columns:1fr 96px 124px 84px 104px 128px}

/* The correspondence rows carry prose, not columns. */
.tree-row.free{display:flex;align-items:center;gap:10px}

@media(max-width:1100px){
  .tree-row.asked{grid-template-columns:1fr 96px 112px 88px 112px}
  .tree-row.offer{grid-template-columns:1fr 88px 112px 76px}
}
/* A part with nobody asked is what the step machine now refuses to move
   past, so it is coloured like the refusal it will cause. */
.tree-none{padding:10px 12px 10px 30px;border-top:1px solid var(--line);
  background:var(--warn-wash);color:var(--warn);font-size:13px}
@media(max-width:640px){
  .tree-part,.tree-row{flex-wrap:wrap}
  .tree-row{padding-left:18px}
}

/* ── who was asked: the table ──────────────────
   Parts as rows, the suppliers asked about each folded under it, as wide
   as the page. The candidates used to hold a column of their own on
   every visit; they now open beside the part they are about (.drawer
   below), and the table has the width back. One set of tracks for the
   caption and every part row, so the headings sit over their figures. */
.ask{margin:0;padding:0;list-style:none;
  /* fold · part · qty · asked · answered · status · action · menu. The
     action track is empty on a part row and holds Remind or Update on a
     supplier row; reserved on both so the menus line up. */
  --ask-cols:34px minmax(0,1fr) 88px 104px 104px 210px 100px 40px}
.ask .r{text-align:right}
.ask-head{display:grid;grid-template-columns:var(--ask-cols);column-gap:12px;align-items:center;
  padding:0 0 8px;font-size:13px;font-weight:500;color:var(--ink-3);border-bottom:1px solid var(--line)}
.ask-part{border-bottom:1px solid var(--line)}
.ask-part:last-child{border-bottom:0}
.ask-row{display:grid;grid-template-columns:var(--ask-cols);column-gap:12px;align-items:center;
  padding:9px 0}
.ask-row[aria-current="true"] .ask-name .pn{color:var(--accent-2)}
.ask-name{display:flex;flex-direction:column;align-items:flex-start;gap:1px;min-width:0;
  justify-self:start;max-width:100%;
  padding:2px 6px;margin-left:-6px;border:0;border-radius:var(--r-s);background:none;
  color:var(--ink);font:inherit;text-align:left;cursor:pointer}
button.ask-name:hover{background:var(--soft)}
div.ask-name{cursor:default}
/* A row that belongs to another part's price: still there to compare
   against, but not the one in hand. */
.ask-sup.dim{opacity:.55}
.ask-sup.dim:hover{opacity:1}
.ask-name .pn{font:600 14.5px/1.4 var(--mono)}
.ask-name>span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ask-row .num{font-size:14px}
/* The two small round controls a row carries: the fold and the menu. */
.fold,.dots{width:30px;height:30px;border:1px solid var(--line-2);border-radius:50%;
  background:var(--panel);color:var(--ink-2);cursor:pointer;display:grid;place-items:center;
  padding:0;font:600 16px/1 inherit}
.dots{border-color:transparent;background:transparent}
.fold:hover,.dots:hover{background:var(--soft);color:var(--ink)}
.fold svg{transition:transform .15s}
.fold[aria-expanded="false"] svg{transform:rotate(-90deg)}
.dots[aria-expanded="true"]{background:var(--wash);color:var(--accent-2)}
.ask-rows{margin:0 0 10px 46px;padding:0;list-style:none}
.ask-rows[hidden]{display:none}
/* A supplier under the part: a block with a rule down its side, so the
   eye reads it as belonging to the row above rather than as a row of
   the table — and on the table's own tracks, so its figures sit under
   the headings that name them. The block starts 46px in and its right
   edge is the table's, so the fixed tracks on the right coincide by
   construction; the flexible first one absorbs the inset. */
.ask-sup{display:grid;grid-template-columns:var(--sup-cols,minmax(0,1fr) 88px 220px 210px 100px 40px);
  column-gap:12px;align-items:center;margin:0 -1px 6px 0;padding:4px 0;
  border:1px solid var(--line);border-left:3px solid var(--accent);border-radius:var(--r-s);
  background:var(--soft)}
/* The selecting button spans the four fact columns as a subgrid: its
   cells are laid on the parent's tracks, not on tracks of its own. */
.ask-pick{grid-column:1/var(--pick-end,5);display:grid;grid-template-columns:subgrid;align-items:center;
  min-width:0;padding:5px 0 5px 12px;border:0;background:none;color:var(--ink);
  font:inherit;text-align:left;cursor:pointer;border-radius:5px 0 0 5px}
.ask-pick:hover{background:var(--sunk)}
.ask-pick[aria-pressed="true"]{background:var(--wash)}
.ask-pick>*{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Prefixed: .who and .nm are the person in the top bar, and a bare class
   here inherited its height and centring. */
.ask-who{display:flex;flex-direction:column;gap:1px}
.ask-nm{font-weight:600;overflow:hidden;text-overflow:ellipsis}
.ask-nm .small{font-weight:400;margin-left:8px}
.ask-said{display:flex;align-items:center;gap:8px}
.ask-pick .num{font:400 13.5px/1.4 var(--mono)}
.ask-pick .short{color:var(--warn);font-weight:600}
.ask-sup>.btn{justify-self:start}
.ask-more{display:flex;align-items:center;justify-content:space-between;padding:2px 0 0}
.ask-more .btn{padding-left:6px;padding-right:6px;margin-left:-6px}
/* A part with nobody asked is what the step machine refuses to move
   past, so it is coloured like the refusal it will cause. */
.ask-note{display:flex;align-items:center;gap:10px;margin:0 0 8px;padding:10px 14px;
  border-radius:var(--r-s);background:var(--warn-wash);color:var(--warn);font-size:13.5px}
.ask-note svg{flex:none}
.ask-none{padding:12px 0}
.fld input[readonly]{background:var(--sunk);color:var(--ink-2);border-color:transparent}
/* A field that needs the room of two — a supplier's name and the part it
   is about do not fit in one column without being cut. */
@media(min-width:640px){.form>.fld-2{grid-column:span 2}}
/* A button drawn in the accent, without being filled by it — the second
   of two actions in a header, next to the first. */
.btn-line{border-color:var(--accent);color:var(--accent)}
.btn-line:hover{background:var(--wash)}
.btn .i{width:15px;height:15px;flex:none;fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round}
@media(max-width:1180px){
  .ask{--ask-cols:34px minmax(0,1fr) 72px 88px 88px 170px 96px 36px;
    --sup-cols:minmax(0,1fr) 72px 188px 170px 96px 36px}
}

/* ── pricing: the offers and the quotation ─────
   The same table twice over, with the price columns the step needs:
   fold · part · qty · price each · condition · status · action · menu on
   the offers, and qty · price each · margin · line total on the quotation.
   An offer row is a subgrid over the first five tracks. */
.ask.offers{--ask-cols:34px minmax(0,1fr) 88px 130px 70px 200px 110px 40px;
  --sup-cols:minmax(0,1fr) 88px 130px 70px 200px 110px 40px;--pick-end:6}
.ask .short{color:var(--warn);font-weight:600}
/* ── sourcing: the parts and the calculator ────
   The parts on the left, laid out as the quotation on the next step
   (table.kp.quote), with the document's card under them; the calculator
   on the right, at a fixed width. */
.src-grid{display:grid;grid-template-columns:minmax(0,1fr) 500px;gap:14px;align-items:start}
table.kp.quote tbody tr[data-row]{cursor:pointer}
table.kp.quote tbody tr[data-row]:hover td{background:var(--soft)}
table.kp.quote tbody tr[aria-selected="true"] td{background:var(--wash)}
/* Taken out of the reckoning: readable, and plainly not counted. */
table.kp.quote tbody tr.out td{background:color-mix(in srgb,var(--crit) 12%,transparent);color:var(--ink-3)}
table.kp.quote tbody tr.out:hover td,table.kp.quote tbody tr.out[aria-selected="true"] td{
  background:color-mix(in srgb,var(--crit) 20%,transparent)}
table.kp.quote tbody tr.out .num.b{text-decoration:line-through}
/* The calculator. Three fields to a row, short controls and no prose
   under them: the whole form, totals and button included, fits a screen
   of ordinary height beside the table. */
.card.calc{padding:16px 18px}
.calc .dsub{margin:0 0 4px;padding-top:0;border-top:0;font-size:13px}
.calc .fld{margin-bottom:6px}
.calc .fld label{font-size:12px;margin-bottom:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.calc .fld label .muted{font-weight:400}
.calc .fld input,.calc .fld select{height:32px;padding:0 9px;font-size:13.5px}
.calc-in{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0 10px}
.calc-in .fld-2{grid-column:span 2}
.calc-price input{font-weight:600}
/* A link drawn as a button, switched off: nothing to download yet. */
a.btn.disabled{opacity:.45;pointer-events:none}
/* Three figures of the same shape — a label, the number, a line under
   it — aligned at the top so the labels sit on one line whatever is
   written beneath them. */
.calc-out{display:flex;align-items:flex-start;gap:14px;flex-wrap:wrap;margin-top:4px;
  padding-top:10px;border-top:1px solid var(--line)}
/* The figure is never cut; the note under it may be, and carries its
   whole text in the tooltip. */
.calc-sum{display:grid;grid-template-rows:16px 24px auto;gap:0;min-width:0}
.calc-sum small{overflow:hidden;text-overflow:ellipsis;max-width:130px}
.calc-out .btn{margin-left:auto;align-self:center}
.calc-sum>span{font-size:12px;color:var(--ink-3);white-space:nowrap}
.calc-sum b{font:600 17px/24px var(--mono);white-space:nowrap}
.calc-sum small{font-size:11.5px;white-space:nowrap}
#o_profbox b{color:var(--ok)}
#o_profbox.loss b{color:var(--crit)}
#o_linebox.loss small{color:var(--crit)}
/* A warning takes a line of its own under the figures rather than
   pushing the button off theirs. */
.calc-out .note{margin:0;flex-basis:100%}
@media(max-width:1100px){
  .src-grid{grid-template-columns:minmax(0,1fr)}
}

/* ── the panel of candidates ───────────────────
   Over the page rather than beside it. The table keeps its width, the
   veil says the rest of the page is waiting, and one click on it puts
   the panel away. Not a <dialog>: a modal takes the keyboard from the
   page, and the table under it is what the reader is checking against. */
.veil{position:fixed;inset:0;z-index:40;background:rgb(21 29 38/.28)}
.veil[hidden]{display:none}
.drawer{position:fixed;top:0;right:0;bottom:0;z-index:41;width:min(460px,100vw);
  display:flex;flex-direction:column;background:var(--panel);color:var(--ink);
  border-left:1px solid var(--line);box-shadow:0 8px 32px rgb(20 35 55/.12)}
.drawer[hidden]{display:none}
.drawer header{padding:20px 22px 0;border-bottom:1px solid var(--line)}
.drawer header h2{font-size:19px}
.drawer header .ghost{margin:-5px -8px 0 0}
.drawer-body{flex:1;overflow:auto;padding:12px 22px 18px}
.drawer footer{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:14px 22px;border-top:1px solid var(--line);background:var(--soft)}
.drawer .btn-go:disabled{opacity:.5;cursor:default}
.dr-scope{display:flex;align-items:center;gap:7px;margin-right:auto;font-size:13px;
  color:var(--ink-2);cursor:pointer;white-space:nowrap}
.dr-scope input{width:16px;height:16px;margin:0;accent-color:var(--accent)}
.dr-scope[hidden]{display:none}
.dtabs{display:flex;gap:2px;margin-top:12px}
.dtabs button{height:40px;padding:0 12px;border:0;border-bottom:2px solid transparent;
  background:none;color:var(--ink-2);font:500 14px/1 inherit;cursor:pointer;
  border-radius:var(--r-s) var(--r-s) 0 0}
.dtabs button:hover{color:var(--ink);background:var(--soft)}
.dtabs button[aria-selected="true"]{color:var(--accent);border-bottom-color:var(--accent);
  background:var(--wash)}
.dsub{margin:18px 0 4px;padding-top:14px;border-top:1px solid var(--line);
  font-size:13.5px;font-weight:600;color:var(--ink)}
.pick{margin:0;padding:0;list-style:none}
.pick li{display:flex;align-items:center;gap:12px;padding:9px 0;border-top:1px solid var(--line)}
.pick li:first-child{border-top:0}
.pick label{display:flex;align-items:flex-start;gap:12px;flex:1;min-width:0;cursor:pointer}
.pick label>span{display:flex;flex-direction:column;min-width:0}
.pick input[type="checkbox"]{width:18px;height:18px;margin:2px 0 0;flex:none;accent-color:var(--accent)}
.pick .nm{font-weight:500}
.pick .st{font-size:13px;color:var(--ink-3)}
.pick li.done{opacity:.7}
.pick li.done label{cursor:default}
.pick li.muted{display:block;padding:12px 0}

/* ── the quotation step ────────────────────────
   Totals under the table, and the document on a panel wide enough for a
   page, drawn as paper: white, margins, the letterhead's type. */
.kp-totals{display:flex;align-items:baseline;gap:28px;justify-content:flex-end;
  margin-top:14px;padding-top:12px;border-top:1px solid var(--line)}
.kp-totals>span:first-child{margin-right:auto}
.kp-total{display:flex;align-items:baseline;gap:10px}
.kp-total b{font:600 16px/1.3 var(--mono)}
.kp-grand span{font-weight:600;letter-spacing:.04em;font-size:13px}
.kp-grand b{font-size:20px}
table.kp.quote td .chip{margin-top:4px;font-size:12px;padding:2px 8px}
table.kp.quote td s{opacity:.7}
/* Documents the customer held before the current one. */
/* The quotations sent: one row each, the current one marked. */
.papers-t{width:100%;border-collapse:collapse}
.papers-t td{padding:9px 12px 9px 0;border-top:1px solid var(--line);font-size:13.5px;vertical-align:middle}
.papers-t tr:first-child td{border-top:0}
.papers-t tr.now td{font-weight:500}
.papers-t tr.old td{color:var(--ink-3)}
.papers-t td.r{text-align:right;white-space:nowrap}
.papers-t td .num{font-family:var(--mono)}
/* The inquiry on step 1 and the quotation on step 4 are one table twice
   over, laid out the same way: fixed tracks, tight gutters, and the
   prose cells cut or wrapped rather than deciding the width. */
table.kp.quote,table.kp.inquiry{table-layout:fixed}
table.kp.quote th,table.kp.quote td,
table.kp.inquiry th,table.kp.inquiry td{padding-right:12px;font-size:13.5px;overflow:hidden}
/* One line, cut with an ellipsis; the whole of it is in the tooltip. */
table.kp.quote td.cell-clip,table.kp.inquiry td.cell-clip{white-space:nowrap;text-overflow:ellipsis}
/* Two lines at most, then cut; the whole of it is in the tooltip. On an
   element inside the cell, not the cell: a cell that stops being a cell
   takes the row with it. */
table.kp .clamp{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;white-space:normal;line-height:1.35}
/* Editable cells keep the height of the field that replaces them; the
   description, which is not edited here, sits at the same height. */
table.kp.inquiry td.editable:hover{box-shadow:inset 0 0 0 1px var(--line-2)}
table.kp.inquiry .lookup{white-space:normal}
table.kp.quote td .short{display:block;white-space:nowrap}
table.kp.quote .dots{margin-left:auto}
.drawer.wide{width:min(820px,100vw)}
.drawer-paper{background:var(--sunk);padding:22px}
.doc{background:#fff;color:#151d26;padding:34px 38px;border:1px solid var(--line);
  border-radius:4px;font:400 13px/1.45 "IBM Plex Sans",system-ui,sans-serif;
  box-shadow:0 8px 24px rgb(20 35 55/.08)}
.doc .mono{font-family:var(--mono);font-variant-numeric:tabular-nums}
.doc .r{text-align:right}
.doc-muted{color:#5b6b7a;font-size:12px}
.doc-head{display:flex;justify-content:space-between;gap:24px;padding-bottom:12px;
  border-bottom:2px solid #151d26;margin-bottom:16px}
.doc-brand{font-size:19px;font-weight:600;letter-spacing:-.01em;margin-bottom:3px}
.doc-kind{text-align:right}
.doc-title{font-size:12px;font-weight:600;letter-spacing:.08em;color:#5b6b7a}
.doc-num{font:600 16px/1.4 var(--mono)}
.doc-label{font-size:11px;letter-spacing:.06em;color:#5b6b7a}
.doc-name{font-weight:600;font-size:14px}
.doc-to{margin-bottom:18px}
.doc-table{width:100%;border-collapse:collapse;font-size:12.5px}
.doc-table th{font-size:10.5px;letter-spacing:.06em;color:#5b6b7a;font-weight:500;text-align:left;
  padding:0 10px 6px 0;border-bottom:1px solid #8d9aa6;white-space:nowrap}
.doc-table td{padding:7px 10px 7px 0;border-top:0;border-bottom:1px solid #e3e9ee;
  vertical-align:top;white-space:normal;color:#151d26}
.doc-table th:last-child,.doc-table td:last-child{padding-right:0}
.doc-detail{font-size:11px;color:#5b6b7a;margin-top:2px}
.doc-total{display:flex;justify-content:flex-end;align-items:baseline;gap:16px;
  margin-top:8px;padding-top:10px;border-top:2px solid #151d26;font-weight:600}
.doc-total b{font-size:16px}
.doc-terms{display:grid;grid-template-columns:auto 1fr;gap:5px 22px;margin:20px 0 0;font-size:12.5px}
.doc-terms dt{color:#5b6b7a} .doc-terms dd{margin:0}
.doc-sign{margin:34px 0 0 auto;width:220px;padding-top:6px;border-top:1px solid #151d26;text-align:right}
.doc-foot{margin-top:28px;padding-top:8px;border-top:1px solid #e3e9ee;font-size:11px;color:#5b6b7a}
/* The company's order form on screen, drawn as the Excel sheet is:
   the heading line, the two parties side by side, the gridded table,
   the terms as label-and-value lines, the signature and the date. */
.doc-form{font-size:13px}
.form-title{text-align:center;font-weight:700;font-size:15px;letter-spacing:.02em;margin-bottom:22px}
.form-parties{display:grid;grid-template-columns:1fr 1fr;gap:24px;margin-bottom:22px}
.form-party>div{margin-bottom:3px}
.form-party .doc-name{margin-bottom:6px}
.form-addr{white-space:pre-line;max-width:34ch}
.form-table{width:100%;border-collapse:collapse;font-size:12.5px;margin-bottom:14px}
.form-table th,.form-table td{border:1px solid #151d26;padding:6px 8px;text-align:center}
.form-table th{font-weight:600;font-size:11.5px}
.form-table td:nth-child(3){text-align:left}
.form-terms{display:flex;flex-direction:column;gap:5px;margin-bottom:26px}
.form-term{display:flex;gap:10px;align-items:baseline}
.form-term>.doc-muted{min-width:190px}
.form-term>b{font-weight:600;min-width:120px;overflow-wrap:anywhere;max-width:52ch}
.form-total{margin-left:auto}
.form-total b{font-size:14px}
.form-sign{display:flex;justify-content:space-between;margin-bottom:18px}
.form-director{text-align:right;font-weight:600}

/* ── the orders step: the paperwork ───────────── */
.drop{display:flex;flex-direction:column;align-items:center;gap:4px;padding:22px;
  border:1.5px dashed var(--line-2);border-radius:var(--r-s);background:var(--soft);
  color:var(--ink-2);cursor:pointer;text-align:center}
.drop.over{border-color:var(--accent);background:var(--wash);color:var(--accent-2)}
.files{list-style:none;margin:12px 0 0;padding:0}
.files li{display:flex;align-items:center;gap:12px;padding:9px 0;border-top:1px solid var(--line)}
.files li:first-child{border-top:0}
.files .file-ico{color:var(--ink-3);display:grid;place-items:center}
.files .file-name{flex:1;min-width:0}
.files .file-name a{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}
.files li.muted{display:block;padding:10px 0}

/* ── the small menu behind ⋮ ──────────────────── */
.pop{position:fixed;z-index:50;margin:0;padding:5px;list-style:none;min-width:210px;
  background:var(--panel);border:1px solid var(--line-2);border-radius:var(--r-s);
  box-shadow:0 12px 28px rgb(21 29 38/.16)}
.pop button,.pop a{display:block;width:100%;padding:8px 10px;border:0;border-radius:5px;
  background:none;color:var(--ink);font:400 14px/1.3 inherit;text-align:left;cursor:pointer;
  text-decoration:none}
.pop button:hover,.pop a:hover,.pop button:focus-visible,.pop a:focus-visible{
  background:var(--wash);text-decoration:none;outline:none}
.pop .danger{color:var(--crit)}

/* ── the conversation with one supplier ────────────
   Sent and received are told apart by a rule down the side and a wash,
   not by sides of the screen. Chat bubbles would say "messenger"; this
   is a record of correspondence that somebody may have to stand behind,
   and it should look like one. */
.feed{margin:0;padding:0;list-style:none;max-height:46vh;overflow:auto}
.msg{border-left:3px solid var(--line-2);border-radius:0 var(--r-s) var(--r-s) 0;
  background:var(--soft);padding:10px 12px;margin-bottom:10px}
.msg-in{border-left-color:var(--accent);background:var(--wash)}
.msg-head{display:flex;flex-wrap:wrap;gap:8px;align-items:baseline;
  font-size:12px;color:var(--ink-2);margin-bottom:6px}
.msg-head .b{color:var(--ink)}
.msg-body{font-size:13.5px;line-height:1.55;overflow-wrap:anywhere}
.msg-body p{margin:0 0 8px}
.msg-body p:last-child{margin-bottom:0}
.msg-flag{color:var(--warn);background:var(--warn-wash);border-radius:4px;padding:1px 6px}

/* The editor. Four controls, because a letter to a supplier is short
   business prose — and because every tag offered here has to survive a
   dozen mail clients on the way. */
.wtools{display:flex;gap:4px;padding:6px;border:1px solid var(--line);
  border-bottom:0;border-radius:var(--r-s) var(--r-s) 0 0;background:var(--soft)}
.wtools button{min-width:30px;height:28px;border:1px solid transparent;
  border-radius:5px;background:none;color:var(--ink-2);cursor:pointer;font-size:13px}
.wtools button:hover{background:var(--panel);border-color:var(--line);color:var(--ink)}
.wbox{min-height:110px;max-height:30vh;overflow:auto;padding:10px 12px;
  border:1px solid var(--line);border-radius:0 0 var(--r-s) var(--r-s);
  background:var(--panel);font-size:13.5px;line-height:1.55}
.wbox:empty::before{content:attr(data-placeholder);color:var(--ink-3)}
.wbox p{margin:0 0 8px}
/* Where the Cyrillic is. Pointing at it is the whole difference between
   a message a person can act on and a count they cannot. */
.wbox mark{background:var(--crit-wash);color:var(--crit);
  box-shadow:0 0 0 1px var(--crit) inset;border-radius:3px;padding:0 2px}


/* The remaining two steps, on the same grid discipline: what was quoted
   and what came back, and what was ordered from whom. */
.tree-row.answer{grid-template-columns:1fr 168px 124px 168px}
.tree-row.order{grid-template-columns:1fr 124px 124px 148px}
@media(max-width:1100px){
  .tree-row.answer{grid-template-columns:1fr 148px 112px}
  .tree-row.order{grid-template-columns:1fr 112px 132px}
}

/* One caption row for a list of parts, naming what the columns hold.
   It wears the row's own classes, so the tracks are the row's tracks
   rather than a second copy that would drift the first time one changed.
   Only the appearance is overridden here. */
.tree-head{border-bottom:1px solid var(--line)}
.tree-row.is-head{padding-bottom:8px;align-items:end;cursor:default;
  font-size:12px;font-weight:500;color:var(--ink-3)}
.tree-row.is-head:hover{background:none}
/* Captions over numeric columns sit where the numbers do. */
.tree-row.offer.is-head>*:nth-child(2),.tree-row.offer.is-head>*:nth-child(3),
.tree-row.quoted.is-head>*:nth-child(2),.tree-row.quoted.is-head>*:nth-child(3),
.tree-row.quoted.is-head>*:nth-child(4),.tree-row.quoted.is-head>*:nth-child(5){
  text-align:right}

/* A part already in the quotation, with the offer it was priced on. */
.tree-row.quoted{grid-template-columns:1fr 96px 124px 84px 136px}
@media(max-width:1100px){
  .tree-row.quoted{grid-template-columns:1fr 88px 112px 76px 120px}
}
/* An empty list says so in plain words rather than as a warning: nothing
   has gone wrong, there is simply nothing in it yet. */
.tree-none.plain{background:var(--soft);color:var(--ink-2)}

/* A certificate, one per part: the document, then who put it there.
   Fixed tracks, like every other tree — `fr` and `minmax(…,auto)` are
   sized against the content of their own grid, so the caption and the
   rows would each pick their own widths and never line up. */
.tree-row.cert{grid-template-columns:1fr 72px 108px 148px}
@media(max-width:1100px){
  .tree-row.cert{grid-template-columns:1fr 72px 108px}
}
/* The file name is a link, but the row is not: it should read as part of
   the line until it is pointed at. */
.tree-row.cert a.who{color:inherit;text-decoration:none}
.tree-row.cert a.who:hover{color:var(--accent);text-decoration:underline}

/* One hop of a journey: where it went, on what paperwork, and what can
   still be said about it. */
.hop{display:flex;align-items:flex-start;gap:12px;padding:12px 0;
  border-top:1px solid var(--line)}
.hop:first-child{border-top:0}

/* One grid for the list and for what opens under it.
   The two panels and the table above them share their column widths, so
   the three read as one thing: a date sits under a part number, a price
   under the last price paid, a count under a count. Percentages and a
   fixed layout, because an automatic table sizes its columns from its
   own contents — three tables would each pick their own and none of
   them would line up. It also stops the columns jumping about as you
   page through the list. */
.parts-grid{table-layout:fixed}
.parts-grid th:nth-child(1),.parts-grid td:nth-child(1){width:17%}
.parts-grid th:nth-child(2),.parts-grid td:nth-child(2){width:22%}
.parts-grid th:nth-child(3),.parts-grid td:nth-child(3){width:11%}
.parts-grid th:nth-child(4),.parts-grid td:nth-child(4){width:7%}
.parts-grid th:nth-child(5),.parts-grid td:nth-child(5){width:12%}
.parts-grid th:nth-child(6),.parts-grid td:nth-child(6){width:12%}
.parts-grid th:nth-child(7),.parts-grid td:nth-child(7){width:19%}
/* Fixed columns cannot widen for their contents, so the contents have to
   give way instead — otherwise a long description simply runs over the
   column beside it. */
.parts-grid th,.parts-grid td{white-space:normal;overflow-wrap:anywhere}

/* What a part number has been worth before, opened under its own row.
   Two tables, one above the other: what it costs us, then what it
   fetches. Read down a column rather than across a sentence, which is
   why these are tables and not lists — a price has to line up with the
   price two rows above it. */
.past{padding:2px 0 12px;white-space:normal}
.past-side + .past-side{margin-top:16px}
.past h3{margin:0 0 7px;font:500 12px/1.4 inherit;color:var(--ink-3);
  letter-spacing:.04em;text-transform:uppercase}
/* Its own type scale: this is a table inside a row of another table, and
   at the outer size it reads as a second list rather than as detail. The
   right-hand padding matches the outer table's so that the text in a
   column starts where the text above it starts, not merely the column. */
.past-grid{font-size:13px}
.past-grid th{padding:0 24px 6px 0;font-size:12px}
.past-grid td{padding:6px 24px 6px 0;border-top:1px solid var(--line)}
.past-grid th:last-child,.past-grid td:last-child{padding-right:0}
.past-grid tbody tr:first-child td{border-top:0}
.past-grid .chip{padding:2px 8px;font-size:11px}
/* The two facts that ride under the cell they belong to. */
.past-under{color:var(--ink-3);font-size:11.5px;font-weight:400;
  font-family:"IBM Plex Sans",system-ui,sans-serif;margin-top:2px}
.past-more{margin:7px 0 0;font-size:13px;color:var(--ink-3)}
/* The row that is open is marked, so that a panel and its line still
   read as one thing once two of them are open at once.

   Sunk rather than washed: `--wash` is the blue a chip uses to mark an
   offer, and on a washed background those chips vanished — the very
   difference they are there to show, between something offered and
   something that actually changed hands, was invisible on half the rows.
   This grey is also distinct from the hover colour, so an open row and a
   pointed-at row do not read as the same thing. */
tr.open td{background:var(--sunk)}
tr.past-row td{padding-top:0;border-top:0;background:var(--sunk)}

/* The caret is the affordance: without it a row that opens looks exactly
   like a row that navigates, and the first click is a surprise either
   way. It turns rather than swapping glyph, so the movement says which
   way the panel went. */
/* An item flagged since the last look. Marked rather than sorted to the
   top: the list is in the order the deals matter in, and news that has
   jumped the queue is news read out of context. */
.bell-new{position:relative}
.bell-new::before{content:"";position:absolute;left:6px;top:16px;
  width:6px;height:6px;border-radius:50%;background:var(--accent)}
.bell-new{padding-left:20px}

.caret{border:0;background:none;color:var(--ink-3);cursor:pointer;
  font:600 15px/1 var(--mono);padding:0 7px 0 0;transition:transform .12s;
  display:inline-block;transform-origin:35% 50%}
.caret[aria-expanded="true"]{transform:rotate(90deg);color:var(--accent)}
.pn-link{color:inherit;text-decoration:none}
.pn-link:hover{color:var(--accent);text-decoration:underline}

/* The parts table on the first step of a deal, laid out as the КП: every
   cell is one line tall and vertically centred, so the head sits squarely
   over the body; the editable cells carry the same input in the rows and in
   the add row at the foot. Edit and remove are icons at the end of the row. */
.icon-btn{display:inline-flex;align-items:center;justify-content:center;
  width:28px;height:28px;border:0;background:transparent;color:var(--ink-3);
  border-radius:7px;cursor:pointer;vertical-align:middle}
.icon-btn:hover{background:var(--soft);color:var(--ink)}
.icon-btn+.icon-btn{margin-left:2px}
table.kp{width:100%}
table.kp th,table.kp td{vertical-align:middle;white-space:nowrap}
/* Rows keep one height whether a cell is text or a field: the text line is
   as tall as the field that replaces it. */
table.kp tbody td{padding-top:6px;padding-bottom:6px;line-height:34px}
table.kp td.cell-desc{white-space:normal;max-width:260px;line-height:1.35}
/* The quotation: two lines in a cell where the part names what it is
   built on, so the rows are not stretched to a control's height. */
table.kp.quote tbody td{line-height:1.4;padding:10px 12px 10px 0}
table.kp.quote td .short{font-size:12.5px}
/* A cell that may be changed: text until clicked, a hint on hover. */
table.kp td.editable{cursor:text}
table.kp td.editable:hover{background:var(--wash);box-shadow:inset 0 0 0 1px var(--line-2);border-radius:6px}
table.kp td.editing{background:transparent;box-shadow:none}
td.line-acts{text-align:right}
table.kp .cell,table.kp tfoot input,table.kp tfoot select{
  font:inherit;color:var(--ink);background:var(--panel);border:1px solid var(--line);
  border-radius:7px;padding:6px 8px;height:34px;width:100%;min-width:0;box-sizing:border-box}
table.kp .cell.num,table.kp tfoot input.num{font-family:var(--mono)}
table.kp td.r .cell,table.kp tfoot td.r input{text-align:right;max-width:96px}
table.kp .cell-part,table.kp #la_part{min-width:0}
table.kp .cell-terms,table.kp #la_terms{min-width:0}
table.kp .cell:focus,table.kp tfoot input:focus,table.kp tfoot select:focus{
  border-color:var(--focus);outline:none;background:var(--panel)}
table.kp tfoot td{padding:12px 6px;
  border-top:1px dashed var(--line-2);background:var(--sunk)}
/* Breathing room between the inputs and the edge of the grey add-row
   strip. Without it the leftmost input (Part Number) and the rightmost
   button (Добавить) butt right up against the card edge. */
table.kp tfoot td:first-child{padding-left:18px}
table.kp tfoot td:last-child{padding-right:18px}
table.kp .lookup-cell{position:relative}

/* The empty-state row above the parts table on a draft or a fresh
   inquiry. A quiet document glyph on the left, the headline on the
   right, the hint underneath — one block the eye reads as a unit
   rather than a lonely sentence floating in a wide table cell. */
/* The inquiry's parts table follows a per-column pixel spec so the
   description cell can wrap long names across several lines instead of
   clipping. Only this instance is widened: the quotation and the other
   step tables keep their fitted layout. */
table.kp.inquiry{table-layout:auto;min-width:1210px}
table.kp.inquiry th,table.kp.inquiry td{padding:12px 16px;gap:12px}
table.kp.inquiry tbody tr{min-height:76px}
table.kp.inquiry tbody td{line-height:1.4}
table.kp.inquiry td.cell-desc{white-space:normal;max-width:none;min-width:320px;
  word-break:normal;overflow-wrap:anywhere}
table.kp.inquiry td.cell-desc .clamp{display:block;white-space:normal;overflow:visible;
  text-overflow:clip;line-height:1.4}
/* The primary CTA under the inquiry card. The spec puts it at 56px tall
   to anchor the bottom of the step; this picks it out from the ambient
   `.btn-go` without changing buttons elsewhere. */
#p_new .btn[data-go-step="sourcing"]{height:56px;padding-left:24px;padding-right:24px;font-size:15px}
#p_new #la_add{min-width:140px;height:48px;justify-content:center}

/* The paste zone under the parts table. One drop target, framed with a
   dashed border so it reads as a landing pad rather than another card.
   The icon anchors the left; the button sits on the right. */
.paste-zone{display:flex;align-items:flex-start;gap:14px;padding:18px 20px;
  border:1.5px dashed var(--line-2);border-radius:10px;background:var(--sunk)}
.paste-zone-ico{color:var(--ink-3);flex:none;display:inline-flex;margin-top:2px}
.paste-zone-text{flex:1;min-width:0}
.paste-zone-head{margin:0;font-size:14.5px;font-weight:500;color:var(--ink)}
.paste-zone-sub{margin:3px 0 0;font-size:13px;color:var(--ink-3);line-height:1.4}
/* A tiny snippet showing how one line should look. Monospace, muted, and
   sunken a touch so it reads as a sample, not as copy to paste. */
.paste-zone-sample{margin:10px 0 0}
.paste-zone-sample-head{font-size:12px;color:var(--ink-3);margin:0 0 4px}
.paste-zone-sample-row{margin:0;padding:8px 10px;font:12px/1.5 var(--mono);
  color:var(--ink);background:var(--panel);border:1px solid var(--line);
  border-radius:7px;overflow-x:auto;white-space:pre}
.paste-zone>button{align-self:center}

/* The row under the primary CTA that counts what the manager has
   gathered: positions, total units, and the sum the quotation will
   carry. The CTA stays on the left; the totals read as a running tally
   on the right. */
.inquiry-foot{align-items:center;flex-wrap:wrap;gap:16px}
.inquiry-totals{margin-left:auto;display:flex;gap:22px;flex-wrap:wrap;
  color:var(--ink);font-size:14px}
.inquiry-totals b{font-weight:600}

/* The paste-from-sheet modal and its preview. The textarea is one
   stretched input the whole paste lands in; the preview below shows
   what the parser understood, with the rejected rows muted and labelled
   with the reason, so the manager fixes the paste rather than filing
   half a bad batch. */
.paste-modal textarea{width:100%;min-height:140px;padding:10px 12px;font:14px/1.5 var(--mono);
  color:var(--ink);background:var(--panel);border:1px solid var(--line);border-radius:8px;
  box-sizing:border-box;resize:vertical}
.paste-modal textarea:focus{border-color:var(--focus);outline:none}
.pz-preview{margin-top:14px;border:1px solid var(--line);border-radius:8px;overflow:auto;max-height:260px}
.pz-table{width:100%;border-collapse:collapse;font-size:13.5px}
.pz-table th{text-align:left;padding:8px 10px;background:var(--sunk);color:var(--ink-2);
  font-weight:500;font-size:12.5px;letter-spacing:.02em;text-transform:uppercase}
.pz-table th.r,.pz-table td.r{text-align:right}
.pz-table td{padding:8px 10px;border-top:1px solid var(--line-2)}
.pz-table td.num{font-family:var(--mono)}
.pz-table tr.pz-bad td{color:var(--ink-3)}
.pz-table tr.pz-bad td:last-child{color:var(--crit)}
/* The second row of an «… ALT …» split: a quiet background shift and a
   small tag next to the number read it as hanging off the one above. */
.pz-table tr.pz-alt td{background:var(--sunk)}
.pz-table tr.pz-alt td.num{padding-left:22px}
.pz-alt-tag{display:inline-block;margin-left:8px;padding:1px 7px;
  font-family:var(--font);font-size:11px;font-weight:500;
  color:var(--ink-3);background:var(--panel);
  border:1px solid var(--line-2);border-radius:9px;vertical-align:1px}

.empty-lines{padding:22px 20px;text-align:center}
.empty-lines-inner{display:inline-flex;align-items:center;gap:14px;text-align:left}
.empty-lines-ico{display:inline-flex;color:var(--ink-3)}
.empty-lines-head{margin:0;color:var(--ink);font-weight:500;font-size:14.5px}
.empty-lines-sub{margin:3px 0 0;color:var(--ink-3);font-size:13px}
/* The suggestion list is lifted onto the page (see dropUnder) so no
   scrolling box can clip it; it keeps the look of a list under a field. */
.kp-drop{right:auto;top:auto;width:max-content;max-width:min(640px,calc(100vw - 32px));
  z-index:60;max-height:260px;overflow:auto;margin:0;padding:4px;list-style:none;
  background:var(--panel);border:1px solid var(--line);border-radius:9px;
  box-shadow:0 8px 24px rgba(0,0,0,.14);white-space:normal;font-size:14px}
/* The number first, the name after it, both from the left: the list sits
   under the number being typed, so that is where the eye already is. */
.kp-drop li{display:flex;gap:12px;align-items:baseline;padding:7px 9px;border-radius:6px;cursor:pointer}
.kp-drop li span{margin-left:0;text-align:left}
.kp-drop li span.num{font-family:var(--mono);font-weight:600;font-size:14px;white-space:nowrap}
.kp-drop li:hover{background:var(--wash)}
.kp-drop li.none{color:var(--ink-3);cursor:default}
.kp-drop[hidden]{display:none}

/* The developer's organisation switcher. Quiet by design: it is chrome for
   one hidden account, not a feature the product advertises. */
.dev-switch{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--ink-3)}
.dev-switch span{white-space:nowrap}
.dev-switch select{font:inherit;color:var(--ink);background:var(--sunk);
  border:1px solid var(--line);border-radius:7px;padding:4px 8px;max-width:190px}
