/*
 * The one stylesheet of the app. Mobile first: what is written without @media is the phone, the blocks at the end widen it
 * for a computer (from 900px). Colors only through the variables below; nothing is loaded from anywhere (system font).
 * Python analogy: this is the one "base template" every page inherits from; the pages themselves carry classes, not styles.
 */
:root {
  --bg: #fbf7f0;
  --card: #fffdf9;
  --line: #efe7da;
  --text: #1b2421;
  --muted: #8a8378;
  --accent: #f2b155;
  --accent-strong: #d9822b;
  --ok: #2f9e44;
  --wait-bg: #fdebd3;
  --wait-text: #a85d12;
  --danger: #c92a2a;
  --danger-bg: #fdecea;
  --bubble-in: #f2ebdf;
  --bubble-out: #fde9cc;
  --tick: #3d8bd4; /* ✓ and ✓✓: sent and read, one calm blue */

  --tabbar-h: 58px;
  --tabbar-w: 92px;
  --radius: 12px;
  --tap: 44px; /* the least height of a button or a field: a finger */
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.4 -apple-system, BlinkMacSystemFont, system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  /* the content must not go under the bottom tab bar (nor under the iPhone's home bar) */
  padding-bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
}

main {
  padding: 12px 16px;
  padding-left: max(16px, env(safe-area-inset-left));
  padding-right: max(16px, env(safe-area-inset-right));
}

main.narrow { max-width: 420px; margin: 0 auto; padding-top: 32px; padding-bottom: 32px; }
body:not(:has(#tabbar)) { padding-bottom: 0; } /* the login and invitation pages have no tab bar */

h1 { font-size: 22px; line-height: 1.2; margin: 8px 0 16px; }
h2 { font-size: 18px; margin: 24px 0 8px; }
h3 { font-size: 16px; margin: 16px 0 8px; }
p { margin: 8px 0; }
small, .muted { color: var(--muted); }
small { font-size: 13px; }
mark { background: var(--wait-bg); color: var(--wait-text); border-radius: 3px; padding: 0 2px; }
code { overflow-wrap: anywhere; }

a { color: var(--accent-strong); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---------- buttons and fields: at least 44px high ---------- */

/*
 * Buttons come in three ranks. A button is secondary unless marked: --card background, --line border, --text text.
 * .btn-primary (filled with --accent) is the one main action of a screen (Найти, Отправить, Войти...); .btn-text is a bare
 * word (Выйти) in --muted.
 */
button,
input[type="submit"],
input[type="text"], input[type="email"], input[type="password"], input[type="date"], input[type="search"],
select, textarea {
  font: inherit;
  font-size: 16px; /* under 16px iOS zooms the page in when a field gets the focus */
  color: var(--text);
  min-height: var(--tap);
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  padding: 8px 12px;
}

button, input[type="submit"] { cursor: pointer; font-weight: 600; padding: 8px 16px; }
button:hover, input[type="submit"]:hover { border-color: var(--accent); }
button:disabled, input[type="submit"]:disabled { opacity: .5; cursor: default; }

.btn-primary { background: var(--accent); border-color: var(--accent); }
.btn-primary:hover { background: var(--accent-strong); border-color: var(--accent-strong); color: #fff; }

/* The small button next to a status ("Отметить полученным"): not taller than a .tag pill. input[type=submit] is more specific than a bare class, hence the selector. */
.inline-form { display: inline; margin: 0; }
input[type="submit"].btn-mini { min-height: 0; font-size: 12px; font-weight: 600; padding: 1px 8px; border-radius: 999px; line-height: inherit; }

.btn-text { background: none; border-color: transparent; color: var(--muted); font-weight: 400; padding-left: 0; }
.btn-text:hover { background: none; border-color: transparent; color: var(--text); text-decoration: underline; }

textarea { width: 100%; resize: vertical; }
input[type="checkbox"] { width: 20px; height: 20px; vertical-align: middle; accent-color: var(--accent-strong); }
:focus-visible { outline: 2px solid var(--accent-strong); outline-offset: 1px; }

/* A form is a row that wraps: fields stretch, the button goes on when there is no room. */
main form { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 8px 0; max-width: 640px; }
main form > p, main form > textarea { flex: 1 1 100%; margin: 0; }
main form > input[type="text"], main form > input[type="email"], main form > input[type="password"],
main form > select { flex: 1 1 200px; min-width: 0; }
main form > p input[type="text"], main form > p input[type="password"], main form > p input[type="email"] { width: 100%; }
main form > p label { display: block; margin-bottom: 4px; }
main form > label { display: inline-flex; align-items: center; gap: 6px; min-height: var(--tap); }
main.narrow form { max-width: none; }

details { margin: 8px 0; }
summary { cursor: pointer; min-height: var(--tap); display: flex; align-items: center; color: var(--accent-strong); }
ul { padding-left: 20px; margin: 4px 0; }

/* ---------- cards ---------- */

.cards { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); margin: 8px 0; }

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 14px;
  min-width: 0;
  overflow-wrap: anywhere;
}
.card > :first-child { margin-top: 0; }
.card > :last-child { margin-bottom: 0; }
.card form { max-width: none; }

.card-link { display: flex; flex-direction: column; gap: 2px; color: var(--text); }
.card-link:hover { text-decoration: none; border-color: var(--accent); }
.card-link small { color: var(--muted); }

/* The big plate of the check mode of the import of the sheet: nothing is written, and nobody may miss it. */
.import-banner { background: var(--wait-bg); color: var(--wait-text); border-radius: var(--radius); padding: 14px 18px; margin: 12px 0; max-width: 640px; font-size: 20px; font-weight: 700; line-height: 1.3; }
.notice { background: var(--wait-bg); color: var(--wait-text); border-radius: var(--radius); padding: 4px 14px; margin: 12px 0; max-width: 640px; }
.public-url { overflow-wrap: anywhere; word-break: break-all; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 13px; margin: 8px 0; }
.read-failed { display: flex; align-items: center; gap: 10px; padding: 6px 14px; margin: 8px 0; }
.track-status { margin: 4px 0 8px; padding-left: 12px; border-left: 3px solid var(--line); }
.note-body { white-space: pre-wrap; overflow-wrap: anywhere; }

.menu { display: grid; gap: 8px; margin: 8px 0 16px; max-width: 640px; }
.menu-item {
  display: flex; align-items: center; min-height: var(--tap);
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 8px 14px; color: var(--text); font-weight: 600;
}
.menu-item:hover { text-decoration: none; border-color: var(--accent); }

/* ---------- marks ---------- */

.badge { display: inline-block; border-radius: 10px; padding: 1px 8px; font-size: 13px; white-space: nowrap; }
.badge-unread { background: var(--accent-strong); color: #fff; }
.badge-wait { background: var(--wait-bg); color: var(--wait-text); }
.badge-danger { background: var(--danger-bg); color: var(--danger); font-weight: 600; }

.photo { max-width: min(320px, 100%); height: auto; border-radius: 8px; }

/* ---------- the chat list and the chat (the screens are reworked in the next steps; here only readable) ---------- */

table { border-collapse: collapse; width: 100%; }
th, td { text-align: left; padding: 8px; border-bottom: 1px solid var(--line); vertical-align: top; }
th { color: var(--muted); font-weight: 600; font-size: 13px; }
.table-wrap { overflow-x: auto; }

/* ---------- the chats: a list of cards, and the chat beside it on a computer ---------- */

main.chats-main { padding: 0; }

/* A phone shows one of the two: the list on /chats, the chat on /chats/{id}. */
.chats-layout.view-list .chat-pane { display: none; }
.chats-layout.view-chat .chat-col { display: none; }

.chat-head {
  position: sticky; top: 0; z-index: 5;
  background: var(--bg); border-bottom: 1px solid var(--line);
  padding: 12px 16px 6px;
  padding-left: max(16px, env(safe-area-inset-left));
  padding-right: max(16px, env(safe-area-inset-right));
}
.chat-head .search-form { margin: 0 0 8px; max-width: none; }

/* The search box: a magnifier inside the field on the left, no button. */
.search-field { position: relative; flex: 1 1 100%; min-width: 0; }
.search-field .icon { position: absolute; left: 12px; top: 50%; width: 20px; height: 20px; transform: translateY(-50%); color: var(--muted); pointer-events: none; }
.search-field input[type="text"] { width: 100%; padding-left: 40px; border-radius: 22px; }

/* One line always; what does not fit is scrolled sideways (no bar), and a soft fade at the right edge says there is more
   (app.js sets .more-right only while something is hidden there). */
.chips { display: flex; flex-wrap: nowrap; gap: 8px; overflow-x: auto; white-space: nowrap; padding: 2px 0 6px; scrollbar-width: none; }
.chips::-webkit-scrollbar { display: none; }
.chips.more-right {
  -webkit-mask-image: linear-gradient(to right, black calc(100% - 32px), transparent);
  mask-image: linear-gradient(to right, black calc(100% - 32px), transparent);
}
.chip {
  flex: none; display: inline-flex; align-items: center; min-height: var(--tap);
  padding: 0 14px; border-radius: 22px; white-space: nowrap;
  background: var(--card); border: 1px solid var(--line); color: var(--text);
}
.chip:hover { text-decoration: none; border-color: var(--accent); }
.chip.active { background: var(--text); border-color: var(--text); color: var(--bg); }

.sync-line { font-size: 12px; color: var(--muted); padding: 0 0 4px; }
.sync-line.problem { color: var(--danger); }

.chat-list { padding: 8px 12px 16px; }
.chat-list .empty { padding: 24px 4px; color: var(--muted); }

.chat-card-wrap { position: relative; margin-bottom: 8px; }
.chat-card {
  display: flex; gap: 12px; align-items: flex-start;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 10px 12px; color: var(--text);
}
.chat-card:hover { text-decoration: none; border-color: var(--accent); }
.chat-card.active { border-color: var(--accent); box-shadow: inset 3px 0 0 var(--accent); }

.chat-thumb { position: relative; flex: none; width: var(--thumb, 52px); height: var(--thumb, 52px); margin: 6px 0 0 6px; }
.chat-thumb-solo { margin: 0; } /* only the interlocutor's picture: no item picture, no corner to leave room for */
.chat-item-img { display: block; width: var(--thumb, 52px); height: var(--thumb, 52px); border-radius: 10px; object-fit: cover; background: var(--line); }
.chat-avatar {
  position: absolute; top: -6px; left: -6px; width: 24px; height: 24px;
  border-radius: 50%; object-fit: cover; border: 2px solid var(--card); background: var(--line);
}
.chat-avatar-big { position: static; width: var(--thumb, 52px); height: var(--thumb, 52px); border: 0; }
.chat-avatar-big.chat-avatar-letter { font-size: 20px; }
.chat-avatar-letter { display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700; color: var(--muted); }

.chat-main { flex: 1 1 auto; min-width: 0; }
.chat-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; }
.chat-name { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-time { flex: none; font-size: 13px; color: var(--muted); }
.chat-time .tick { margin-right: 4px; }
.chat-item, .chat-last { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.chat-item { display: flex; gap: 6px; font-size: 13px; color: var(--muted); }
.chat-item-title { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-item-price { flex: none; font-weight: 600; color: var(--text); }
.chat-last { color: var(--muted); }
.chat-card.unread .chat-last { color: var(--text); font-weight: 700; }
.chat-count {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; height: 22px; padding: 0 6px; border-radius: 11px;
  background: var(--accent-strong); color: #fff; font-size: 12px; font-weight: 600;
}
.chat-tags { margin-top: 4px; }
.chat-card { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; } /* a long press opens the pin menu, not a text selection */
.pin-mark { flex: none; display: inline-flex; margin-left: 6px; color: var(--accent-strong); }
.pin-mark .icon { width: 14px; height: 14px; }
.chat-name { flex: 0 1 auto; }
.chat-row > .chat-name + .pin-mark { margin-right: auto; }
.card-menu {
  position: fixed; z-index: 50; min-width: 200px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 6px 24px rgba(0, 0, 0, .18); padding: 0 12px;
}
.card-menu[hidden] { display: none; }
.card-menu form { margin: 0; max-width: none; }
.card-menu .menu-row { border-bottom: 0; }
.card-menu a.menu-row { color: var(--text); text-decoration: none; }
.card-menu [hidden] { display: none; }
.card-menu-backdrop { display: none; }

/* The "⋯" of a card: only where there is a mouse (it shows on hover, on a keyboard focus and on the open chat). Dressed like a chip
   (--card, --line, --text; the border turns --accent on hover), not like the general button, which is 44px high and has its padding.
   Where it stands: counted from the BOTTOM of the card, so that the height of the rows above (a chat with no item, no price) does not
   matter. The card ends with the preview row and, when the chat waits for an answer, the row of tags under it; the button's middle is the
   middle of the preview row: bottom = the card's padding + the tags row (when there is one) + half of what the preview row is higher
   than the button. The numbers below are the ones the card is built with (.chat-card padding 10px 12px + 1px border, the preview row
   --preview-h = the badge of unread, the tags row = 4px + the 22px badge). */
.chat-card-wrap { --card-pad-bottom: 11px; --preview-h: 22px; --more-w: 29px; --more-h: 26px; --tags-h: 0px; }
.chat-card-wrap:has(.chat-tags) { --tags-h: 26px; }
.chat-card .chat-row:has(> .chat-last) { min-height: var(--preview-h); }
.chat-tags { height: 22px; }
.card-more { display: none; }
@media (hover: hover) and (pointer: fine) {
  .card-more {
    display: flex; align-items: center; justify-content: center; position: absolute; right: 13px;
    bottom: calc(var(--card-pad-bottom) + var(--tags-h) + (var(--preview-h) - var(--more-h)) / 2);
    width: var(--more-w); height: var(--more-h); min-height: 0; padding: 0; border: 1px solid var(--line); border-radius: 8px; box-shadow: none;
    background: var(--card); color: var(--text); font-size: 15px; font-weight: 400; line-height: 1; cursor: pointer;
    opacity: 0; pointer-events: none; /* not there for the mouse while it is not shown (the badge below it can be pointed at) */
  }
  .chat-card-wrap:hover .card-more, .chat-card-wrap:focus-within .card-more, .card-more:focus-visible,
  .card-more[aria-expanded="true"], .chat-card.active + .card-more { opacity: 1; pointer-events: auto; }
  .card-more:hover { border-color: var(--accent); }
  /* The preview ends before the corner for good (not only while the button shows), so that the text does not jump: 13px of the
     padding, the button and 8px of air. The badge, when there is one, takes part of that room itself (22px and its 8px gap). */
  .chat-card .chat-last { margin-right: calc(var(--more-w) + 8px); }
  .chat-card .chat-row:has(> .chat-count) .chat-last { margin-right: 7px; }
  /* The badge of unread messages is in the same corner: it gives way to the button while the button shows. */
  .chat-card-wrap:hover .chat-count, .chat-card-wrap:focus-within .chat-count,
  .chat-card-wrap:has(.card-more[aria-expanded="true"]) .chat-count, .chat-card.active .chat-count { visibility: hidden; }
}

/* A touch screen: the same menu as a sheet at the bottom, over a dimmed list. */
@media (pointer: coarse) {
  #card-menu {
    left: 0 !important; right: 0; top: auto !important; bottom: 0; min-width: 0; z-index: 61;
    border-radius: 14px 14px 0 0; border-bottom: 0; padding: 4px 16px calc(8px + env(safe-area-inset-bottom));
  }
  #card-menu .menu-row { min-height: 52px; }
  .card-menu-backdrop { position: fixed; inset: 0; z-index: 60; background: rgba(0, 0, 0, .35); }
  .card-menu-backdrop:not([hidden]) { display: block; }
}
.chat-more { padding: 16px; text-align: center; color: var(--muted); min-height: 80px; }

/* ---------- the open chat: header on top, the feed scrolling in its own box, the input at the bottom ---------- */

/* The window does not scroll on a chat page: the pane has the height of the screen (minus the tab bar on a phone), so the input
   is always in view and the header never goes away while older messages load. */
/* 100dvh shrinks with the keyboard in Chrome (the viewport meta asks for it); iOS Safari does not shrink it, so app.js puts the
   height of the visible part into --vvh and the smaller of the two wins. With the keyboard open (html.kb) the tab bar is under
   it anyway: it is hidden and the chat takes the whole visible height. */
.chats-layout.view-chat { height: calc(100vh - var(--tabbar-h) - 1px - env(safe-area-inset-bottom)); height: calc(min(100dvh, var(--vvh, 100dvh)) - var(--tabbar-h) - 1px - env(safe-area-inset-bottom)); }
html.kb #tabbar { display: none; }
html.kb body { padding-bottom: 0; }
html.kb .chats-layout.view-chat { height: min(100dvh, var(--vvh, 100dvh)); }
html.kb .composer { padding-bottom: calc(8px + env(safe-area-inset-bottom)); }
.chat-pane { padding: 0; height: 100%; overflow: hidden; }
.pane-body { position: relative; display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); height: 100%; min-height: 0; }
.chat-stack { display: flex; flex-direction: column; min-height: 0; min-width: 0; }

.chat-top {
  position: relative; z-index: 6; flex: none;
  display: flex; align-items: center; gap: 10px;
  background: var(--card); border-bottom: 1px solid var(--line);
  padding: 6px 8px 6px max(4px, env(safe-area-inset-left));
  padding-right: max(8px, env(safe-area-inset-right));
  --thumb: 40px;
}
.chat-back, .chat-menu summary {
  flex: none; width: var(--tap); height: var(--tap); min-height: var(--tap);
  display: flex; align-items: center; justify-content: center; color: var(--text);
}
.chat-back:hover, .chat-menu summary:hover { text-decoration: none; color: var(--accent-strong); }
.chat-top .chat-thumb { margin: 0; }
.chat-top .icon { width: 24px; height: 24px; }
.chat-top-text { flex: 1 1 auto; min-width: 0; }
.chat-top-name { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-top-item { display: block; font-size: 13px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-top-price { font-size: 12px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
a.chat-top-item:hover { color: var(--accent-strong); }

.chat-menu { margin: 0; flex: none; }
.chat-menu summary { list-style: none; cursor: pointer; border-radius: 50%; }
.chat-menu summary::-webkit-details-marker { display: none; }
.chat-menu[open] summary { background: var(--line); }
.chat-menu-panel {
  position: absolute; right: 8px; top: 100%; z-index: 30;
  width: min(320px, calc(100% - 16px)); max-height: 70vh; max-height: 70dvh; overflow-y: auto; overscroll-behavior: contain;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 6px 24px rgba(0, 0, 0, .18); padding: 0 14px 12px;
}
.chat-menu-panel > :first-child { margin-top: 4px; }
.menu-row {
  display: flex; align-items: center; width: 100%; min-height: var(--tap); padding: 0 2px;
  border: 0; border-bottom: 1px solid var(--line); border-radius: 0; background: none;
  color: var(--text); font-size: 16px; font-weight: 400; text-align: left; cursor: pointer;
}
.menu-row:hover { color: var(--accent-strong); text-decoration: none; background: none; }
.chat-menu-panel form { max-width: none; }

#reply-line:empty { display: none; }
#reply-line .reply-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px;
  margin: 0; padding: 6px 12px; background: var(--wait-bg); color: var(--wait-text); font-size: 14px;
}
#reply-line .reply-row form { margin: 0; }
#reply-line input[type="submit"] { min-height: 32px; padding: 2px 12px; font-weight: 400; }
#reply-line .badge-wait { background: none; padding: 0; font-weight: 600; }
#reply-line small { color: var(--wait-text); }

.chat-body { position: relative; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.chat-scroll {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  display: flex; flex-direction: column; padding: 8px 12px;
  padding-left: max(12px, env(safe-area-inset-left)); padding-right: max(12px, env(safe-area-inset-right));
}
.chat-scroll > * { flex: none; }
#messages { display: flex; flex-direction: column; margin-top: auto; } /* a short chat sits at the bottom, like in a messenger */
#messages > #older, #messages > #history-start { text-align: center; padding: 8px 0; }
.chat-empty { margin: auto; color: var(--muted); text-align: center; }

.msg {
  position: relative; max-width: 75%; margin: 2px 0; padding: 6px 10px 4px;
  border-radius: 16px; overflow-wrap: anywhere;
}
.msg[data-dir="in"] { align-self: flex-start; margin-left: 44px; border-bottom-left-radius: 4px; background: var(--bubble-in); }
.msg[data-dir="out"] { align-self: flex-end; border-bottom-right-radius: 4px; background: var(--bubble-out); }

/* The customer's picture beside the last bubble of a row of theirs (--avatar or --letter come from the list, see ChatPages.kt). */
.msg-avatar {
  position: absolute; left: -44px; bottom: 0; width: 36px; height: 36px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background-color: var(--line); background-image: var(--avatar, none); background-size: cover; background-position: center;
  color: var(--muted); font-weight: 700; font-size: 15px;
}
.msg-avatar::after { content: var(--letter, ""); }
.msg[data-dir="in"]:has(+ .msg[data-dir="in"]) > .msg-avatar { visibility: hidden; }

.msg-system { align-self: center; max-width: 85%; margin: 6px 0; padding: 0; text-align: center; font-size: 13px; color: var(--muted); }
.msg[data-dir="in"] + .msg[data-dir="out"], .msg[data-dir="out"] + .msg[data-dir="in"] { margin-top: 8px; }
.msg-text { white-space: pre-line; }
.msg-text a { overflow-wrap: anywhere; word-break: break-word; } /* a long address wraps inside the bubble, it is not cut short */
.msg-link { display: inline-block; margin-top: 2px; font-size: 14px; }
.msg-time { display: block; text-align: right; font-size: 11px; line-height: 1.3; color: var(--muted); margin-top: 2px; }
.tick { color: var(--tick); font-size: 12px; font-weight: 700; letter-spacing: -1px; }
.msg-time .tick { margin-left: 2px; }
.msg .photo { display: block; margin-top: 4px; max-width: 100%; }
.day {
  align-self: center; margin: 10px 0 6px; padding: 2px 10px; border-radius: 10px;
  background: var(--line); color: var(--muted); font-size: 12px;
}

.pending-title { margin: 12px 0 4px; font-size: 13px; font-weight: 400; color: var(--muted); text-align: right; }
.pending {
  max-width: 75%; margin: 4px 0 4px auto; padding: 8px 12px; overflow-wrap: anywhere;
  background: var(--card); border: 1px dashed var(--accent-strong); border-radius: 16px;
}
.pending .msg-text { white-space: pre-line; }
.pending-state { margin-top: 2px; font-size: 12px; color: var(--muted); }
.pending-state.failed { color: var(--danger); }
.pending-mark { font-weight: 700; }
.pending form { display: inline-flex; margin: 6px 6px 0 0; }
.pending input[type="submit"] { min-height: 36px; padding: 4px 14px; }
.pending button[data-local-action] { min-height: 36px; padding: 4px 14px; margin: 6px 6px 0 0; }

.fab {
  position: absolute; right: 16px; bottom: 12px; z-index: 15;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .2);
}
.fab[hidden] { display: none; }

/* The input: always at the bottom. The field grows with the text (app.js), the buttons stay at its bottom edge. */
main form.composer {
  position: relative; flex: none; flex-wrap: wrap; align-items: flex-end; gap: 8px; max-width: none; margin: 0;
  padding: 8px 12px; background: var(--bg); border-top: 1px solid var(--line);
  padding-left: max(12px, env(safe-area-inset-left)); padding-right: max(12px, env(safe-area-inset-right));
}
main form.composer > textarea.composer-text {
  flex: 1 1 0; min-width: 0; width: auto; resize: none; overflow-y: auto;
  min-height: var(--tap); max-height: 150px; padding: 10px 14px; border-radius: 22px; line-height: 1.3;
}
.icon-btn {
  flex: none; width: var(--tap); height: var(--tap); padding: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
}
.icon-btn .icon { width: 22px; height: 22px; }
.plus-btn { color: var(--muted); background: none; }
.plus-btn:hover { border-color: var(--line); color: var(--text); }

/* Chosen photos: a strip over the field (the form wraps, the strip takes the first row), a cross on every picture. */
.photo-strip { order: -1; flex: 1 0 100%; display: flex; align-items: center; gap: 10px; overflow-x: auto; padding: 8px 8px 4px 0; }
.photo-strip[hidden], .photo-error[hidden] { display: none; }
.photo-error { order: -2; flex: 1 0 100%; border-radius: 8px; }
.photo-thumb { position: relative; flex: none; width: 64px; height: 64px; }
.photo-thumb img { width: 100%; height: 100%; object-fit: cover; border-radius: 8px; border: 1px solid var(--line); display: block; }
.photo-remove {
  position: absolute; top: -6px; right: -6px; width: 22px; height: 22px; min-width: 22px; min-height: 22px; box-sizing: border-box; padding: 0; border-radius: 50%;
  line-height: 1; font-size: 16px; display: inline-flex; align-items: center; justify-content: center;
  background: var(--card); color: var(--text); border: 1px solid var(--line);
}
.photo-remove:disabled { opacity: .4; }
.photo-status { flex: none; color: var(--muted); font-size: 14px; padding-left: 4px; }
.composer-count { position: absolute; right: 20px; top: -20px; font-size: 12px; color: var(--muted); background: var(--bg); padding: 0 6px; border-radius: 8px; }
.composer-count.over { color: var(--danger); font-weight: 600; }
.quick-btn { color: var(--accent-strong); }
.quick-btn[aria-expanded="true"] { background: var(--wait-bg); border-color: var(--accent); }
.send-btn { background: var(--accent); border-color: var(--accent); color: var(--text); }
.send-btn:hover { background: var(--accent-strong); border-color: var(--accent-strong); color: #fff; }
.composer-error { flex: none; margin: 0; padding: 6px 12px; background: var(--danger-bg); color: var(--danger); }

/* Quick replies: the panel opens above the input (the replies themselves come later: a `.quick-reply` with `data-text`). */
.quick-panel {
  position: absolute; left: 12px; right: 12px; bottom: 100%; z-index: 20; margin-bottom: 6px;
  max-height: 40vh; max-height: 40dvh; overflow-y: auto;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 6px 24px rgba(0, 0, 0, .18); padding: 8px 12px;
}
.quick-empty { margin: 8px 0; color: var(--muted); text-align: center; }
.quick-reply { display: block; width: 100%; text-align: left; font-weight: 400; margin: 6px 0; line-height: 1.3; padding: 8px 12px; }
.quick-reply strong { display: block; font-weight: 600; }
.quick-preview { display: block; color: var(--muted); font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.quick-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0; }
.quick-actions form { margin: 0; }

.pane-empty { color: var(--muted); }

/* ---------- the panel of the client: a sheet from the bottom on a phone, over the chat from 900px, a column from 1280px ---------- */

.client-panel {
  position: fixed; inset: 0; z-index: 40; display: flex; flex-direction: column; background: var(--bg);
  transform: translateY(100%); visibility: hidden; transition: transform .2s ease, visibility 0s linear .2s;
}
.pane-body.client-open .client-panel { transform: none; visibility: visible; transition: transform .2s ease; }
.client-panel-head {
  flex: none; display: flex; align-items: center; justify-content: space-between; gap: 8px;
  background: var(--card); border-bottom: 1px solid var(--line);
  padding: max(6px, env(safe-area-inset-top)) 8px 6px 16px;
}
.client-panel-body {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 0 16px 24px;
  padding-bottom: max(24px, env(safe-area-inset-bottom));
}
.client-panel-body > :first-child { margin-top: 12px; }
.client-panel form { max-width: none; }

/* ---------- read-only role and owner-only links (classes of <body>, set by the server) ---------- */

body.readonly form[method="post"]:not([action="/logout"]):not([action="/sync/refresh"]):not([action="/push/settings"]) { display: none; }
.push-box button { margin: 4px 8px 4px 0; }
body.no-owner .owner-only { display: none; }

/* ---------- the bottom tab bar ---------- */

#tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
  display: flex;
  background: var(--card);
  border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom); /* the home bar of an iPhone */
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
  view-transition-name: tabbar; /* stays in place while the page below it changes */
}

.tab {
  position: relative; flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  min-height: var(--tabbar-h);
  color: var(--muted); font-size: 11px; line-height: 1.1;
}
.tab:hover { text-decoration: none; color: var(--text); }
.tab[aria-current="page"] { color: var(--accent-strong); font-weight: 600; }
.tab .icon { width: 24px; height: 24px; }
.tab img { width: 26px; height: 26px; border-radius: 6px; opacity: .75; }
.tab[aria-current="page"] img { opacity: 1; outline: 2px solid var(--accent-strong); outline-offset: 1px; }

.count {
  position: absolute; top: 4px; left: calc(50% + 6px);
  min-width: 18px; padding: 0 5px; border-radius: 9px;
  background: var(--accent-strong); color: #fff;
  font-size: 11px; font-weight: 600; line-height: 18px; text-align: center;
}
.count[hidden] { display: none; }

::view-transition-old(root), ::view-transition-new(root) { animation-duration: .15s; }

/* ---------- a computer: the tab bar becomes a narrow column on the left, the content takes the rest ---------- */

@media (min-width: 900px) {
  /* The tab bar is the left column of a grid and sticks to the top of the window with the height of the window, so it never
     ends where a long page ends (and, unlike `fixed`, it takes its own place: nothing to pad around). */
  body:has(#tabbar) { display: grid; grid-template-columns: var(--tabbar-w) minmax(0, 1fr); padding-bottom: 0; }
  body:has(#tabbar) > main { grid-column: 2; grid-row: 1; min-width: 0; }

  #tabbar {
    position: sticky; top: 0; bottom: auto; left: auto; right: auto;
    grid-column: 1; grid-row: 1; align-self: start;
    width: var(--tabbar-w);
    height: 100vh; height: 100dvh;
    flex-direction: column; justify-content: flex-start; gap: 4px;
    border-top: 0; border-right: 1px solid var(--line);
    padding: 12px 0 0;
  }
  .tab { flex: 0 0 auto; min-height: 64px; font-size: 12px; }
  .tab-more { order: -1; margin-bottom: 8px; }  /* the raven goes first, on top */
  .tab img { width: 32px; height: 32px; }
  .count { top: 6px; left: calc(50% + 8px); }

  main { padding: 24px 32px; }
  main.chats-main { padding: 0; }
  main.narrow { padding-top: 64px; }

  /* Two columns: the list (the column scrolls by itself, its search and chips stay on top) and the open chat beside it. */
  .chats-layout { display: grid; grid-template-columns: 360px minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); align-items: start; height: 100vh; height: 100dvh; }
  .chats-layout.view-chat { height: 100vh; height: 100dvh; } /* no tab bar below on a computer: it overrides the phone's height */
  .chats-layout.view-list .chat-pane, .chats-layout.view-chat .chat-col { display: block; }
  .chat-col {
    position: sticky; top: 0; align-self: start;
    height: 100vh; height: 100dvh; overflow-y: auto; overscroll-behavior: contain;
    border-right: 1px solid var(--line);
  }
  .chat-back { display: none; }
  .msg { max-width: 60%; }
  .pending { max-width: 60%; }
  .client-panel {
    position: absolute; inset: 0 0 0 auto; z-index: 35; width: min(380px, 100%);
    border-left: 1px solid var(--line); box-shadow: -6px 0 24px rgba(0, 0, 0, .12);
    transform: translateX(100%);
  }
  .chat-top { padding-left: 14px; }
  .chip { padding: 0 12px; font-size: 15px; } /* the column is 360px wide: a little tighter, still one line (the rest scrolls) */
  .pane-empty { display: flex; align-items: center; justify-content: center; min-height: 60vh; }
  h1 { font-size: 26px; }
  .cards { grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); gap: 16px; }
}

@media (min-width: 1280px) {
  /* The panel is the third column: closed it takes no room. */
  .pane-body { grid-template-columns: minmax(0, 1fr) 0; }
  .pane-body.client-open { grid-template-columns: minmax(0, 1fr) 340px; }
  .client-panel { position: static; width: auto; min-width: 0; overflow: hidden; transform: none; box-shadow: none; z-index: auto; }
  .pane-body:not(.client-open) .client-panel { visibility: hidden; }
}

@media (min-width: 1500px) {
  .cards { grid-template-columns: repeat(auto-fill, minmax(420px, 1fr)); }
}

/* ---------- the photo viewer (PhotoSwipe): above the header, the tab bar and the panels ---------- */
.pswp { --pswp-z-index: 2000; }
a.msg-photo { display: inline-block; }
/* Until the real size of a picture is known it must not be stretched to the size of the markup. */
.pswp__img { object-fit: contain; }
a.msg-photo.msg-photo-loading { cursor: progress; opacity: .6; }

/* ---------- the search strip of a chat: under the header, the hits as a list over the feed ---------- */
.chat-search { position: relative; z-index: 5; flex: none; background: var(--card); border-bottom: 1px solid var(--line); }
.chat-search-row { display: flex; align-items: center; gap: 8px; padding: 6px 8px 6px 14px; }
.chat-search-row > .icon { flex: none; width: 20px; height: 20px; color: var(--muted); }
.chat-search-input { flex: 1 1 auto; min-width: 0; margin: 0; }
.chat-search-results {
  position: absolute; left: 0; right: 0; top: 100%;
  max-height: 55vh; max-height: 55dvh; overflow-y: auto; overscroll-behavior: contain;
  background: var(--card); border-bottom: 1px solid var(--line); box-shadow: 0 8px 20px rgba(0, 0, 0, .15);
}
.chat-search-results .search-note { margin: 0; padding: 8px 14px; font-size: 13px; color: var(--muted); }
.search-hit {
  display: block; width: 100%; text-align: left; margin: 0; padding: 8px 14px; border: 0; border-top: 1px solid var(--line);
  border-radius: 0; background: none; color: var(--text); font: inherit; cursor: pointer; min-height: 0;
}
.search-hit:hover { background: var(--line); }
.search-hit small { display: block; color: var(--muted); }
.search-hit-text { display: block; overflow-wrap: anywhere; }
.search-hit .search-hit-note { display: block; font-size: 12px; color: var(--wait-text); }
@keyframes msg-flash { from { box-shadow: 0 0 0 3px var(--accent); } to { box-shadow: 0 0 0 3px transparent; } }
.msg.msg-flash { animation: msg-flash 1.8s ease-out; }

/* ---------- refreshing the chat list: the strip a phone pulls down, the button of a computer, the plate ---------- */
html:has(.chats-layout.view-list) { overscroll-behavior-y: contain; } /* Chrome's own pull-to-refresh must not start beside ours */
.sync-row { display: flex; align-items: center; gap: 8px; }
.sync-row .sync-line { flex: 1 1 auto; min-width: 0; }
.list-refresh {
  display: none; flex: none; width: 28px; height: 28px; min-height: 0; padding: 0; margin: 0 0 4px;
  align-items: center; justify-content: center; border: 0; border-radius: 50%; background: none; color: var(--muted); cursor: pointer;
}
@media (min-width: 900px) { .list-refresh { display: inline-flex; } }
.list-refresh:hover { color: var(--accent-strong); }
.list-refresh:disabled { cursor: progress; opacity: .7; }
.list-refresh .icon { width: 18px; height: 18px; }
.list-refresh.busy .icon, .pull-indicator.spinning .icon { animation: list-spin .8s linear infinite; }
@keyframes list-spin { to { transform: rotate(360deg); } }
.pull-indicator { height: 0; overflow: hidden; display: flex; align-items: center; justify-content: center; transition: height .2s ease; }
.pull-indicator.pulling { transition: none; }
.pull-spinner {
  display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 50%;
  background: var(--card); border: 1px solid var(--line); color: var(--muted);
}
.pull-indicator.ready .pull-spinner, .pull-indicator.spinning .pull-spinner { color: var(--accent-strong); }
.pull-spinner .icon { width: 18px; height: 18px; }
.list-notice { background: var(--wait-bg); color: var(--wait-text); border-radius: var(--radius); padding: 4px 12px; margin: 0 0 8px; font-size: 13px; }

/* ---------- the tab "Заказы": groups by client, the strip of seven steps (docs/mockups/orders-summary-mockup.html, variant А) ---------- */

:root {
  --step-off: color-mix(in srgb, var(--muted) 28%, var(--bg));
  --step-on: var(--ok);
  --step-cur: var(--accent-strong);
  --ok-bg: color-mix(in srgb, var(--ok) 14%, var(--card));
}

/* The chips are links here: a row that scrolls sideways on a phone, wraps on a computer. */
.o-chips { display: flex; gap: 6px; overflow-x: auto; padding-bottom: 4px; margin: 0 0 8px; scrollbar-width: none; }
.o-chips .chip { flex: 0 0 auto; }
.o-chips .chip .n { margin-left: 6px; font-variant-numeric: tabular-nums; opacity: .7; }
.o-chips .chip.zero { color: var(--muted); }
.o-chips .chip.alert:not(.zero) { border-color: var(--danger); color: var(--danger); }
.o-chips .chip.alert.active { background: var(--danger); color: #fff; }

.o-tools { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-start; margin: 0 0 12px; }
.o-found { margin: 0 0 8px; color: var(--muted); }
.o-tools .o-search { flex: 1 1 260px; margin: 0; max-width: none; }
.o-tools .o-search input[type="search"] { flex: 1 1 160px; min-width: 0; }
/* The head: the title on the left, the main action on the right. The form of a new order opens under the button as a panel
   over the list, so that opening it does not push the page around. */
.o-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 8px 0 16px; }
.o-head h1 { margin: 0; }
.o-new-btn {
  display: inline-flex; align-items: center; min-height: var(--tap); padding: 8px 16px; cursor: pointer; margin-left: auto;
  font-weight: 600; color: var(--text); border: 1px solid var(--accent); border-radius: 10px; user-select: none; white-space: nowrap;
}
.o-new-btn:hover { background: var(--accent-strong); border-color: var(--accent-strong); color: #fff; text-decoration: none; }

/* The page "Новый заказ": one column, every field the width of it. */
main.new-order { max-width: 560px; margin-left: auto; margin-right: auto; }
main.new-order form { max-width: none; flex-direction: column; align-items: stretch; }
/* As specific as "main form > input[type=text]" above (a field there grows to 200px in a row; here it is a column, so the 200px would be its height) and later. */
main.new-order form > *, main.new-order form > input[type="text"], main.new-order > input[type="search"] { width: 100%; box-sizing: border-box; min-width: 0; flex: 0 0 auto; }
main.new-order form input[type="submit"].btn-primary { background: var(--accent); border-color: var(--accent); }
main.new-order form input[type="submit"].btn-primary:hover { background: var(--accent-strong); border-color: var(--accent-strong); color: #fff; }
main.new-order > input[type="search"] { margin-bottom: 8px; }
main.new-order .form-error { color: var(--danger); }
main.new-order .o-new-client { margin: 12px 0; }
main.new-order .o-new-client summary { cursor: pointer; font-weight: 600; min-height: var(--tap); display: flex; align-items: center; }
main.new-order .pick-row { overflow-wrap: anywhere; }

.o-grp { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); margin: 0 0 12px; overflow: hidden; }
.o-grp-h {
  display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: baseline;
  padding: 10px 12px; background: var(--bg); border-bottom: 1px solid var(--line);
}
.o-who { font-weight: 600; font-size: 16px; }
.o-who a { color: var(--text); }
.o-contacts { font-weight: 400; font-size: 13px; margin-left: 8px; }
.o-who .o-contacts a { color: var(--muted, var(--text)); }
.o-meta { color: var(--muted); font-size: 13px; }
.o-ship { margin-left: auto; font-size: 13px; display: inline-flex; gap: 6px; align-items: baseline; flex-wrap: wrap; }

.o-grp .tag { display: inline-block; font-size: 12px; padding: 1px 8px; border-radius: 999px; white-space: nowrap; }
.o-grp .tag.warn { background: var(--wait-bg); color: var(--wait-text); }
.o-grp .tag.bad { background: var(--danger-bg); color: var(--danger); }
.o-grp .tag.ok { background: var(--ok-bg); color: var(--ok); }
.o-grp a.tag:hover { text-decoration: none; filter: brightness(.96); }

.o-bar { display: flex; gap: 2px; width: 126px; }
.o-bar i { flex: 1; height: 7px; border-radius: 2px; background: var(--step-off); }
.o-dots { display: flex; gap: 4px; flex: 0 0 auto; }
.o-dots i { width: 8px; height: 8px; border-radius: 50%; background: var(--step-off); }
.o-bar i.on, .o-dots i.on { background: var(--step-on); }
.o-bar i.cur, .o-dots i.cur { background: var(--step-cur); }
.o-cap { font-size: 13px; white-space: nowrap; }
.o-k { color: var(--muted); }

.trk { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; overflow-wrap: anywhere; }
.trk.many { font-family: inherit; font-size: 13px; color: var(--muted); }
.copy { cursor: pointer; border-radius: 4px; }
.copy:hover { background: var(--wait-bg); }
.copy.copied::after { content: "Скопировано"; font-family: inherit; font-size: 11px; margin-left: 6px; color: var(--ok); }

.o-finished { opacity: .6; }
.o-title { color: var(--text); font-weight: 500; }

/*
 * The whole row (a card on a phone, a table row on a computer) opens the order: the title link is stretched over it with
 * ::after. What has its own action (the number, the track that is copied, the tags) lies above the stretched link.
 * Selecting text under it does not work any more; the track stays selectable by its own press (it is copied).
 */
.o-card, .o-table tr { position: relative; }
.o-title::after { content: ""; position: absolute; inset: 0; }
.o-title:focus-visible { outline: none; }
.o-title:focus-visible::after { outline: 2px solid var(--accent-strong); outline-offset: -2px; }
.o-card:hover, .o-table tr:hover td { background: color-mix(in srgb, var(--accent) 7%, var(--card)); }
.o-grp .copy, .o-grp .o-tags, .o-grp .tags a, .o-card .no, .o-table td.no a { position: relative; z-index: 1; }

/* A phone: a card per order, two lines. A computer shows the table instead (below). */
.o-table { display: none; }
.o-card { padding: 10px 12px; border-top: 1px solid var(--line); display: flex; flex-direction: column; gap: 6px; }
.o-card:first-child { border-top: 0; }
.o-row { display: flex; justify-content: space-between; align-items: center; gap: 6px 10px; flex-wrap: wrap; }
.o-row .no, .o-table .no, .o-table .no a { color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.o-tags { display: inline-flex; gap: 4px; flex-wrap: wrap; }
.o-wc { color: var(--muted); font-size: 12px; margin-left: auto; }

@media (min-width: 900px) {
  .o-cards { display: none; }
  .o-table { display: block; overflow-x: auto; }
  .o-chips { flex-wrap: wrap; overflow-x: visible; }
  /* One grid for every client: the columns stand under each other from group to group. */
  .o-table table { width: 100%; border-collapse: collapse; min-width: 860px; table-layout: fixed; }
  .o-table td.no { width: 72px; }
  .o-table td.stat { width: 170px; }
  .o-table td.trk-cell { width: 190px; }
  .o-table td.wc { width: 190px; }
  .o-table td.tags { width: 210px; }
  .o-table td { padding: 9px 12px; border-top: 1px solid var(--line); vertical-align: middle; }
  .o-table tr:first-child td { border-top: 0; }
  .o-table .what small { display: block; }
  .o-table .stat .o-cap { display: block; margin-top: 4px; }
  .o-table .wc { color: var(--muted); font-size: 13px; white-space: nowrap; }
  .o-table .tags .tag { margin: 0 4px 2px 0; }
}

/* ---------- the page of an order (docs/mockups/orders-summary-mockup.html): the head, open tasks, cards of parcels ---------- */

.oh { display: flex; flex-wrap: wrap; gap: 4px 16px; align-items: baseline; }
.oh h1 { margin: 8px 0 4px; }
.oh a { color: var(--text); text-decoration: underline; text-decoration-color: var(--line); }
.o-state { background: var(--wait-bg); color: var(--wait-text); border-radius: 999px; padding: 1px 10px; font-size: 13px; white-space: nowrap; }
.o-sum { color: var(--muted); display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

.o-tasks { display: flex; flex-direction: column; gap: 6px; margin: 8px 0; }
.o-task { font-size: 14px; }
.tag { display: inline-block; font-size: 12px; padding: 1px 8px; border-radius: 999px; white-space: nowrap; }
.tag.warn { background: var(--wait-bg); color: var(--wait-text); }
.tag.bad { background: var(--danger-bg); color: var(--danger); }
.tag.ok { background: var(--ok-bg); color: var(--ok); }

.o-pcard { display: flex; flex-direction: column; gap: 8px; }
.o-pcard .o-row { justify-content: space-between; }
.o-bar-wide { width: 100%; }
.o-kv { display: grid; grid-template-columns: 120px minmax(0, 1fr); gap: 2px 8px; margin: 0; font-size: 14px; }
.o-kv dt { color: var(--muted); }
.o-kv dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.o-actions { margin-top: 4px; }
.o-edit summary { font-size: 14px; }
.o-ship-box { border: 1px dashed var(--line); border-radius: var(--radius); padding: 4px 14px 10px; margin: 12px 0; background: var(--bg); }
.o-ship-box h2 { margin-top: 8px; }
.o-ship-item { margin: 4px 0; }

/* ---------- the tab "Сводка" (docs/mockups/orders-summary-mockup.html) ---------- */

.s-grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.s-panel { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px; min-width: 0; }
.s-wide { grid-column: 1 / -1; }
.s-panel h3 { margin: 0 0 8px; font-size: 13px; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); font-weight: 600; }
.s-counts { display: grid; gap: 8px; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); }
.s-cnt { display: block; border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px; background: var(--bg); color: var(--text); }
.s-cnt:hover { text-decoration: none; border-color: var(--accent); }
.s-cnt b { display: block; font-size: 22px; font-variant-numeric: tabular-nums; }
.s-cnt span { font-size: 12px; color: var(--muted); }
.s-cnt.zero b { color: var(--muted); }
.s-li, .s-src { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; padding: 6px 0; border-top: 1px solid var(--line); font-size: 14px; flex-wrap: wrap; }
.s-li:first-of-type, .s-src:first-of-type { border-top: 0; padding-top: 0; }
.s-r { color: var(--muted); white-space: nowrap; font-size: 13px; }
.s-empty { margin: 4px 0; }
.s-more, .s-note { margin: 6px 0 0; font-size: 13px; }
.s-li a { color: var(--text); font-weight: 500; }

/*
 * The zone under the header of a chat: the open tasks of the client (amber cards) and one chip per open order, in one scrolling line
 * (docs/mockups/chat-context-mockup.html, A). The colors are the tokens of the app; a phone shows one line of a task, a wider screen two.
 */
:root { --task-bg: var(--wait-bg); --task-line: color-mix(in srgb, var(--wait-text) 25%, var(--wait-bg)); }
.ctx { display: flex; flex-direction: column; gap: 5px; padding: 6px 10px; border-bottom: 1px solid var(--line); background: var(--bg); }
.ctx:empty, .pane-body.ctx-hidden .ctx { display: none; }
.ctx-error { margin: 0; font-size: 13px; color: var(--danger); }
.ctx-task {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 0 8px; align-items: start;
  background: var(--task-bg); border: 1px solid var(--task-line); border-radius: 10px; padding: 5px 10px;
}
.ctx-flag { color: var(--wait-text); font-size: 13px; line-height: 18px; }
.ctx-txt { font-size: 13px; line-height: 18px; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1; cursor: pointer; }
.ctx-meta { grid-column: 2; display: flex; flex-wrap: wrap; gap: 0 10px; font-size: 12px; line-height: 16px; color: var(--muted); }
.ctx-meta:empty { display: none; }
.ctx-meta a { color: var(--wait-text); font-weight: 500; }
.ctx-due.over { color: var(--danger); font-weight: 600; }
.ctx-due.today { color: var(--wait-text); font-weight: 600; }
.ctx-act { grid-column: 3; grid-row: 1 / span 2; display: flex; align-items: center; gap: 6px; } /* in a row: "+K" next to "Готово" costs no height */
.ctx-form { margin: 0; max-width: none; }
.ctx button { min-height: 0; font-size: 12px; line-height: 16px; font-weight: 600; padding: 3px 10px; border-radius: 999px; }
.ctx-done { background: var(--card); border-color: var(--task-line); white-space: nowrap; }
.ctx-plus { background: none; border: 0; color: var(--wait-text); padding: 0 2px; }
.ctx-less, .ctx.expanded .ctx-more { display: none; }
.ctx.expanded .ctx-less { display: inline; }
.ctx:not(.expanded) .ctx-task:nth-of-type(n+2) { display: none; }
.ctx.expanded .ctx-txt { -webkit-line-clamp: 2; cursor: default; }
@media (min-width: 600px) { .ctx-txt { -webkit-line-clamp: 2; } }
/* "Задача закрыта · Вернуть": 5 s on screen, then it cannot be pressed or seen and takes no room. */
.ctx-undo { display: flex; align-items: center; gap: 4px; font-size: 12px; color: var(--muted); animation: ctx-undo-fade 5s forwards; }
.ctx-undo .ctx-form { display: inline; }
.ctx-return { background: none; border: 0; color: var(--accent-strong); padding: 0; }
@keyframes ctx-undo-fade {
  0%, 90% { opacity: 1; }
  100% { opacity: 0; visibility: hidden; pointer-events: none; height: 0; overflow: hidden; margin: -5px 0 0; }
}
.ctx-chips { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; }
.ctx-chips::-webkit-scrollbar { display: none; }
.ctx-chip {
  flex: none; display: flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 400; line-height: 16px; white-space: nowrap;
  color: var(--text); background: var(--card); border: 1px solid var(--line); border-radius: 999px; padding: 4px 10px 4px 8px; text-decoration: none;
}
.ctx-chip:hover { text-decoration: none; border-color: var(--accent); }
.ctx-no { color: var(--muted); font-variant-numeric: tabular-nums; }
.ctx-mini { display: flex; gap: 1px; }
.ctx-mini i { width: 5px; height: 6px; border-radius: 1px; background: var(--step-off); }
.ctx-mini i.on { background: var(--step-on); }
.ctx-mini i.cur { background: var(--step-cur); }
.ctx-chip.ghost { color: var(--muted); border-style: dashed; }
.ctx-chip.new { color: var(--accent-strong); border-style: dashed; border-color: var(--accent-strong); font-weight: 600; }

/* "Заказы | Неделя": two sections of one place; the title and the switch sit in one row. (Not `.o-title`: that class is the stretched link of an
   order row, its ::after covers everything around it; it lay over the switch and took the clicks.) */
.o-headline { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.o-switch { display: flex; gap: 2px; background: var(--line); border-radius: 10px; padding: 3px; }
.o-switch a { padding: 6px 12px; border-radius: 8px; color: var(--text); font-size: 14px; }
.o-switch a:hover { text-decoration: none; }
.o-switch a.on { background: var(--card); font-weight: 600; }

/* The screen "Неделя" (docs/mockups/weekly-mockup.html): blocks by the day of arrival, in a block the clients with their parcels. */
.wk-sum { display: block; color: var(--muted); font-size: 14px; margin: 0 0 12px; }
.wk-block { border: 1px solid var(--line); border-radius: 14px; background: var(--card); overflow: hidden; margin: 0 0 16px; }
.wk-bhead { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; padding: 10px 12px; background: var(--bubble-in); border-bottom: 1px solid var(--line); font-size: 14px; }
.wk-bhead label { display: flex; align-items: center; gap: 10px; font-weight: 600; font-size: 16px; }
.wk-cb { width: 22px; height: 22px; accent-color: var(--accent-strong); margin: 0; flex: none; }
.wk-cli { padding: 8px 12px; border-top: 1px solid var(--line); display: flex; flex-direction: column; gap: 3px; }
.wk-bhead + .wk-cli { border-top: 0; }
.wk-chead { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
.wk-who { font-weight: 600; font-size: 15px; color: var(--text); }
.wk-chat { font-size: 13px; }
.wk-paid { display: flex; align-items: center; gap: 8px; margin-left: auto; font-size: 14px; }
.wk-row { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 0 12px; font-size: 13px; }
.wk-trk { grid-column: 1; font-family: ui-monospace, "JetBrains Mono", Menlo, monospace; font-size: 12px; overflow-wrap: anywhere; color: var(--text); }
.wk-w, .wk-c { white-space: nowrap; text-align: right; }
.wk-d { grid-column: 1 / -1; color: var(--muted); }
.wk-row .missing { color: var(--danger); }
.wk-tot { font-size: 13px; color: var(--muted); }
@media (min-width: 900px) {
  .wk-bhead { padding: 12px 18px; }
  .wk-cli { padding: 10px 18px; }
  .wk-row { grid-template-columns: 280px 100px 100px minmax(0, 1fr); gap: 14px; padding: 2px 0 2px 30px; font-size: 14px; }
  .wk-trk { font-size: 13px; }
  .wk-w, .wk-c { text-align: left; }
  .wk-d { grid-column: auto; color: var(--text); }
  .wk-tot { padding-left: 30px; font-size: 14px; }
}

/* The bar "В выгрузку" under the blocks (stays in view, above the tab bar of a phone) and the page of the statement. */
.wk-bar {
  position: sticky; bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + 8px); display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; background: var(--text); color: var(--bg); border-radius: 14px; z-index: 5;
}
.wk-bar-text { font-size: 13px; line-height: 1.3; flex: 1 1 auto; min-width: 0; }
.wk-bar-go { margin-left: auto; flex: none; background: var(--accent); color: var(--text); border: 0; font-weight: 600; padding: 11px 18px; border-radius: 11px; cursor: pointer; font: inherit; font-weight: 600; }
.wk-bar-go:disabled { opacity: .45; cursor: default; }
@media (min-width: 900px) { .wk-bar { bottom: 16px; padding: 14px 18px; } .wk-bar-text { font-size: 15px; } }
.wk-export { max-width: 760px; margin: 0 auto; background: var(--card); border: 1px solid var(--line); border-radius: 16px; padding: 18px; display: flex; flex-direction: column; gap: 12px; }
.wk-ehead { display: flex; align-items: center; gap: 12px; }
.wk-ehead h2 { margin: 0; font-size: 19px; }
.wk-ehead .muted { margin-left: auto; font-size: 14px; }
.wk-statement {
  background: var(--bubble-in); border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; overflow-wrap: anywhere;
  font-family: ui-monospace, "JetBrains Mono", Menlo, monospace; font-size: 13px; line-height: 1.6; color: var(--text);
}
.wk-hint, .wk-warn { font-size: 13px; margin: 0; }
.wk-warn { color: var(--wait-text); background: var(--wait-bg); border-radius: 8px; padding: 6px 10px; }
.wk-ebtns { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.wk-close { padding: 10px 16px; border: 1px solid var(--line); border-radius: 10px; color: var(--text); background: var(--card); }
.wk-close:hover { text-decoration: none; }
.wk-copy { font: inherit; font-size: 15px; border: 1px solid var(--line); background: var(--card); color: var(--text); padding: 10px 16px; border-radius: 10px; cursor: pointer; }
.wk-copy.primary { border: 0; background: var(--accent); font-weight: 600; margin-left: 0; }
.wk-ebtns .wk-copy:first-of-type { margin-left: auto; }

/* The screen "Неопознанные" (parcels of the EasyExpress accounts that are in none of our orders). */
.o-switch a .n { margin-left: 4px; font-variant-numeric: tabular-nums; opacity: .7; }
.un-status { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; margin: 0 0 10px; font-size: 14px; }
.un-refresh, .un-hide-all { margin: 0 0 10px; }
.un-status .un-refresh { margin: 0; }
.un-bad { color: var(--danger); }
.un-flash { font-weight: 600; }
.un-row { border: 1px solid var(--line); border-radius: 12px; background: var(--card); padding: 10px 12px; margin: 0 0 8px; display: grid; gap: 4px; }
.un-main { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; }
.un-track { font-weight: 600; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; overflow-wrap: anywhere; }
.un-status-badge { font-size: 13px; background: var(--bubble-in); border-radius: 999px; padding: 1px 8px; }
.un-about { font-size: 14px; overflow-wrap: anywhere; }
.un-numbers { font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; }
.un-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
a.btn-link { font-size: 12px; font-weight: 600; padding: 1px 10px; border: 1px solid var(--line); border-radius: 999px; background: var(--card); color: var(--text); }
a.btn-link:hover { text-decoration: none; background: var(--bubble-in); }
.un-hidden { margin-top: 18px; }
.un-hidden summary { cursor: pointer; font-weight: 600; margin-bottom: 8px; }


/* client card: the buttons of the contacts, the note, and the picker of "+ Новый заказ" */
.client-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0; }
.client-actions a { text-decoration: none; }
.client-note { white-space: pre-wrap; }
.pick-row { display: block; padding: 6px 0; }
.o-new-client form { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }

/* On a phone the head of "Заказы" is two rows: the title with the button, then the tabs the whole width (the button does not crowd them). */
@media (max-width: 560px) {
  .o-headline h1 { order: 1; flex: 1 1 auto; }
  .o-headline .o-new-btn { order: 2; }
  .o-headline .o-switch { order: 3; flex: 1 1 100%; }
  .o-switch a { flex: 1 1 0; text-align: center; padding: 8px 6px; white-space: nowrap; }
}
