/* Base components of the cabinet. Ported from design/prototype-v2/assets/app.css (v2.1).
   Rules: radius 0, no shadows, 1px lines, no icons except the brand square and the status dot,
   no animations, no chips / tiles / segments / caps labels. Tokens live in tokens.css. */

* { box-sizing: border-box; }
html, body { margin: 0; background: var(--bg); color: var(--fg); }
body { font: var(--fs-base)/1.55 var(--sans); -webkit-font-smoothing: antialiased; }
a { color: inherit; text-underline-offset: 3px; }
code, pre, .mono, input, select, button, textarea, table { font-family: var(--mono); }
code { font-size: 12.5px; background: var(--soft); padding: 1px 5px; }
h1 { font: 500 var(--fs-h1)/1.3 var(--sans); letter-spacing: -0.01em; margin: 0; }
h2 { font: 500 var(--fs-h2)/1.4 var(--sans); margin: 0 0 4px; }
p { margin: 8px 0; }
.muted { color: var(--muted); }
.faint { color: var(--faint); }
.bad { color: var(--bad); }
.small { font-size: var(--fs-small); }
.num { font-variant-numeric: tabular-nums; }
[hidden] { display: none !important; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
:focus-visible { outline: 1px solid var(--line-strong); outline-offset: 2px; }
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: none; } /* the border already shows focus */
#app:focus, .main:focus, h1:focus { outline: none; }
.skip { position: absolute; left: 16px; top: -100px; z-index: 30; background: var(--fg); color: var(--bg); padding: 8px 12px; font: 12.5px var(--mono); text-decoration: none; }
.skip:focus { top: 12px; }
.nw { white-space: nowrap; }

/* ---------- shell (ux-v3 SPEC §2.1, §3, §4.6) ----------
   Desktop: sidebar column (brand, server list, menu) + <main>; the footer of the sidebar (language, «Выйти») comes
   after <main> in the DOM (tab order: menu -> content -> footer) and is put back into the left column by the grid.
   Phone (<= 900): the sidebar is a 52 px top bar (brand + server button), the menu is the bottom bar nav.mbar with
   «Ещё» (a plain list above the bar). <main> and the router's inert copy (.stale) share the same grid cell. */
.shell { display: grid; grid-template-columns: var(--side-w) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) auto; min-height: 100vh; min-height: 100dvh;
  background: linear-gradient(var(--line), var(--line)) calc(var(--side-w) - 1px) 0 / 1px 100% no-repeat; }
.shell > .main { grid-column: 2; grid-row: 1 / span 2; }
/* max-height leaves room for the sticky footer under it (language, «Что нового», «Статус», «Аккаунт», «Выйти»: 152 px), so
   a long menu scrolls inside the column instead of sliding under the footer (changelog review issue 20) */
.side { grid-column: 1; grid-row: 1; align-self: start; position: sticky; top: 0; max-height: calc(100vh - 156px); max-height: calc(100dvh - 156px); overflow-y: auto;
  padding: 22px 14px 12px; margin-right: 1px; display: flex; flex-direction: column; scrollbar-width: thin; scrollbar-color: var(--line) transparent; }
.brand { font: 500 14px var(--mono); padding: 0 10px 22px; display: flex; align-items: center; gap: 8px; text-decoration: none; }
.brand i { width: 10px; height: 10px; background: var(--accent); display: inline-block; flex: none; }

/* server list: open (<= 5 servers, desktop) or a button that unfolds the same list (phone, 6+ servers) */
.switch { position: relative; padding: 0 0 14px; min-width: 0; }
.switch .sw-cur { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 34px; border: 1px solid var(--line); background: none; padding: 6px 10px;
  font: 12.5px/1.4 var(--mono); color: var(--fg); text-align: left; }
.switch .sw-cur:hover, .switch .sw-cur[aria-expanded="true"] { border-color: var(--field); background: none; }
.switch .sw-cur .nm { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.switch .sw-cur::after { content: '\25BE'; color: var(--muted); padding-left: 6px; flex: none; }
.switch .sw-cur[aria-expanded="true"]::after { content: '\25B4'; }
.switch .sw-list { list-style: none; margin: 6px 0 0; padding: 0; display: none; }
.switch .sw-cur[aria-expanded="true"] + .sw-list { display: block; }
.switch .sw-list a { display: flex; align-items: center; gap: 8px; min-height: 32px; padding: 4px 10px; font: 13px/1.35 var(--mono); color: var(--muted); text-decoration: none; }
.switch .sw-list a:hover { color: var(--fg); }
.switch .sw-list li.sw-on > a { color: var(--fg); background: var(--soft); }
.switch .sw-list a .nm { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.switch .sw-list a .q { flex: none; font-size: 11.5px; color: var(--faint); white-space: nowrap; }
.switch .sw-list li.sw-on > a .q { color: var(--muted); }                     /* --faint is below AA on --soft */
.switch .sw-list a.pend { flex-wrap: wrap; row-gap: 0; }
.switch .sw-list a.pend .q { flex-basis: 100%; padding-left: 14px; }          /* «ждёт подключения» on its own line */
.sw-dot { width: 6px; height: 6px; flex: none; background: var(--accent); }
.sw-dot.off { background: var(--faint); }
.sw-dot.pend { background: none; box-shadow: inset 0 0 0 1px var(--faint); }
/* health (f-health): a square at the end of the line, only while something needs a look; no colour (DESIGN rule 3) */
.sw-hw { display: inline-flex; align-items: center; flex: none; }
.sw-hw:empty { display: none; }
.sw-h { width: 6px; height: 6px; flex: none; }
.sw-h.warn { box-shadow: inset 0 0 0 1px var(--fg-2); }
.sw-h.bad { background: var(--fg); }
.sw-hq { display: none; }
@media (max-width: 900px) {   /* phones: the word next to the square in the open list (6 px alone said nothing) */
  .switch .sw-list .sw-hq { display: inline; margin-left: 6px; font-size: 11.5px; color: var(--muted); white-space: nowrap; }
}
/* «+ Добавить сервер»: always the last line; at the quota the same words as quiet text with the reason under them */
.switch .sw-list li.sw-add > a { color: var(--muted); }
.switch .sw-add .sw-off { display: block; padding: 6px 10px 0; font: 12.5px/1.45 var(--mono); color: var(--faint); opacity: .6; cursor: default; }   /* disabled (WCAG 1.4.3 exempts inactive controls) */
.switch .sw-add .sw-hint { display: block; padding: 0 10px 6px; font: 11.5px/1.45 var(--mono); color: var(--faint); }
@media (min-width: 901px) {
  .switch.open .sw-cur { display: none; }
  .switch.open .sw-list { display: block; margin: 0; }
}

/* menu: two groups split by a line; signals are text only (a count at «Журнал», a word at «Telegram») */
.nav a { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 32px; padding: 4px 10px; text-decoration: none; font: 13px var(--mono); color: var(--muted); }
.nav a:hover { color: var(--fg); }
.nav a.on { color: var(--fg); background: var(--soft); }
.nav a .cnt { color: var(--fg); font-size: 12px; font-variant-numeric: tabular-nums; }
.nav a .st { color: var(--faint); font-size: 11.5px; white-space: nowrap; }
.nav a.on .st { color: var(--muted); }
.nav .sep { height: 1px; background: var(--line); margin: 10px 10px; }
.switch + .nav { border-top: 1px solid var(--line); padding-top: 10px; }

/* sidebar footer: language + «Выйти», after <main> in the DOM, sticky at the bottom of the left column */
.side-foot { grid-column: 1; grid-row: 2; align-self: end; position: sticky; bottom: 0; margin-right: 1px; background: var(--bg);
  padding: 12px 24px 22px; display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
/* «Выйти» is a text link everywhere: sidebar, login, invite, 404 */
.out { font: 12px var(--mono); color: var(--muted); background: none; border: 0; padding: 0; text-decoration: underline; text-underline-offset: 3px; text-align: left; cursor: pointer; }
.out:hover { color: var(--fg); background: none; }
.lang { font: 12px var(--mono); color: var(--faint); display: flex; gap: 10px; }
.lang button { font: inherit; color: var(--muted); background: none; border: 0; padding: 0; cursor: pointer; }
.lang button:hover { color: var(--fg); background: none; }
.lang button.on { color: var(--fg); text-decoration: underline; text-underline-offset: 4px; }
/* in the cabinet the language switch is one quiet line, no underline */
.side-foot .lang button { color: var(--faint); }
.side-foot .lang button.on { color: var(--muted); text-decoration: none; }
.side-foot .lang button:hover { color: var(--fg); }
/* «Статус» (the public /status page): the same quiet text link as «Аккаунт» / «Выйти». The footer is 34 px of padding,
   the language row (14 px), a link row each (16 px with Cyrillic) and 10 px between rows: language, «Статус»,
   «Аккаунт», «Выйти» = 126 px, so .side above leaves it 130 px; each further row needs 26 more */
.side-foot .svc-link { font: 12px var(--mono); color: var(--muted); text-decoration: underline; text-underline-offset: 3px; }
.side-foot .svc-link:hover { color: var(--fg); }
/* «Аккаунт» (e-mail login on): the same text link as «Выйти» under it; on /account it is the current page (--fg, no underline) */
.side-foot .acc-link { font: 12px var(--mono); color: var(--muted); text-decoration: underline; text-underline-offset: 3px; }
.side-foot .acc-link:hover { color: var(--fg); }
.side-foot .acc-link.on { color: var(--fg); text-decoration: none; }
/* «Что нового» (changelog SPEC §5.1): the footer link reads like «Аккаунт»; the unread square is the status .dot in its
   neutral form (7 px like .dot, --fg-2, never --accent or --bad). DESIGN rule 1 allows no icon besides the brand
   square, the status dot, the chevron and chart marks: reusing the dot for «unread» is open question 5 (SPEC §16) */
.side-foot .news-link { font: 12px var(--mono); color: var(--muted); text-decoration: underline; text-underline-offset: 3px; }
.side-foot .news-link:hover { color: var(--fg); }
.side-foot .news-link.on { color: var(--fg); text-decoration: none; }
.ndot { display: inline-block; flex: none; width: 7px; height: 7px; margin-left: 8px; background: var(--fg-2); vertical-align: 1px; }
/* «новое» (changelog SPEC §5.5, core/marks.js): one plain word, no frame, no fill, no colour (DESIGN rules 2, 3):
   --fg against the muted line it sits in; «новое: поиск ↓» before the words of a toggle, «Сводки · новое» after a
   label or heading (the « · » in --faint like every separator) */
.nb { font: 400 12px/1 var(--mono); color: var(--fg); white-space: nowrap; letter-spacing: 0; text-decoration: none; }
.nb-s { color: var(--faint); }

/* phone bottom bar and the «Ещё» list (desktop: not shown) */
.mbar { display: none; }

.main { padding: var(--page-top) var(--page-x) 80px; width: 100%; min-width: 0; }
/* safety net: a page without a .pg primitive (player card page, 404) keeps the v2 width instead of stretching to 2560 */
.main:not(:has(> .pg)) { max-width: calc(1040px + 2 * var(--page-x)); }
.main.narrow:not(:has(> .pg)) { max-width: calc(820px + 2 * var(--page-x)); }
.head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: var(--after-head); }
.head .sub { font: var(--fs-cap)/1.7 var(--mono); color: var(--muted); margin-top: 6px; }

/* ---------- page primitives (SPEC §4.2; js/core/layout.js builds them) ----------
   < 1400: one column, the panel above the list (.m-top), after the form (.m-after) or not at all (.m-hide).
   >= 1400: the panel is a second column; >= 2200: the whole block is at most --w-max, centred. */
.pg { max-width: var(--w-max); width: 100%; min-width: 0; }
@media (min-width: 2200px) { .pg { margin-inline: auto; } }
.pg-la, .pg-sa { display: grid; grid-template-columns: minmax(0, 1fr); }
.pg-h { order: 0; min-width: 0; }
.aside.m-top { order: 1; }
.pg-b { order: 2; min-width: 0; }
.aside.m-after { order: 3; }
.aside { min-width: 0; }
.aside.m-hide { display: none; }
.aside.m-top { margin: 0 0 24px; }
.aside.m-after { margin: 40px 0 0; }
.aside-in { min-width: 0; }
@media (min-width: 1400px) {
  .pg-la { grid-template: "head head" auto "body aside" 1fr / minmax(0, 1fr) var(--w-aside); column-gap: var(--gap-aside); }
  .pg-sa { grid-template: "head head" auto "body aside" 1fr / minmax(0, var(--w-settings)) minmax(var(--w-aside), 1fr); column-gap: var(--gap-aside); }
  .pg-la > .pg-h, .pg-sa > .pg-h { grid-area: head; }
  .pg-la > .pg-b, .pg-sa > .pg-b { grid-area: body; }
  .pg-la > .aside, .pg-sa > .aside { grid-area: aside; display: block; margin: 0; border-left: 1px solid var(--line); padding-left: 24px; }
  .aside-in { position: sticky; top: 28px; max-height: calc(100vh - 56px); max-height: calc(100dvh - 56px); overflow: auto; overscroll-behavior: contain; scrollbar-width: thin; scrollbar-color: var(--line) transparent; }
  /* the journal's panel with the marks block (review mqh 03.10): a short list made the grid row only as tall as the
     panel, so the sticky panel moved up with the page and its top (date, nick, the text) left the screen; the cell now
     reaches the viewport's height and the wheel at the panel's end no longer scrolls the page */
  .pg-la > .aside:has(.jr-fb) { min-height: 100vh; min-height: 100dvh; }
  .pg-sa .aside-in { max-width: 720px; }
}
@media (min-width: 1900px) {
  .pg-sa { grid-template-columns: minmax(0, var(--w-form-wide)) minmax(460px, 1fr); }
}
/* settings: table of contents + sections */
.pg-toc { display: grid; grid-template-columns: minmax(0, 1fr); }
.pg-toc > .toc { display: none; }
.pg-toc > .pg-h, .pg-toc > .pg-b { min-width: 0; }
@media (min-width: 1280px) {
  /* the h1 keeps the shared left edge (a full-width head row); the TOC and the sections start under it */
  .pg-toc { grid-template: "head head" auto "toc body" 1fr / 180px minmax(0, var(--w-settings)); column-gap: 48px; }
  .pg-toc > .toc { grid-area: toc; display: block; }
  .pg-toc > .pg-h { grid-area: head; }
  .pg-toc > .pg-b { grid-area: body; }
}
@media (min-width: 1900px) {
  .pg-toc { grid-template-columns: 180px minmax(0, 1fr); }
  .pg-toc > .pg-b.two, .pg-toc .two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 48px; align-items: start; }
}
.pg-read { max-width: var(--w-read); }
.toc .toc-in { position: sticky; top: 28px; font: 12.5px/1.5 var(--mono); }
.toc a { display: block; padding: 5px 0 5px 12px; color: var(--muted); text-decoration: none; border-left: 1px solid var(--line); }
.toc a:hover { color: var(--fg); }
.toc a.on { color: var(--fg); border-left-color: var(--fg); }

/* panel blocks: a heading and 3-6 lines of text and links (never a dashboard) */
.ax { margin-bottom: 28px; }
.ax:last-child { margin-bottom: 0; }
.ax h2 { margin-bottom: 8px; }
.ax .l { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; min-height: 28px; padding: 4px 0; font: 12.5px/1.5 var(--mono); color: var(--muted); text-decoration: none; }
.ax .l .v { color: var(--fg); text-align: right; min-width: 0; overflow-wrap: anywhere; }
.ax a.l { color: var(--fg-2); }
.ax a.l:hover { color: var(--fg); }
.ax a.l .v { color: var(--muted); }
.ax a.l:hover .v { color: var(--fg); }
.ax .l .go { color: var(--muted); flex: none; }
.pg-sa .ax .l { max-width: 460px; }          /* the form panel grows at 1920+: a value stays near its label */
.aside.busy .aside-in { opacity: .45; transition: opacity 0s linear .12s; }   /* old content while the next one loads (I4) */

/* selected row of a list with a panel */
.sel, .sel > summary { background: var(--soft); box-shadow: inset 2px 0 0 var(--fg); }
.sel .t, .sel > summary .t { color: var(--muted); }

/* object tabs inside a module */
.tabs { display: flex; gap: 0 24px; border-bottom: 1px solid var(--line); font: 13px var(--mono); margin-bottom: 16px; overflow-x: auto; scrollbar-width: none; }
.tabs::-webkit-scrollbar { display: none; }
.tabs a { padding: 10px 0 11px; color: var(--muted); text-decoration: none; white-space: nowrap; }
.tabs a:hover { color: var(--fg); }
.tabs a.on, .tabs a[aria-current="page"] { color: var(--fg); box-shadow: inset 0 -1px 0 var(--fg); }
.tabs a .n { color: var(--fg); margin-left: 6px; font-variant-numeric: tabular-nums; }

/* pause presets: «Пауза: 30 мин · 2 ч · сутки» */
.pause { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 0 2px; font: 12.5px var(--mono); color: var(--muted); }
.pause > .muted { margin-right: 6px; }
.pause .link { min-height: 28px; padding: 0 2px; }
.pause .sep::before { content: '\00a0\00b7\00a0'; color: var(--faint); }

/* sections, read-only, danger, confirm */
details.msec > summary { list-style: none; display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
details.msec > summary::-webkit-details-marker { display: none; }
details.msec > summary h2 { margin: 0; }
details.msec > summary .sum { font: 12.5px var(--mono); color: var(--muted); }
details.msec + details.msec { margin-top: 36px; }
details.msec > summary + * { margin-top: 8px; }
.ro { font: 12px var(--mono); color: var(--muted); margin: 0 0 14px; }
select:disabled { opacity: .55; cursor: default; }
.danger { margin-top: 44px; }
.danger > h2 { padding-bottom: 8px; border-bottom: 1px solid var(--line); margin-bottom: 12px; }
.confirm { background: var(--soft); padding: 10px 12px; font: 12.5px var(--mono); color: var(--fg); display: flex; gap: 10px 14px; align-items: center; flex-wrap: wrap; }
.confirm .sp { flex: 1; }
.confirm button { padding: 5px 12px; }
.confirm button:not(.link):not(.primary):not(:disabled):hover { background: var(--bg); }   /* the strip is --soft already: the hover goes darker */
.step .n { font: 13px var(--mono); color: var(--muted); }

/* settings sections (lifted from access.css: bridge, team and settings use them) */
.set { margin-top: 48px; }
.set:first-child { margin-top: 0; }
.set h2 { margin-bottom: 4px; }
.set .lead { color: var(--muted); font-size: 13.5px; margin: 0 0 14px; max-width: 620px; }
.set .rules { margin-top: 4px; }
.set .rule { grid-template-columns: minmax(0, 1fr) auto; min-height: 56px; }
.set .rule .act { display: flex; justify-content: flex-end; }
.set .row { display: flex; gap: 12px 16px; align-items: center; flex-wrap: wrap; margin-top: 16px; font: 12.5px var(--mono); }
.set .row .ask { color: var(--fg); }
.set .inv { max-width: 620px; }
.set .hint { font: 12px/1.7 var(--mono); color: var(--muted); margin-top: 8px; }
.set .cfg { max-width: 620px; }
.set .cfg label { margin-top: 20px; }
.set .cfg .code { margin-top: 0; }
.set .err:empty { min-height: 0; margin: 0; }

/* bare layout: login, invite code, join, 404 */
.bare { min-height: 100vh; min-height: 100dvh; display: grid; place-items: center; padding: 24px 16px; }
.bare .box { width: 100%; max-width: 360px; }
.bare .brand { padding: 0 0 28px; font-size: 15px; }
.bare h1 { margin-bottom: 8px; }
.bare .lead { color: var(--muted); font-size: 13.5px; margin: 0 0 8px; }
.bare form .primary, .bare form button[type=submit] { width: 100%; margin-top: 18px; padding: 10px; }
.bare .alt { margin-top: 28px; font: 12px var(--mono); color: var(--muted); display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.bare .alt a { color: var(--muted); }
/* phone: the language buttons keep their 32 px targets, the labels start on the column edge like the text above */
@media (max-width: 900px) { .bare .alt .lang button { justify-content: flex-start; } }
/* phone: the box starts at the top, so the brand and heading stay put between states (appeal open / sent, 404) */
@media (max-width: 900px) { .bare { place-items: start center; padding-top: var(--s7); } }
.tg { min-height: 40px; margin-top: 8px; }

/* ---------- controls ---------- */
button, .btn { font: 12.5px var(--mono); background: transparent; color: var(--fg); border: 1px solid var(--line-strong); padding: 7px 14px; cursor: pointer; border-radius: 0; text-decoration: none; display: inline-block; line-height: 1.5; }
button:hover, .btn:hover { background: var(--soft); }
button:disabled, .btn[aria-disabled="true"] { opacity: .5; cursor: default; }
button:disabled:hover { background: transparent; }
.primary { background: var(--fg); color: var(--bg); }
.primary:hover { background: var(--fg); opacity: .88; }
.primary:disabled:hover { background: var(--fg); }
.ghost { border-color: var(--line); color: var(--fg-2); }
.ghost:hover { border-color: var(--line-strong); color: var(--fg); }
.link { border: 0; padding: 0; background: none; color: var(--muted); text-decoration: underline; text-underline-offset: 3px; }
.link:hover { background: none; color: var(--fg); }
input, select, textarea { font-size: 13px; color: var(--fg); background: var(--bg); border: 1px solid var(--field); padding: 8px 10px; border-radius: 0; outline: none; width: 100%; }
input:focus, select:focus, textarea:focus { border-color: var(--line-strong); }
input::placeholder, textarea::placeholder { color: var(--faint); }
textarea { resize: vertical; line-height: 1.5; }
select { width: auto; appearance: none; padding-right: 28px; cursor: pointer;
  background: var(--bg) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%238a8a8a'/%3E%3C/svg%3E") no-repeat right 10px center; }
label { display: block; font: 12px var(--mono); color: var(--muted); margin: 16px 0 6px; }
.err { color: var(--bad); font: 12px var(--mono); margin-top: 12px; min-height: 18px; }

/* text switches instead of segmented controls */
.links { font: 12.5px var(--mono); color: var(--faint); display: flex; gap: 6px 16px; flex-wrap: wrap; }
.links a, .links button { color: var(--muted); text-decoration: none; background: none; border: 0; padding: 0; font: inherit; cursor: pointer; }
.links a:hover, .links button:hover { color: var(--fg); background: none; }
.links .on { color: var(--fg); text-decoration: underline; text-underline-offset: 5px; }

/* status */
.dot { display: inline-block; width: 7px; height: 7px; background: var(--accent); margin-right: 8px; vertical-align: 1px; }
.dot.bad { background: var(--bad); }
.dot.off { background: var(--faint); }
.status { font: 12.5px var(--mono); color: var(--muted); margin-top: 8px; }
.status .st { color: var(--fg); }
.status .st.bad { color: var(--bad); }
.todo { font: 13px var(--mono); margin-top: 20px; }
.todo a { color: var(--fg); }
.todo .calm { color: var(--muted); }
.today { font: 12.5px var(--mono); color: var(--muted); margin-top: 6px; }
.today a { color: var(--muted); }
.today a:hover { color: var(--fg); }
.saved { font: 12px var(--mono); color: var(--muted); padding-top: 6px; }

/* ---------- feed rows (Server) ---------- */
.sect { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin: 40px 0 10px; }
.feed { border-top: 1px solid var(--line); font: var(--fs-row)/1.5 var(--mono); }
.msg { display: grid; grid-template-columns: 48px 140px minmax(0, 1fr) auto; gap: 16px; padding: 9px 0; border-bottom: 1px solid var(--line); align-items: baseline; text-decoration: none; }
.msg .t { color: var(--faint); font-variant-numeric: tabular-nums; }
.msg.open .t, .it[open] > summary .t { color: var(--muted); }   /* on --soft --faint drops below 4.5:1 */
.msg .n { color: var(--fg-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msg .x { min-width: 0; overflow-wrap: anywhere; }
.msg .m { color: var(--muted); font-size: 12px; white-space: nowrap; }
a.msg:hover { background: var(--soft); }
.msg.hid .x { color: var(--muted); text-decoration: line-through; text-decoration-color: var(--faint); }
.msg.sys .x { color: var(--muted); }
.foot { font: 12px var(--mono); color: var(--faint); padding: 16px 0; }
.foot a { color: var(--muted); }

/* ---------- journal entries ---------- */
.day { font: 12px var(--mono); color: var(--faint); padding: 28px 0 8px; border-bottom: 1px solid var(--line); }
.day:first-child { padding-top: 0; }
.log { font: var(--fs-row)/1.5 var(--mono); }
.it > summary { list-style: none; cursor: pointer; display: grid; grid-template-columns: 48px 140px minmax(0, 1fr) auto; gap: 16px; padding: 10px 0; border-bottom: 1px solid var(--line); align-items: baseline; }
.it > summary::-webkit-details-marker { display: none; }
.it > summary:hover { background: var(--soft); }
.it .t { color: var(--faint); font-variant-numeric: tabular-nums; }
.it .n { color: var(--fg-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.it .x { min-width: 0; overflow-wrap: anywhere; }
.it .m { color: var(--muted); font-size: 12px; white-space: nowrap; text-align: right; }
.it[open] > summary { border-bottom-color: transparent; background: var(--soft); }
.it.fp .x { color: var(--muted); text-decoration: line-through; text-decoration-color: var(--faint); }
.ctx { background: var(--soft); border-bottom: 1px solid var(--line); padding: 2px 16px 16px 220px; }
.ctx .l { padding: 2px 0; color: var(--muted); overflow-wrap: anywhere; }
.ctx .l b { font-weight: 400; color: var(--muted); margin-right: 10px; }
.ctx .l.me { color: var(--fg); }
.ctx .l.me b { color: var(--fg-2); }
.ctx .meta { margin-top: 14px; display: flex; gap: 10px 16px; align-items: center; flex-wrap: wrap; font-size: 12.5px; color: var(--muted); }
.ctx .meta .sp { flex: 1; }
.ctx .meta button { padding: 5px 12px; }
.ctx .meta a { color: var(--muted); }

/* ---------- rules ---------- */
.rules { border-top: 1px solid var(--line); }
.rule { display: grid; grid-template-columns: minmax(0, 1fr) 220px; gap: 20px; align-items: center; padding: 14px 0; border-bottom: 1px solid var(--line); }
.rule .nm { font: 13.5px var(--mono); }
.rule .ds { font-size: 12.5px; color: var(--muted); margin-top: 2px; }
.rule select { width: 100%; }
.more { border-bottom: 1px solid var(--line); }
.more > summary { list-style: none; cursor: pointer; padding: 14px 0; font: 13px var(--mono); color: var(--muted); }
.more > summary:hover { color: var(--fg); }
.more > summary::-webkit-details-marker { display: none; }
.more > summary::after { content: '\00a0↓'; color: var(--faint); }
.more[open] > summary::after { content: '\00a0↑'; }
.more > .rule:first-of-type { border-top: 1px solid var(--line); }
.more .rule:last-child { border-bottom: 0; }
.probe { margin-top: 56px; max-width: 560px; }
.probe textarea { font-size: 13.5px; }
.probe .row { display: flex; gap: 16px; align-items: baseline; margin-top: 10px; flex-wrap: wrap; font: 12.5px var(--mono); color: var(--muted); }
.probe .row b { font-weight: 400; color: var(--fg); }

/* ---------- connect ---------- */
.steps { border-top: 1px solid var(--line); max-width: 680px; }
.step { display: grid; grid-template-columns: 40px minmax(0, 1fr); gap: 8px; padding: 26px 0; border-bottom: 1px solid var(--line); }
.step .no { font: 13px var(--mono); color: var(--faint); padding-top: 1px; }
.step p { color: var(--muted); margin: 0 0 14px; font-size: 13.5px; }
.step .ver { font: 12px var(--mono); color: var(--faint); margin-left: 12px; }
.code { display: flex; align-items: stretch; border: 1px solid var(--line); background: var(--soft); margin-top: 10px; }
.code pre { margin: 0; flex: 1; min-width: 0; padding: 12px 14px; font-size: 13.5px; line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere; }
.code button { border: 0; border-left: 1px solid var(--line); color: var(--muted); padding: 0 14px; flex: none; }
.wait { font: 13px var(--mono); color: var(--muted); }
.check { margin: 14px 0 0; padding: 0 0 0 18px; color: var(--muted); font-size: 13px; line-height: 1.8; }

/* ---------- admin ---------- */
.big { display: flex; gap: 64px; flex-wrap: wrap; margin-bottom: 40px; }
.big .k { font: 12.5px var(--mono); color: var(--muted); }
.big .v { font: 500 var(--fs-big)/1.2 var(--mono); margin-top: 6px; font-variant-numeric: tabular-nums; }
.big .d { font: 12.5px var(--mono); color: var(--muted); margin-top: 4px; }
.tbl { width: 100%; overflow-x: auto; }
table { border-collapse: collapse; width: 100%; font-size: 13px; font-variant-numeric: tabular-nums; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line); white-space: nowrap; }
th:first-child, td:first-child { padding-left: 0; }
th:last-child, td:last-child { padding-right: 0; }
th { font-weight: 400; color: var(--muted); font-size: 12px; }
th.sort { cursor: pointer; }
th.sort:hover { color: var(--fg); }
td.r, th.r { text-align: right; }
td.nm { white-space: normal; overflow-wrap: anywhere; }
tr.row { cursor: pointer; }
tr.row:hover td { background: var(--soft); }
tr.row.open td { background: var(--soft); border-bottom-color: transparent; }
tr.card > td { background: var(--soft); padding: 0 16px 18px; }
tr.card .ip { font-size: 12px; color: var(--muted); padding: 2px 0 10px; }
tr.card table { font-size: 12.5px; }
tr.card th, tr.card td { padding: 6px 12px; }
tr.grp td { color: var(--muted); font-size: 12px; padding-top: 22px; }
tr.fold td { color: var(--muted); cursor: pointer; }
tr.fold:hover td { color: var(--fg); }
tr.off td { color: var(--muted); }
tfoot td { border-bottom: 0; border-top: 1px solid var(--fg-2); }
.note { font: 12px/1.7 var(--mono); color: var(--faint); margin-top: 16px; }

/* ---------- states: loading, empty, error, 404 ----------
   No skeletons, no spinners, no toasts for loading (owner's decision 30.09). While a screen or its data is on the way:
   - .nprog: a 2 px line in the accent colour at the top of the window (core/progress.js), only after 120 ms;
   - the old content stays on screen, inert (core/router.js): the last copy of the same screen as is (.stale), the
     previous screen dimmed (.stale-dim), never an empty main area. */
.nprog { position: fixed; top: 0; left: 0; z-index: 60; height: 2px; width: 0; background: var(--accent); opacity: 0; pointer-events: none; }
.nprog.on { opacity: 1; }
.nprog.grow { width: 80%; transition: width 6s cubic-bezier(.08, .7, .2, 1); }
.nprog.done { width: 100%; opacity: 0; transition: width .12s linear, opacity .18s linear .06s; }
@media (prefers-reduced-motion: reduce) {
  .nprog.on, .nprog.grow { width: 100%; transition: none; }
  .nprog.done { transition: none; }
}
.main[hidden] { display: none; }
.stale { pointer-events: none; user-select: none; }
.stale.stale-dim { opacity: .45; }
.empty { font: 13px var(--mono); color: var(--muted); padding: 28px 0; }
.empty .act { margin-top: 14px; }
.failed { font: 13px var(--mono); color: var(--bad); padding: 28px 0; }
.failed button { margin-left: 12px; }
@media (max-width: 900px) { .failed button { display: block; margin: 12px 0 0; } }   /* phone: «Повторить» on its own line, not after wrapped text */
.nf { font: 13px var(--mono); color: var(--muted); }
.nf .code404 { font: 12.5px var(--mono); color: var(--faint); margin-bottom: 8px; }
.stub { font: 12.5px/1.7 var(--mono); color: var(--faint); border-top: 1px solid var(--line); padding-top: 16px; margin-top: 40px; }

/* ---------- toast ----------
   One quiet line at the bottom, used for errors and "undo". No shadow, no animation, no colours
   except --bad for errors. Pages prefer inline states; the toast is for things with no place on screen. */
.toast { position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%); z-index: 20; max-width: min(560px, calc(100vw - 32px));
  width: max-content;   /* the automatic width stops at left: 50% (half a phone screen, 4-line towers): size to the text */
  background: var(--soft); border: 1px solid var(--line); color: var(--fg); font: 12.5px/1.5 var(--mono); padding: 10px 14px;
  display: flex; gap: 16px; align-items: baseline; }
.toast.error .tx { color: var(--bad); }
.toast button { padding: 0; border: 0; background: none; color: var(--muted); text-decoration: underline; text-underline-offset: 3px; }
.toast button:hover { color: var(--fg); background: none; }

/* ---------- mobile ---------- */
@media (max-width: 900px) {
  :root { --page-top: 24px; --page-x: 16px; }
  /* top bar: brand + server button (52 px, sticky); the menu moves to the bottom bar */
  .shell { display: block; background: none; }
  .side { position: sticky; top: 0; z-index: 10; height: 52px; max-height: none; overflow: visible; margin: 0; flex-direction: row; align-items: center;
    justify-content: space-between; gap: 12px; padding: 0 16px; background: var(--bg); border-bottom: 1px solid var(--line); }
  .brand { padding: 0; min-height: var(--tap); flex: none; }
  .side .nav, .side-foot { display: none; }
  .switch { position: static; padding: 0; min-width: 0; max-width: 60%; }
  .switch .sw-cur { border: 0; padding: 0; min-height: 44px; gap: 8px; font-size: 13px; }
  .switch .sw-cur:hover, .switch .sw-cur[aria-expanded="true"] { border: 0; }
  .switch .sw-list { position: absolute; left: 0; right: 0; top: 100%; z-index: 11; margin: 0; padding: 4px 16px 10px; background: var(--bg); border-top: 1px solid var(--fg-2); border-bottom: 1px solid var(--fg-2); }
  .switch .sw-list a { min-height: 44px; padding: 4px 0; font-size: 14px; }
  .switch .sw-list li.sw-on > a { background: none; color: var(--fg); }
  .switch .sw-add .sw-off, .switch .sw-add .sw-hint { padding-left: 0; padding-right: 0; }
  .out, .lang button { min-height: var(--tap); }
  .lang button { min-width: 32px; display: inline-flex; align-items: center; justify-content: center; }
  .main { padding: var(--page-top) var(--page-x) calc(var(--mbar-h) + env(safe-area-inset-bottom) + 16px); }
  .toast { bottom: calc(var(--mbar-h) + env(safe-area-inset-bottom) + 12px); }
  /* bottom bar: five text cells (the fifth is «Ещё», or the name of the section that lives there) */
  .mbar { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); position: fixed; left: 0; right: 0; bottom: 0; z-index: 12;
    min-height: var(--mbar-h); padding-bottom: env(safe-area-inset-bottom); background: var(--bg); border-top: 1px solid var(--line); }
  .mbar > a, .mbar > button.more { min-height: var(--mbar-h); display: flex; align-items: center; justify-content: center; gap: 4px; padding: 0 2px;
    font: 12px var(--mono); color: var(--muted); text-decoration: none; white-space: nowrap; background: none; border: 0; min-width: 0; }
  .mbar > a .lb, .mbar > button.more .lb { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .mbar > a:hover, .mbar > button.more:hover { color: var(--fg); background: none; }
  .mbar > a.on, .mbar > button.more.on { color: var(--fg); box-shadow: inset 0 1px 0 var(--fg); }
  .mbar > a .cnt { color: var(--fg); flex: none; }
  .mbar > a:focus-visible, .mbar > button.more:focus-visible { outline-offset: -3px; }
  .mbar > button.more[aria-expanded="true"] { color: var(--fg); }
  /* the open sheet dims the page above it (a plain layer, no blur); a tap on it closes the sheet */
  .more-bd { position: fixed; left: 0; right: 0; top: 0; bottom: calc(var(--mbar-h) + env(safe-area-inset-bottom)); z-index: -1; background: rgba(0, 0, 0, .5); }
  .more-bd[hidden] { display: none; }
  .more-sheet { position: absolute; left: 0; right: 0; bottom: 100%; max-height: calc(100dvh - 52px - var(--mbar-h)); overflow-y: auto;
    padding: 4px 16px 8px; background: var(--bg); border-top: 1px solid var(--fg-2); }   /* the sheet's edge over the content: a line, no shadow */
  .more-sheet a, .more-sheet .out { display: flex; align-items: center; justify-content: space-between; width: 100%; min-height: 48px; padding: 0;
    border-bottom: 1px solid var(--line); font: 14px var(--mono); color: var(--fg-2); text-decoration: none; }
  .more-sheet a.on { color: var(--fg); }
  .more-sheet a:hover { color: var(--fg); }
  .more-sheet .out { border-bottom: 0; text-decoration: none; }
  .more-sheet .sep { height: 12px; }
  /* «Ещё ▪» (flex gap 4) and «Что нового … ▪» (the row's space-between puts the square on the right) */
  .mbar > button.more .ndot, .more-sheet a.news-link .ndot { margin-left: 0; }
  .more-lang { display: flex; align-items: center; gap: 8px; min-height: 48px; border-bottom: 1px solid var(--line); font: 14px var(--mono); }
  .more-lang .k { color: var(--muted); margin-right: 8px; }
  .more-lang button { min-width: 44px; min-height: 44px; padding: 0 6px; border: 0; background: none; font: 14px var(--mono); color: var(--muted); }
  .more-lang button:hover { color: var(--fg); background: none; }
  .more-lang button.on { color: var(--fg); text-decoration: underline; text-underline-offset: 5px; }
  .ax .l { min-height: 36px; }
  .pause .link { min-height: var(--tap); }
  .tabs a { min-height: 40px; }
  /* one scrolling line fades out at the right (SPEC §4.6), so a cut word reads as «more this way»; the spacer lets
     the last item scroll clear of the fade */
  .tabs, .jr-flt { -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent); }
  .tabs::after { content: ''; flex: 0 0 8px; }            /* + the 24 px gap = 32 */
  .jr-flt::after { content: ''; flex: 0 0 14px; }         /* + the 18 px gap = 32 */
  details.msec { border-bottom: 1px solid var(--line); }
  details.msec + details.msec { margin-top: 0; }
  details.msec > summary { min-height: 48px; padding: 12px 0; cursor: pointer; }
  details.msec > summary h2 { font-size: 15px; }
  /* a setting row with a select: name and select on one line, the description under both (SPEC §4.6) */
  .rule:has(> div:first-child + select:last-child) { grid-template-columns: minmax(0, 1fr) auto; gap: 4px 12px; }
  .rule:has(> div:first-child + select:last-child) > div:first-child { display: contents; }
  .rule:has(> div:first-child + select:last-child) .nm { grid-column: 1; grid-row: 1; align-self: center; }
  .rule:has(> div:first-child + select:last-child) > div:first-child > :not(.nm) { grid-column: 1 / -1; }
  /* one width for every select of a form, so their left edges line up (the longest value, «Режим ИИ», fits) */
  .rule:has(> div:first-child + select:last-child) > select { grid-column: 2; grid-row: 1; width: 188px; max-width: 52vw; }
  /* …unless its longest value does not fit 188 px: then name / select (full width) / description, one per line */
  .rule:has(> div:first-child + select.sel-w:last-child) { grid-template-columns: minmax(0, 1fr); }
  .rule:has(> div:first-child + select.sel-w:last-child) > select { grid-column: 1; grid-row: 2; width: 100%; max-width: none; }
  .head { margin-bottom: 24px; }
  .sect { margin-top: 32px; }
  button, .btn { min-height: var(--tap); }
  input, textarea { min-height: var(--tap); }
  .link, .links a, .links button { min-height: var(--tap); display: inline-flex; align-items: center; }
  /* stand-alone links (not inside a sentence) get a 36px tap target (DESIGN_V2 rule 12) */
  .todo a, .foot a, .foot .link, .nf a, .foot-link a, .jr-more a, .note a, .empty .act a { display: inline-flex; align-items: center; min-height: var(--tap); }
  details > summary { min-height: var(--tap); display: flex; align-items: center; }
  .it > summary { display: grid; }
  .msg { grid-template-columns: minmax(0, 1fr) auto; gap: 2px 12px; }
  .msg .n { grid-column: 1; grid-row: 1; }
  .msg .t { grid-column: 2; grid-row: 1; font-size: 12px; text-align: right; }
  .msg .x { grid-column: 1 / 3; }
  .msg .m { grid-column: 1 / 3; white-space: normal; }
  .it > summary { grid-template-columns: minmax(0, 1fr) auto; gap: 2px 12px; padding: 12px 0; }
  .it .n { grid-column: 1; grid-row: 1; }
  .it .t { grid-column: 2; grid-row: 1; font-size: 12px; text-align: right; }
  .it .x { grid-column: 1 / 3; }
  .it .m { grid-column: 1 / 3; text-align: left; white-space: normal; }
  .ctx { padding: 4px 12px 16px; }
  .ctx .meta .sp { display: none; }
  .ctx .meta button { padding: 9px 14px; }
  .rule { grid-template-columns: minmax(0, 1fr) 168px; gap: 12px; }
  .rule select { font-size: 12.5px; padding-left: 9px; padding-right: 22px; background-position: right 8px center; min-height: var(--tap); }
  .big { gap: 32px; }
  .big .v { font-size: 24px; }
  .hide-m { display: none; }
  .skel .r { grid-template-columns: minmax(0, 1fr) 40px; }
  .skel .r i:nth-child(1) { display: none; }
}
/* iOS Safari zooms into any field with a font below 16px and leaves the page wider than the screen.
   Never disable zoom through the viewport; make touch-screen fields 16px instead. */
@media (max-width: 900px) and (pointer: coarse) {
  input, select, textarea, .rule select, .probe textarea { font-size: 16px; }
}
.nf h1 { color: var(--fg); }

/* phone: an address with #anchor (rules#mode, settings#data) scrolls its target below the sticky 52 px top bar */
@media (max-width: 900px) {
  #main [id] { scroll-margin-top: 68px; }
}

/* ---------- charts (js/core/chart.js, unified-stats SPEC §8.6) ----------
   Monochrome: line --fg, area --fg at 10 %, grid --line, labels --faint 11 px mono; --accent only for the «now» dot,
   --bad only for «offline». Square ends (radius 0, the cabinet's rule). The svg is drawn at the real pixel width. */
.ch { margin: 0; min-width: 0; }
.ch-plot { min-width: 0; width: 100%; line-height: 0; }
.ch-svg { display: block; overflow: visible; touch-action: pan-y; }
.ch-svg:focus { outline: none; }
.ch-svg:focus-visible { outline: 1px solid var(--line-strong); outline-offset: 2px; }
.ch-read { font: 12px/1.5 var(--mono); color: var(--muted); min-height: 18px; margin: 0 0 6px; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.ch-t { fill: var(--faint); font: 11px var(--mono); font-variant-numeric: tabular-nums; }
.ch-grid line { stroke: var(--line); stroke-width: 1; shape-rendering: crispEdges; }
.ch-fill path { fill: var(--fg); fill-opacity: .1; stroke: none; }
.ch-line polyline { fill: none; stroke: var(--fg); stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; }
.ch-slot line { stroke: var(--faint); stroke-width: 1; stroke-dasharray: 3 3; shape-rendering: crispEdges; }
.ch-off line { stroke: var(--bad); stroke-width: 2; }
.ch-mk line { stroke: var(--muted); stroke-width: 1; shape-rendering: crispEdges; }
.ch-now { fill: var(--accent); stroke: var(--bg); stroke-width: 2; }
.ch-cur line { stroke: var(--fg-2); stroke-width: 1; shape-rendering: crispEdges; }
.ch-cur circle { fill: var(--fg); stroke: var(--bg); stroke-width: 2; }
/* columns: --fg on top (new), --muted below (returning) with a 2 px surface gap; the pointed column stays, the rest dims */
.ch-b1 { fill: var(--fg); }
.ch-b2 { fill: var(--muted); }
.ch-bd { fill: var(--bad); }
.ch-svg.ch-has .ch-col:not(.on) rect { opacity: .45; }
.ch-lb { fill: var(--muted); }
/* heat map: 5 steps of --fg, empty cells --soft */
.ch-hn { fill: var(--soft); }
.ch-h0 { fill: var(--fg); fill-opacity: .07; }
.ch-h1 { fill: var(--fg); fill-opacity: .22; }
.ch-h2 { fill: var(--fg); fill-opacity: .4; }
.ch-h3 { fill: var(--fg); fill-opacity: .62; }
.ch-h4 { fill: var(--fg); fill-opacity: .9; }
.ch-heat rect.on { stroke: var(--fg); stroke-width: 1.5; }
/* map strip: neighbouring runs alternate two greys, the name inside when it fits */
.ch-s0 { fill: var(--muted); fill-opacity: .5; }
.ch-s1 { fill: var(--muted); fill-opacity: .28; }
.ch-in { fill: var(--fg); }
.ch-strip g.on rect { fill: var(--fg-2); fill-opacity: .8; }
.ch-strip g.on .ch-in { fill: var(--bg); }
/* legend: a swatch that mirrors the mark + the name in text colour */
.ch-leg { display: flex; flex-wrap: wrap; gap: 4px 16px; font: 12px var(--mono); color: var(--muted); margin: 0 0 4px; }
.ch-leg span { display: inline-flex; align-items: center; gap: 6px; }
.ch-key { width: 10px; height: 10px; display: inline-block; flex: none; }
.ch-key.ch-b1 { background: var(--fg); }
.ch-key.ch-b2 { background: var(--muted); }
.ch-key.ch-bd { background: var(--bad); }
.ch-spark { display: inline-block; vertical-align: middle; }
.ch-spark polyline { fill: none; stroke: var(--fg-2); stroke-width: 1; stroke-linejoin: round; }
.ch-hbar { display: inline-block; vertical-align: middle; }
.ch-hbar .ch-tr { fill: var(--line); }
.ch-hbar .ch-v { fill: var(--fg-2); }
@media (pointer: coarse) { .ch-svg { touch-action: pan-y pinch-zoom; } }
/* map card .ch-mc (js/core/mapcard.js): 16:9, --soft, the «radar» in --line / --muted, name mono; no --accent */
.ch-mc { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; background: var(--soft); object-fit: cover; }
.ch-mc.ch-mc-s { width: 48px; height: 27px; flex: none; }
.ch-mc .ch-mc-bg { fill: var(--soft); }
.ch-mc .ch-mc-c1 { fill: var(--line); }
.ch-mc .ch-mc-c2 { fill: var(--muted); fill-opacity: .35; }
.ch-mc .ch-mc-p { fill: none; stroke: var(--muted); stroke-width: 2; }
.ch-mc .ch-mc-pt { fill: var(--fg-2); font: 500 12px var(--mono); }
.ch-mc .ch-mc-shade { fill: var(--soft); fill-opacity: .82; }
.ch-mc .ch-mc-m { fill: var(--muted); font: 13px var(--mono); }
.ch-mc .ch-mc-n { fill: var(--fg); font: 500 22px var(--mono); }
.ch-mc .ch-mc-n.ch-mc-n-s { font-size: 16px; }

/* stats-auto §7.2: server type line, one «·» line: «Тип сервера: Паблик + мод · VIP · не уверены — проверьте · изменить»;
   «изменить» (owner) opens the select in place. The empty error line takes no room (DESIGN.md §3.5). */
.mode-line { font: var(--fs-cap)/1.7 var(--mono); color: var(--muted); }
.mode-line .mode-v { color: var(--fg-2); }
.mode-line .mode-edit { font: inherit; }
.mode-pick { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s3); align-items: center; margin-top: var(--s2); }
.mode-err:empty { display: none; }
.ov-type:empty, .sx-mode:empty, .st-mode:empty { display: none; }
.ov-type, .sx-mode { margin-top: var(--s1); }
.st-mode { margin-top: var(--s3); }
/* stats-auto §7.3: the new-edition notice is the .confirm strip (DESIGN.md §3.10): --soft, no frame, one mono sentence
   in --fg-2 with «Читать оферту», a bordered «Принять» on the right (under the text when it does not fit). Обзор: under
   the type line (owner); Настройки: it opens «Статистика и баны» (settings.css .st-pg .terms-new) */
.terms-new { margin-top: var(--s2); max-width: var(--w-read); }
.terms-new .terms-tx { flex: 1 1 340px; margin: 0; font: var(--fs-cap)/1.7 var(--mono); color: var(--fg-2); }
.terms-new .terms-tx a { color: var(--fg-2); }
.terms-new .terms-tx a:hover { color: var(--fg); }
.terms-new .err { flex-basis: 100%; margin: 0; min-height: 0; }
.terms-new .err:empty { display: none; }
/* the offer tick: the line under it is its fine print, under the label text (14 px box + 8 px gap), then the field */
.terms-w { margin: 4px 0 16px; }
.terms-w .terms { margin: 0; }
.terms-auto { margin: 6px 0 0 22px; max-width: 620px; text-wrap: pretty; }   /* the lead width: EN ends on 2 lines like RU / UK; never a lone «/privacy.» */
@media (max-width: 900px) { .terms-auto { margin-left: 26px; } }   /* the box is 18 px on phones */
.bare .terms-w { margin: 16px 0 0; }
.bare .terms-w .terms { margin: 0; }

/* first-time path: «шаг 2 из 4 · код приглашения» above the h1 on the bare pages (mono status line, no colour) */
.onb-step { font: var(--fs-cap)/1.6 var(--mono); color: var(--muted); margin: 0 0 8px; }
