/* ============================================================================
   One stylesheet for the whole application (task 0.15, methods/ui-style.md).

   Every screen takes its look from here: the tokens below are the only
   colours, sizes and distances the program knows. A template never carries
   its own <style>; a screen that needs something new adds a class here.

   Structure: tokens · base · frame (sidebar + topbar) · typography · buttons
   · forms · cards and stats · tabs and navigation lines · tags and states ·
   tables and the table component · panel, checks, tour · messages · screens
   (small per-screen layout classes) · narrow screen.
   ========================================================================== */

/* ---------- tokens ------------------------------------------------------- */
/* Dark is the default (the owner's reference: the EV1Charge admin, 16.09.2026); the light
   theme overrides the colour tokens when <html data-theme="light"> is set by the switch in
   the menu. Sizes, spacing and radii are the same in both. */
:root {
  --font: "Inter", "Segoe UI", system-ui, -apple-system, Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* Владелец 26.09.2026: «всё крупнее, кнопки крупнее, читабельные, заметные, чтобы их не надо
     было выискивать в строчках». Шкала поднята на ступень: то, что было подписью, стало текстом. */
  --fs-xs: .8125rem; /* 13px — captions, table legend            */
  --fs-sm: .875rem;  /* 14px — table cells, secondary text       */
  --fs-md: 1rem;     /* 16px — body                              */
  --fs-lg: 1.25rem;  /* 20px — section titles (h2)               */
  --fs-xl: 1.75rem;  /* 28px — page title (h1)                   */

  --bg: #1a1a2e;          /* page                                  */
  --surface: #16213e;     /* cards, tables                         */
  --surface-2: #0f3460;   /* inputs, table head, wells             */
  --surface-3: #1a2744;   /* hover rows, raised parts              */
  --line: #1e2a44;        /* hairline borders                      */
  --line-2: #1a4a7a;      /* stronger borders (inputs, focus base) */
  --text: #ffffff;
  --text-2: #b4bccc;      /* secondary                             */
  --text-3: #7c869c;      /* captions, placeholders                */

  --brand: #00e676;
  --brand-hover: #00c853;
  --brand-soft: rgba(0, 230, 118, .12);
  --brand-text: #00e676;
  --on-brand: #04120a;

  /* The colours of the mark (the owner's decision, 18.09.2026): the same in both themes —
     the brand does not follow the theme. Used by the login page (task 0.21). */
  --ident-green: #1F4B43;
  --ident-gold: #C9A961;
  --ident-paper: #F3F2EE;
  --ident-dark: #12211E;

  --danger: #ff5252;
  --danger-soft: rgba(255, 82, 82, .12);
  --danger-text: #ff6b6b;
  --ok: #00e676;
  --ok-soft: rgba(0, 230, 118, .12);
  --ok-text: #00e676;
  --warn: #ff9800;
  --warn-soft: rgba(255, 152, 0, .14);
  --warn-text: #ffb300;
  --info-soft: rgba(33, 150, 243, .14);
  --info-text: #64b5f6;
  --auto-soft: rgba(156, 39, 176, .16);
  --auto-text: #ce93d8;

  --side-bg: #16213e;
  --side-text: #aab3c5;
  --side-text-strong: #ffffff;
  --side-hover: rgba(255, 255, 255, .05);
  --side-active: rgba(0, 230, 118, .1);
  --side-line: #1a3a6e;
  --side-w: 248px;

  --radius: 12px;
  --radius-sm: 8px;
  --shadow-sm: 0 2px 8px rgba(0, 0, 0, .2);
  --shadow: 0 8px 24px rgba(0, 0, 0, .3);
  --shadow-lg: 0 12px 32px rgba(0, 0, 0, .45);

  --sp-1: .25rem; --sp-2: .5rem; --sp-3: .75rem; --sp-4: 1rem; --sp-5: 1.25rem; --sp-6: 1.5rem; --sp-8: 2rem;
  --control-h: 2.75rem; /* 44px — inputs, selects, buttons: одна высота в строке и палец попадает */
  color-scheme: dark;
}
:root[data-theme="light"] {
  --bg: #eef1f8; --surface: #ffffff; --surface-2: #eef2fb; --surface-3: #f4f7fd;
  --line: #e5eaf5; --line-2: #c2cfe6;
  --text: #16203a; --text-2: #5a6a8c; --text-3: #5f6d8f;
  --brand: #00a651; --brand-hover: #00893f; --brand-soft: rgba(0, 166, 81, .12); --brand-text: #00893f; --on-brand: #ffffff;
  --danger: #e53935; --danger-soft: rgba(229, 57, 53, .12); --danger-text: #c62828;
  --ok: #00a651; --ok-soft: rgba(0, 166, 81, .12); --ok-text: #00893f;
  --warn: #e08600; --warn-soft: rgba(224, 134, 0, .14); --warn-text: #a86400;
  --info-soft: rgba(25, 118, 210, .12); --info-text: #1565c0;
  --auto-soft: rgba(123, 31, 162, .12); --auto-text: #6a1b9a;
  --side-bg: #ffffff; --side-text: #5a6a8c; --side-text-strong: #16203a;
  --side-hover: rgba(22, 32, 58, .05); --side-active: rgba(0, 166, 81, .1); --side-line: #d8e0f0;
  --shadow-sm: 0 1px 3px rgba(20, 30, 60, .08), 0 6px 18px rgba(20, 30, 60, .05);
  --shadow: 0 10px 30px rgba(20, 30, 60, .12);
  --shadow-lg: 0 12px 32px rgba(20, 30, 60, .18);
  color-scheme: light;
}

/* ---------- base --------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { font-size: 16px; -webkit-text-size-adjust: 100%; }
body {
  margin: 0; min-height: 100vh;
  font-family: var(--font); font-size: var(--fs-md); line-height: 1.5;
  color: var(--text); background: var(--bg);
  -webkit-font-smoothing: antialiased;
}
a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }
img { max-width: 100%; }
hr { border: 0; border-top: 1px solid var(--line); margin: var(--sp-6) 0; }
main table { width: 100%; border-collapse: collapse; }
/* A table that can scroll sideways says so (task 0.19): a soft shadow on the right edge
   while there is more to the right, and a one-time line under the first such table. */
.can-scroll { box-shadow: inset -28px 0 18px -18px rgba(0, 0, 0, .45); }
.scroll-hint { font-size: var(--fs-xs); color: var(--text-3); margin: var(--sp-1) 0 var(--sp-2); text-align: center; }
main table.auto { width: auto; }
td.date, th.date { white-space: nowrap; }
/* The name column keeps room on the desk too (task 0.23): the estimate's name was squeezed to five lines. */
.tbl td.p-key, .tbl th.p-key { min-width: 18rem; }
.tbl td.clip { min-width: 16rem; }

/* ---------- frame: sidebar + topbar + content ---------------------------- */
.app { display: flex; min-height: 100vh; }

nav.side {
  position: fixed; inset: 0 auto 0 0; width: var(--side-w); z-index: 40;
  display: flex; flex-direction: column;
  background: var(--side-bg); color: var(--side-text); border-right: 1px solid var(--side-line);
  transition: transform .2s ease;
}
nav.side .brand {
  display: flex; align-items: center; gap: var(--sp-2) var(--sp-3); flex-wrap: wrap;
  padding: var(--sp-4) var(--sp-4); color: var(--side-text-strong);
  font-weight: 700; font-size: 1.0625rem; letter-spacing: -.01em; border-bottom: 1px solid var(--side-line);
}
nav.side .brand .logo {
  /* The Stimario mark (18.09.2026): the plumb line in its ring, the ring and the line in the menu's text colour, the bob in gold. */
  width: 36px; height: 36px; display: grid; place-items: center; color: var(--side-text-strong); flex: 0 0 auto;
}
nav.side .brand .logo .mark { width: 36px; height: 36px; display: block; }
nav.side .brand .name { display: block; line-height: 1.2; }
nav.side .brand > span:not(.logo) { min-width: 0; flex: 1 1 auto; }
nav.side .brand .co { display: block; font-size: var(--fs-xs); font-weight: 500; color: var(--side-text); line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
nav.side .brand .co.warn { color: var(--warn-text); }
/* Language pills in the head of the menu: one tap, no dropdown (the reference). */
nav.side .langs { display: flex; gap: 2px; flex: 1 1 100%; justify-content: space-between; padding: 2px; border-radius: 999px; background: var(--side-hover); }
nav.side .langs button {
  flex: 1 1 0; height: 1.5rem; padding: 0 .55rem; border: 0; border-radius: 999px; background: transparent;
  color: var(--side-text); font-size: .6875rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
}
nav.side .langs button:hover { color: var(--side-text-strong); background: transparent; }
nav.side .langs button.active { background: var(--brand); color: var(--on-brand); }
nav.side .menu { display: flex; flex-direction: column; gap: 1px; padding: var(--sp-2) 0; flex: 1 1 auto; min-height: 0; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--side-line) transparent; }
nav.side .menu a, nav.side .menu button.link {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-5); border-left: 3px solid transparent;
  color: var(--side-text); font-size: var(--fs-md); font-weight: 600; text-decoration: none;
  background: none; border-top: 0; border-right: 0; border-bottom: 0; width: 100%; text-align: left; cursor: pointer; border-radius: 0;
  transition: background .15s ease, color .15s ease;
}
nav.side .menu a:hover, nav.side .menu button.link:hover { background: var(--side-hover); color: var(--side-text-strong); }
nav.side .menu a.active { background: var(--side-active); color: var(--brand-text); border-left-color: var(--brand); }
nav.side .menu svg { width: 18px; height: 18px; flex: 0 0 auto; opacity: .9; }
nav.side .menu .group { padding: var(--sp-5) var(--sp-5) var(--sp-2); font-size: .75rem; font-weight: 700; text-transform: uppercase; letter-spacing: .12em; color: var(--text-3); }
/* The sub-items of the open section, under its item: one click between the pages of
   the section on the desktop (task 0.15). */
nav.side .sub-menu { display: flex; flex-direction: column; gap: 1px; margin: 0 0 var(--sp-2) 0; padding-left: 2.6rem; }
nav.side .sub-menu a { padding: var(--sp-2) var(--sp-3); font-size: var(--fs-sm); font-weight: 500; color: var(--text-2); border-radius: var(--radius-sm); border-left: 0; }
nav.side .sub-menu a:hover { color: var(--side-text-strong); background: var(--side-hover); }
nav.side .sub-menu a.active { color: var(--brand-text); background: var(--side-active); font-weight: 500; }
nav.side .spacer { flex: 0 0 0; }
nav.side .user {
  border-top: 1px solid var(--side-line); padding: var(--sp-3) var(--sp-4) var(--sp-4);
  display: grid; gap: var(--sp-2); font-size: var(--fs-sm); flex: 0 0 auto;
}
nav.side .user .who { display: inline-block; max-width: calc(100% - 1.4em); vertical-align: bottom; color: var(--side-text-strong); font-weight: 600; font-size: var(--fs-md); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
nav.side .user .k { display: block; font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .06em; color: var(--text-3); }
nav.side .user select {
  width: 100%; height: 2.125rem; background: var(--surface-2); color: var(--side-text-strong);
  border: 1px solid var(--side-line); border-radius: var(--radius-sm); padding: 0 var(--sp-2); font-size: var(--fs-sm);
}
nav.side .user .row { display: flex; gap: var(--sp-2); align-items: center; flex-wrap: wrap; }
nav.side .user .tag { background: var(--side-hover); color: var(--side-text); border-color: var(--side-line); }
nav.side .user .tag.admin { background: var(--danger-soft); color: var(--danger-text); border-color: transparent; }
nav.side .user .tag.nocompany { background: var(--warn-soft); color: var(--warn-text); border-color: transparent; }
nav.side .user button, nav.side .user a.btn { height: 2.125rem; padding: 0 var(--sp-3); font-size: var(--fs-sm); }
nav.side .user button.ghost { background: transparent; color: var(--side-text); border: 1px solid var(--side-line); }
nav.side .user button.ghost:hover { background: var(--side-hover); color: var(--side-text-strong); }
nav.side .user details summary { cursor: pointer; color: var(--side-text); list-style: none; }
nav.side .user details summary::-webkit-details-marker { display: none; }
nav.side .user details summary::after { content: " ▾"; color: var(--text-3); }
nav.side .user details[open] summary::after { content: " ▴"; }
nav.side .user details .switcher { display: grid; gap: var(--sp-2); padding-top: var(--sp-2); }
nav.side .user details .switcher a { color: var(--side-text); font-size: var(--fs-xs); }
/* The foot of the menu: the theme switch and the status dot, as in the reference. */
nav.side .foot { flex: 0 0 auto; display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-3) var(--sp-4); border-top: 1px solid var(--side-line); font-size: var(--fs-xs); color: var(--text-3); }
nav.side .foot .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--brand); box-shadow: 0 0 6px var(--brand); flex: 0 0 auto; }
nav.side .foot .theme { margin-left: auto; height: 1.75rem; padding: 0 var(--sp-2); background: transparent; border: 1px solid var(--side-line); color: var(--side-text); font-size: var(--fs-xs); }
nav.side .foot .theme:hover { color: var(--side-text-strong); background: var(--side-hover); }

.topbar {
  display: none; position: sticky; top: 0; z-index: 30;
  align-items: center; gap: var(--sp-3); height: 3.25rem; padding: 0 var(--sp-4);
  background: var(--surface); border-bottom: 1px solid var(--line);
}
.topbar .burger {
  width: 2.25rem; height: 2.25rem; padding: 0; display: grid; place-items: center;
  background: transparent; border: 1px solid var(--line); border-radius: var(--radius-sm); color: var(--text);
}
.topbar .burger svg { width: 20px; height: 20px; }
.topbar .title { font-weight: 600; font-size: var(--fs-md); flex: 1 1 auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.backdrop { display: none; position: fixed; inset: 0; background: rgba(15, 23, 42, .5); z-index: 35; }
body.menu-open .backdrop { display: block; }

.content { flex: 1 1 auto; min-width: 0; margin-left: var(--side-w); display: flex; flex-direction: column; }
main { width: 100%; padding: var(--sp-6) var(--sp-8) var(--sp-8); }
/* Two kinds of screen (methods/ui-style.md, 1): a sheet reads like a document and
   stays narrow; a desk is a machine and takes the width it is given. */
body.sheet main { max-width: 680px; margin: 0 auto; }
body.desk main { max-width: 1680px; }
body.bare .content { margin-left: 0; }
body.bare main { max-width: 480px; margin: 8vh auto 0; }

/* ---------- typography --------------------------------------------------- */
h1 { font-size: var(--fs-xl); font-weight: 650; letter-spacing: -.01em; line-height: 1.25; margin: 0 0 var(--sp-2); }
h2 { font-size: var(--fs-lg); font-weight: 600; margin: var(--sp-6) 0 var(--sp-3); }
h3 { font-size: var(--fs-lg); font-weight: 600; margin: var(--sp-5) 0 var(--sp-3); }
p { margin: 0 0 var(--sp-3); }
.sub { color: var(--text-2); font-size: var(--fs-sm); }
/* Цифра, проигравшая спор источников: видна у места вместе с причиной, но не выглядит принятой. */
.aside { color: var(--text-2); font-size: var(--fs-sm); margin-top: var(--sp-1);
  padding-left: var(--sp-2); border-left: 2px solid var(--line); }
.muted { color: var(--text-3); }
.num { text-align: right; font-variant-numeric: tabular-nums; }
code, .mono { font-family: var(--mono); font-size: .9em; }
abbr.term { text-decoration: underline dotted; cursor: help; }
.head { display: flex; justify-content: space-between; align-items: flex-end; gap: var(--sp-4); flex-wrap: wrap; margin-bottom: var(--sp-4); }
.head h1 { margin-bottom: 0; }
.head > div:first-child { min-width: 0; }
.crumbs { font-size: var(--fs-sm); color: var(--text-2); margin-bottom: var(--sp-3); }
.crumbs a { color: var(--text-2); }
.crumbs .sep { margin: 0 var(--sp-2); color: var(--text-3); }

/* ---------- buttons ------------------------------------------------------ */
/* A button without a class is the ordinary, framed one; the one main action of a screen says
   `.primary` and is the only green button there (task 0.18 — the audit found 2–4 green buttons on
   every list because the default used to be the green one). `.secondary` stays as a synonym. */
button, .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  height: var(--control-h); padding: 0 var(--sp-5);
  font: inherit; font-size: var(--fs-md); font-weight: 600; line-height: 1;
  /* Обычная кнопка приподнята фоном: рамка на тёмном теряется, и кнопку приходилось искать. */
  color: var(--text); background: var(--surface-2); border: 1px solid var(--line-2); border-radius: var(--radius-sm);
  cursor: pointer; white-space: nowrap; text-decoration: none;
  transition: background .12s ease, border-color .12s ease, box-shadow .12s ease;
}
button:hover, .btn:hover, .tbl-actions a:hover { background: var(--surface-3); border-color: var(--text-2); text-decoration: none; }
button:focus-visible, .btn:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--brand); outline-offset: 2px;
}
button[disabled], .btn[disabled] { opacity: .5; cursor: default; }
button.primary, .btn.primary { color: var(--on-brand); background: var(--brand); border-color: var(--brand); font-weight: 700; box-shadow: var(--shadow-sm); }
button.primary:hover, .btn.primary:hover { background: var(--brand-hover); border-color: var(--brand-hover); }
.tbl-actions a { color: var(--text); background: var(--surface); border-color: var(--line-2); }
/* Dangerous: red, framed, never first in a row (ui-style.md, 7). */
button.danger, .btn.danger { color: var(--danger-text); background: transparent; border-color: var(--danger); }
button.danger:hover { background: var(--danger-soft); border-color: var(--danger); }
/* Link-shaped action: a word, no frame. */
button.link { height: auto; padding: 0; background: none; border: 0; color: var(--brand); font-weight: 500; }
button.link:hover { background: none; text-decoration: underline; }
button.link.danger, .tbl-panel .tbl-view button.link { color: var(--danger); }
/* «Маленькая» — это кнопка в строке таблицы, а не кнопка для мыши снайпера: 36 px, не 30. */
button.small, .btn.small { height: 2.25rem; padding: 0 var(--sp-4); font-size: var(--fs-sm); }
.actions-row { display: flex; gap: var(--sp-4); align-items: center; flex-wrap: wrap; margin-top: var(--sp-5); }

/* Складка — это кнопка: её нажимают, значит она должна выглядеть нажимаемой. */
details > summary {
  cursor: pointer; font-size: var(--fs-md); font-weight: 600; color: var(--text);
  padding: var(--sp-3) 0; list-style: none;
}
details > summary::-webkit-details-marker { display: none; }
details > summary::before { content: "▸ "; color: var(--brand); font-weight: 700; }
details[open] > summary::before { content: "▾ "; }
details > summary:hover { color: var(--brand-text); }

/* ---------- forms -------------------------------------------------------- */
label { font-size: var(--fs-md); font-weight: 500; color: var(--text-2); }
input[type=text], input[type=email], input[type=password], input[type=number], input[type=date], input[type=search], input[type=url], input[type=tel],
select, textarea {
  width: 100%; font: inherit; font-size: var(--fs-md); color: var(--text);
  background: var(--surface-2); border: 1px solid var(--line-2); border-radius: var(--radius-sm);
  padding: 0 var(--sp-3); height: var(--control-h);
  transition: border-color .12s ease, box-shadow .12s ease;
}
textarea { height: auto; min-height: 5rem; padding: var(--sp-2) var(--sp-3); line-height: 1.45; resize: vertical; }
select[multiple] { height: auto; padding: var(--sp-1); }
input:hover, select:hover, textarea:hover { border-color: var(--text-3); }
input:focus, select:focus, textarea:focus { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); outline: none; }
input[readonly], input[disabled], select[disabled], textarea[disabled] { background: var(--surface-2); color: var(--text-2); }
/* Галочка — цель для пальца, а не точка: 20 px и отступ, чтобы попасть не целясь. */
input[type=checkbox], input[type=radio] { width: 1.25rem; height: 1.25rem; accent-color: var(--brand); margin: 0 var(--sp-3) 0 0; vertical-align: -4px; }
.checks label { display: inline-flex; align-items: center; padding: var(--sp-2) 0; cursor: pointer; }
input::placeholder { color: var(--text-3); }
/* A form is air: label above the field, fields apart, errors by the field. */
form p { display: flex; flex-direction: column; gap: var(--sp-1); margin: 0 0 var(--sp-4); }
form p > label { display: block; }
form p > br { display: none; }
/* A button inside a form paragraph keeps its own width: the column flex stretched it across the card (task 0.24). */
form p > button, form p > .btn { align-self: flex-start; }
/* A list of ticks (CheckboxSelectMultiple) inside a form paragraph: one per line, no bullets. */
form p div[id^=id_], form p ul[id^=id_] { display: grid; gap: var(--sp-1); margin: 0; padding: 0; list-style: none; }
form p div[id^=id_] label, form p ul[id^=id_] label { display: flex; align-items: center; gap: var(--sp-2); font-weight: 400; color: var(--text); font-size: var(--fs-md); }
form p label input[type=checkbox] { margin-right: var(--sp-2); }
form.new, form.card-form { display: grid; gap: var(--sp-3); }
ul.errorlist { color: var(--danger-text); margin: var(--sp-1) 0 0; padding-left: 1.1rem; font-size: var(--fs-sm); }
.helptext, form .sub { font-size: var(--fs-xs); }
form.inline { display: inline-flex; gap: var(--sp-2); align-items: center; }
form.inline select, form.inline input[type=text] { width: auto; max-width: 16rem; height: 2.25rem; font-size: var(--fs-sm); }
form.inline { flex-wrap: wrap; row-gap: var(--sp-2); }
.role-name { display: flex; gap: var(--sp-3); align-items: center; flex-wrap: wrap; margin: var(--sp-3) 0 var(--sp-5); }
.role-name input[type=text] { width: auto; min-width: 18rem; }

/* ---------- cards, stats, lists ------------------------------------------ */
.card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: var(--sp-6) var(--sp-8); box-shadow: var(--shadow-sm);
}
.card + .card, .card + h2 { margin-top: var(--sp-4); }
.card h1:first-child, .card h2:first-child { margin-top: 0; }
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: var(--sp-4); }
.cards .card { display: block; color: inherit; text-decoration: none; transition: box-shadow .12s ease, border-color .12s ease; }
.cards .card:hover { box-shadow: var(--shadow); border-color: var(--line-2); text-decoration: none; }
.cards .card .head { margin-bottom: var(--sp-2); align-items: flex-start; }
.cards .card h3 { margin: 0; font-size: var(--fs-md); }
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--sp-3); margin: var(--sp-4) 0; }
.stat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: var(--sp-4) var(--sp-5); box-shadow: var(--shadow-sm); transition: transform .15s ease, border-color .15s ease; }
/* A tile that opens its source (task 0.20): a link, a corner arrow, a hover like the hub tiles. */
a.stat { display: block; position: relative; color: inherit; text-decoration: none; }
a.stat::after { content: "→"; position: absolute; top: var(--sp-3); right: var(--sp-4); color: var(--text-3); font-size: var(--fs-sm); transition: color .15s ease, transform .15s ease; }
a.stat:hover { text-decoration: none; border-color: var(--brand); box-shadow: var(--shadow); }
a.stat:hover::after { color: var(--brand-text); transform: translateX(2px); }
a.stat .sub { display: block; }
.stat:hover { transform: translateY(-2px); border-color: var(--line-2); }
.stat .ico { width: 40px; height: 40px; border-radius: var(--radius-sm); display: grid; place-items: center; margin-bottom: var(--sp-3); background: var(--brand-soft); color: var(--brand-text); }
.stat .ico svg { width: 20px; height: 20px; }
.stat .ico.info { background: var(--info-soft); color: var(--info-text); }
.stat .ico.warn { background: var(--warn-soft); color: var(--warn-text); }
.stat .ico.auto { background: var(--auto-soft); color: var(--auto-text); }
.stat .k { display: block; font-size: var(--fs-sm); font-weight: 500; color: var(--text-3); margin-bottom: var(--sp-1); text-transform: none; letter-spacing: 0; }
.stat .v { font-size: 1.75rem; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; line-height: 1.15; }
/* A tile whose value is words, not a figure (task 0.23): the section-title size, three lines at most. */
.stat .v.text { font-size: var(--fs-lg); font-weight: 600; letter-spacing: 0; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 3; line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
.stat .sub { display: block; margin-top: var(--sp-1); }
.steps { display: flex; gap: var(--sp-2); list-style: none; padding: 0; margin: 0 0 var(--sp-5); font-size: var(--fs-sm); flex-wrap: wrap; }
.steps li { padding: .2rem .7rem; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--line); color: var(--text-2); }
.steps li.active { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }
.steps li.done { background: var(--ok-soft); border-color: transparent; color: var(--ok-text); }
table.history { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
table.history th, table.history td { padding: var(--sp-2) var(--sp-3); border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
table.history th { background: var(--surface-2); font-weight: 600; color: var(--text-2); }

/* ---------- hub tiles ---------------------------------------------------- */
/* The hub of a section: a tile per page — section → list → card (task 0.15). */
.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--sp-3); }
/* The screens of an object as compact tiles (task 0.23): a name and a hint, three or four in a row. */
.quick-links { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--sp-2); margin: var(--sp-4) 0; }
.quick-links a { display: block; padding: var(--sp-3) var(--sp-4); background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm); color: inherit; text-decoration: none; transition: border-color .12s ease, box-shadow .12s ease; }
.quick-links a:hover { text-decoration: none; border-color: var(--brand); box-shadow: var(--shadow-sm); }
.quick-links a b { display: block; color: var(--brand-text); font-weight: 600; }
.quick-links a .sub { display: block; margin-top: 2px; }
.tile {
  display: flex; flex-direction: column; gap: var(--sp-1); min-height: 5.5rem;
  padding: var(--sp-4) var(--sp-5); background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--text); text-decoration: none; box-shadow: var(--shadow-sm);
  transition: box-shadow .12s ease, border-color .12s ease, transform .12s ease;
}
.tile:hover { text-decoration: none; box-shadow: var(--shadow); border-color: var(--line-2); transform: translateY(-1px); }
.tile-title { font-weight: 600; font-size: var(--fs-md); display: flex; align-items: center; gap: var(--sp-2); }
.tile-count { font-size: var(--fs-xs); font-weight: 600; color: var(--brand-text); background: var(--brand-soft); border-radius: 999px; padding: 0 .5rem; }
.tile-hint { font-size: var(--fs-sm); color: var(--text-2); }

/* ---------- tabs and navigation lines ------------------------------------ */
/* A navigation line is a row of pills: every item has a frame, the current one is
   filled. Words alone read as text, not as buttons — on the phone above all. */
.toggle, .reference-nav {
  display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: 0 0 var(--sp-4);
}
.toggle a, .reference-nav a, .reference-nav span {
  display: inline-flex; align-items: center; height: 2.125rem; padding: 0 var(--sp-4);
  border: 1px solid var(--line-2); border-radius: 999px; background: var(--surface);
  color: var(--text); font-size: var(--fs-sm); font-weight: 500; text-decoration: none; white-space: nowrap;
  transition: background .12s ease, border-color .12s ease;
}
.toggle a:hover, .reference-nav a:hover { background: var(--surface-2); border-color: var(--text-3); text-decoration: none; }
.toggle a b, .reference-nav .here { font-weight: 600; }
.toggle a:has(b), .reference-nav .here { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }
.head .toggle { margin: 0; }

/* ---------- tags and states ---------------------------------------------- */
.tag, .st-mark, .owner-mark, .system-mark {
  display: inline-block; padding: .15rem .65rem; border-radius: 999px;
  font-size: var(--fs-xs); font-weight: 600; white-space: nowrap; line-height: 1.5;
  background: var(--surface-2); color: var(--text-2); border: 1px solid transparent;
}
.tag.admin { background: var(--danger-soft); color: var(--danger-text); border-color: transparent; }
.tag.nocompany { background: var(--warn-soft); color: var(--warn-text); border-color: transparent; }
.owner-mark { background: var(--warn-soft); color: var(--warn-text); border-color: transparent; }
.system-mark { background: var(--brand-soft); color: var(--brand-text); border-color: transparent; }
/* Record states — one set for the whole application (methods/help-and-hints.md, 6).
   Colour is never alone: the mark carries an icon and a word. */
tr.st-draft .st-mark { background: var(--surface-2); color: var(--text-2); }
tr.st-unchecked .st-mark, tr.st-required .st-mark, .st-mark.st-unchecked { background: var(--warn-soft); color: var(--warn-text); border-color: transparent; }
tr.st-pending .st-mark { background: var(--info-soft); color: var(--info-text); border-color: transparent; }
tr.st-rejected .st-mark { background: var(--danger-soft); color: var(--danger-text); border-color: transparent; }
tr.st-approved .st-mark { background: var(--ok-soft); color: var(--ok-text); border-color: transparent; }
tr.st-deleted td { text-decoration: line-through; color: var(--text-3); }
tr.st-deleted .st-mark { text-decoration: none; }
.st-auto .st-mark, .st-mark.st-auto { background: var(--auto-soft); color: var(--auto-text); border-color: transparent; }
.st-locked { background: var(--surface-2); color: var(--text-2); }
.status.deleted { color: var(--danger-text); }
tr.off td { color: var(--text-3); }

/* Badges: a pill with a dot, the word beside it (colour is never alone — help-and-hints.md, 6). */
.badge { display: inline-flex; align-items: center; gap: .4rem; padding: .3rem .75rem; border-radius: 999px; font-size: var(--fs-xs); font-weight: 700; background: var(--surface-2); color: var(--text-2); white-space: nowrap; }
.badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.badge.ok { background: var(--ok-soft); color: var(--ok-text); }
.badge.warn { background: var(--warn-soft); color: var(--warn-text); }
.badge.danger { background: var(--danger-soft); color: var(--danger-text); }
.badge.info { background: var(--info-soft); color: var(--info-text); }
.badge.auto { background: var(--auto-soft); color: var(--auto-text); }
/* A person in a list: initials in a coloured square, name and caption beside (the reference). */
.avatar { width: 36px; height: 36px; border-radius: var(--radius-sm); display: inline-grid; place-items: center; font-weight: 700; font-size: var(--fs-sm); color: #fff; flex: 0 0 auto; }
.avatar.c0 { background: #ff7043; } .avatar.c1 { background: #ec407a; } .avatar.c2 { background: #7e57c2; } .avatar.c3 { background: #26a69a; }
.avatar.c4 { background: #42a5f5; } .avatar.c5 { background: #ffa726; } .avatar.c6 { background: #66bb6a; } .avatar.c7 { background: #8d6e63; }
.person { display: flex; align-items: center; gap: var(--sp-3); }
.person .lines { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.person .lines .main { color: var(--text); font-weight: 500; }
.person .lines .sub { font-size: var(--fs-xs); }

 ------------------------------- */
/* Density, not air: a table of tens of thousands of rows is read by seeing more of it
   at once (ui-style.md, 2 and 3). Air belongs between the blocks of a screen. */
table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
th, td { padding: var(--sp-2) var(--sp-4); border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; line-height: 1.45; }
th { background: var(--surface-2); font-weight: 700; color: var(--text-2); font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .04em; }
/* Ссылка в таблице должна читаться ссылкой, а не текстом: её искали глазами (26.09.2026). */
tbody td a { color: var(--brand-text); font-weight: 600; }
tbody td a:hover { text-decoration: underline; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
tr.group td { background: var(--surface-2); font-weight: 600; cursor: pointer; text-transform: none; }
tr.total td { font-weight: 600; background: var(--surface-2); }
tbody tr:hover td { background: var(--surface-3); }
tbody a { text-decoration: none; }
tbody a:hover { text-decoration: underline; }

.tbl { margin-top: var(--sp-2); }
.tbl-filters {
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-3); align-items: flex-end;
  margin-bottom: var(--sp-3); padding: var(--sp-3) var(--sp-4);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
}
.tbl-filters p, .tbl-columns form label { margin: 0; }
.tbl-filters .tbl-filter { display: flex; flex-direction: column; gap: var(--sp-1); min-width: 11rem; flex: 1 1 11rem; max-width: 20rem; }
.tbl-filters .tbl-filter label { font-size: var(--fs-xs); }
.tbl-filters .tbl-filter input, .tbl-filters .tbl-filter select { height: 2.125rem; font-size: var(--fs-sm); padding: 0 var(--sp-2); }
.tbl-filters .tbl-filter select[multiple] { height: auto; min-height: 2.125rem; max-height: 7.5rem; padding: var(--sp-1); }
.tbl-filters .tbl-filter .range { display: flex; gap: var(--sp-1); align-items: center; }
.tbl-filters .tbl-filter .range input { flex: 1 1 0; min-width: 0; }
.tbl-filters .tbl-actions { margin-left: auto; display: flex; flex-direction: row; gap: var(--sp-2); align-items: center; flex: 0 0 auto; margin-bottom: 0; }
.tbl-filters .tbl-actions button, .tbl-filters .tbl-actions a { height: 2.125rem; font-size: var(--fs-sm); padding: 0 var(--sp-3); }
/* One line of tools above the table, to the right (task 0.18, С2): columns and views open as panels. */
.tbl-tools { display: flex; justify-content: flex-end; align-items: center; gap: var(--sp-4); flex-wrap: wrap; margin: var(--sp-2) 0; font-size: var(--fs-xs); color: var(--text-2); }
.tbl-tools details { position: relative; }
.tbl-tools summary { cursor: pointer; color: var(--brand); list-style: none; }
.tbl-tools summary::-webkit-details-marker { display: none; }
.tbl-panel { position: absolute; right: 0; top: calc(100% + var(--sp-1)); z-index: 30; min-width: 16rem; max-width: 92vw; padding: var(--sp-3); background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--radius-sm); box-shadow: var(--shadow); font-size: var(--fs-sm); color: var(--text); }
form.tbl-panel { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-3); align-items: center; max-width: 40rem; }
.tbl-panel label { font-weight: 400; color: var(--text); }
.tbl-panel .tbl-view { display: flex; align-items: center; gap: var(--sp-1); margin-bottom: var(--sp-1); }
.tbl-panel .tbl-view-save { display: flex; gap: var(--sp-2); align-items: center; flex-wrap: wrap; margin-top: var(--sp-2); padding-top: var(--sp-2); border-top: 1px solid var(--line); }
.tbl-panel .tbl-view-save input[type=text], .tbl-panel .tbl-view-save select { width: auto; height: 1.875rem; font-size: var(--fs-sm); }
.tbl-export a { margin-left: var(--sp-1); }
/* The multi-choice filter (task 0.18, С3): a field of the row's height; the list drops down. */
.tbl-multi { position: relative; }
.tbl-multi > summary { display: flex; align-items: center; justify-content: space-between; height: 2.125rem; padding: 0 var(--sp-2); font-size: var(--fs-sm); font-weight: 400; color: var(--text); background: var(--surface-2); border: 1px solid var(--line-2); border-radius: var(--radius-sm); cursor: pointer; list-style: none; white-space: nowrap; }
.tbl-multi > summary::-webkit-details-marker { display: none; }
.tbl-multi > summary::after { content: "▾"; color: var(--text-3); margin-left: var(--sp-2); }
.tbl-multi[open] > summary { border-color: var(--brand); }
.tbl-multi .tbl-multi-list { position: absolute; left: 0; top: calc(100% + 2px); z-index: 30; min-width: 100%; max-height: 16rem; overflow-y: auto; padding: var(--sp-2); background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--radius-sm); box-shadow: var(--shadow); }
.tbl-multi .tbl-multi-list label { display: flex; align-items: center; gap: var(--sp-2); padding: .2rem var(--sp-1); font-size: var(--fs-sm); font-weight: 400; color: var(--text); white-space: nowrap; cursor: pointer; border-radius: 4px; }
.tbl-multi .tbl-multi-list label:hover { background: var(--surface-3); }
.pager { margin-top: var(--sp-3); font-size: var(--fs-sm); color: var(--text-2); }
.pager a { margin: 0 var(--sp-2); }
/* The table scrolls, the page never does: sideways inside its own box, and downwards inside
   it too — which is what keeps the heading in place on the ten-thousandth row. */
.tbl .tbl-body { overflow: auto; max-height: 70vh; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow-sm); }
.tbl table { font-size: var(--fs-sm); }
.tbl th, .tbl td { padding: .4rem var(--sp-3); border-bottom: 1px solid var(--line); }
.tbl thead th { position: sticky; top: 0; z-index: 2; background: var(--surface); box-shadow: inset 0 -1px 0 var(--line-2); white-space: nowrap; }
.tbl tbody tr:hover td { background: var(--surface-3); }
.tbl tfoot td { position: sticky; bottom: 0; background: var(--surface-2); border-top: 1px solid var(--line-2); font-weight: 600; }
.tbl td.clip { max-width: 34rem; }
.tbl td.clip > .cut { display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; max-width: 34rem; }
.tbl-legend { font-size: var(--fs-xs); color: var(--text-2); margin: var(--sp-1) 0 var(--sp-2); }
.tbl-legend .st-mark { margin-right: var(--sp-1); }
.tbl-legend span + span { margin-left: var(--sp-3); }

/* ---------- panel «Что здесь делать», checks, tour ----------------------- */
.panel {
  position: relative; background: var(--warn-soft); border: 1px solid transparent; border-radius: var(--radius);
  padding: var(--sp-3) 2.6rem var(--sp-2) var(--sp-4); margin-bottom: var(--sp-4); font-size: var(--fs-sm);
}
.panel.closed { padding: 0; background: transparent; border-color: transparent; margin-bottom: var(--sp-2); }
.panel h2 { margin: 0 0 var(--sp-2); font-size: var(--fs-md); }
.panel-text p { margin-bottom: var(--sp-2); }
/* Help and hint texts rendered from Markdown-lite (task 0.17): the blocks they may contain. */
.help-text h2, .help-text h3 { font-size: var(--fs-lg); margin: var(--sp-5) 0 var(--sp-2); }
.help-text p, .help-text ul, .help-text ol { margin: 0 0 var(--sp-3); }
.help-text ul, .help-text ol, .panel-text ul, .panel-text ol { padding-left: 1.4rem; }
.help-text table, .panel-text table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); margin: 0 0 var(--sp-3); }
.help-text th, .help-text td, .panel-text th, .panel-text td { padding: var(--sp-1) var(--sp-2); border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
.help-text th, .panel-text th { background: var(--surface-2); font-weight: 600; color: var(--text-2); }
.help-text code, .panel-text code, form p code { padding: 0 .3em; border-radius: 4px; background: var(--surface-2); }
.panel-toggle { position: absolute; top: var(--sp-2); right: var(--sp-2); }
.panel-toggle button { height: 1.75rem; padding: 0 var(--sp-2); font-size: var(--fs-sm); background: transparent; border-color: var(--warn); color: var(--warn-text); }
.panel.closed .panel-toggle { position: static; }
.panel.closed .panel-toggle button { background: none; border: 0; color: var(--warn-text); padding: 0; height: auto; text-decoration: underline dotted; }
.checks ul { padding-left: 1rem; }
.tour-target { outline: 3px solid var(--brand); outline-offset: 3px; border-radius: var(--radius-sm); }
.tour-box {
  position: fixed; right: var(--sp-4); bottom: var(--sp-4); max-width: 360px; z-index: 1000;
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--radius); padding: var(--sp-4); box-shadow: var(--shadow-lg);
}
.tour-nav { display: flex; gap: var(--sp-2); align-items: center; justify-content: flex-end; margin-top: var(--sp-3); }
.tour-nav .tour-count { margin-right: auto; color: var(--text-2); font-size: var(--fs-sm); }
.tour-nav .tour-next { color: var(--on-brand); background: var(--brand); border-color: var(--brand); }

/* ---------- messages ----------------------------------------------------- */
.messages { list-style: none; padding: 0; margin: 0 0 var(--sp-4); display: grid; gap: var(--sp-2); }
.messages li { padding: var(--sp-3) var(--sp-4); border-radius: var(--radius-sm); background: var(--ok-soft); color: var(--ok-text); border: 1px solid transparent; font-size: var(--fs-sm); }
.messages li.error { background: var(--danger-soft); color: var(--danger-text); border-color: transparent; }
.messages li.warning { background: var(--warn-soft); color: var(--warn-text); border-color: transparent; }
.messages li.info { background: var(--info-soft); color: var(--info-text); border-color: transparent; }

/* ---------- small per-screen layout classes ------------------------------ */
.invite-link { min-width: 22rem; }
.copy-row { display: flex; gap: var(--sp-2); margin-top: var(--sp-1); }
.copy-row input { flex: 1 1 auto; min-width: 0; font-family: var(--mono); font-size: var(--fs-xs); height: 2rem; }
.copy-row button.copy { flex: 0 0 auto; height: 2rem; font-size: var(--fs-sm); padding: 0 var(--sp-3); }
/* The roles screen (task 7.2) is rebuilt as a tree by task 7.12: its rules live in «rights tree» at the end. */

.row-tools { display: inline-flex; gap: var(--sp-2); align-items: center; margin-left: var(--sp-2); font-size: var(--fs-xs); }
.row-tools button.link { font-size: var(--fs-sm); color: var(--text-2); }

/* Journal: the filter grid and the changes column (a JSON diff reads in monospace). */
.filters form { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: var(--sp-3); align-items: end; }
.filters form p { margin: 0; }
.changes { font-family: var(--mono); font-size: var(--fs-xs); white-space: pre-wrap; }
/* Two flows side by side (acts and certificates), two columns of a card (purchase price). */
.flows { display: grid; grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); gap: var(--sp-5); align-items: start; }
.two { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: var(--sp-5); align-items: start; }
/* A history under a value is grey on purpose: it is a hint, not a value (help-and-hints.md, 6). */
.history { color: var(--text-2); }
.history caption { text-align: left; color: var(--text-2); font-size: var(--fs-sm); padding-bottom: var(--sp-2); }
/* The platform administrator's current company, called out. */
.current { background: var(--warn-soft); border: 1px solid transparent; border-radius: var(--radius); padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-4); }
/* A table that is not the table component but wants its look: the platform lists. */
table.tbl-body { margin-top: var(--sp-3); background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); }
.card.flush { padding: 0; overflow-x: auto; }
/* A card folded behind its title (task 0.23): the transaction form under the tiles. */
details.card.fold > summary { cursor: pointer; list-style: none; }
details.card.fold > summary::-webkit-details-marker { display: none; }
details.card.fold > summary h2 { margin: 0; }
details.card.fold > summary::after { content: " ▾"; color: var(--text-3); }
details.card.fold[open] > summary::after { content: " ▴"; }
details.card.fold[open] > summary { margin-bottom: var(--sp-3); }
.sub.path { overflow-wrap: anywhere; margin-bottom: var(--sp-1); }
/* The error pages (task 0.24): the code large and grey, one line of what to do. */
.error-card { max-width: 560px; margin: 8vh auto 0; text-align: center; }
.error-card .error-code { font-size: 3rem; font-weight: 800; color: var(--text-3); letter-spacing: -.03em; line-height: 1; }
.error-card h1 { margin: var(--sp-2) 0; }
.error-card .actions-row { justify-content: center; }
/* The source of a takeoff line is a long trail of keys: kept narrow and wrapped, so the state column stays on screen (18.09.2026). */
td.src, th.src { width: 16rem; min-width: 12rem; max-width: 18rem; overflow-wrap: break-word; }
.card.flush table { border: 0; }

/* Utility classes for the small things templates used to say inline. */
.mt { margin-top: var(--sp-4); }
.mt-sm { margin-top: var(--sp-2); }
.ml { margin-left: var(--sp-4); }
.inline { display: inline; }
.ok { color: var(--ok-text); }
.danger-text { color: var(--danger-text); }
a.danger, button.link.danger { color: var(--danger); }
.scroll-x { overflow-x: auto; }
.plain-list { list-style: none; padding-left: 0; margin: 0; }
.logo-preview { max-height: 80px; }
/* A tree drawn as a list: the depth is a variable the row carries, the indent is here. */
.tree-row { padding: .15rem 0 .15rem calc(var(--depth, 0) * 1.4rem); }

/* ---------- narrow screen (methods/ui-style.md, 7а) ---------------------- */
@media (max-width: 900px) {
  nav.side { transform: translateX(-100%); width: min(var(--side-w), 86vw); box-shadow: none; overflow: hidden; }
  body.menu-open nav.side { transform: none; box-shadow: var(--shadow-lg); }
  .topbar { display: flex; }
  .content { margin-left: 0; }
  main { padding: var(--sp-4); }
  nav.side .menu a, nav.side .menu button.link { padding: .75rem var(--sp-3); font-size: 1.0625rem; }
}
@media (max-width: 640px) {
  html { font-size: 16px; }
  main { padding: var(--sp-3); }
  .card { padding: var(--sp-4); }
  .head { align-items: flex-start; }
  .tbl-filters .tbl-filter { flex: 1 1 calc(50% - .5rem); min-width: calc(50% - .5rem); max-width: none; }
  .tbl-filters .tbl-actions { flex: 1 1 100%; margin-left: 0; justify-content: flex-end; }
  /* The phone (task 0.19): the name column is seen first and stays put while the table
     scrolls sideways; secondary columns are hidden (still listed under «Колонки»). */
  .p-hide { display: none; }
  .p-key { position: sticky; left: 0; z-index: 1; min-width: 9rem; max-width: 55vw; background: var(--surface); box-shadow: 4px 0 8px -6px rgba(0, 0, 0, .45); }
  .tbl tbody tr:hover td.p-key { background: var(--surface-3); }
  .tbl thead th.p-key { z-index: 3; }
  .tbl tfoot td.p-key { background: var(--surface-2); }
  .p-key .cut, td.p-key { overflow-wrap: anywhere; }
  /* Nothing wider than the screen: a table lives inside a scrolling card, a control never grows past its box. */
  .card, .scroll-x, .tbl-body, table.history { max-width: 100%; overflow-x: auto; }
  /* A table that stands outside a card or the component scrolls in its own box, like table.history does. */
  main table:not(.tbl-body table) { display: block; overflow-x: auto; max-width: 100%; }
  .toggle a, .toggle span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .flows { grid-template-columns: 1fr; }
  .flows > div { min-width: 0; }
  .badge { white-space: normal; max-width: 100%; }
  main, main > *, .card { min-width: 0; }
  select, input, textarea, .stat, .tbl-multi .tbl-multi-list { max-width: 100%; box-sizing: border-box; }
  .tbl-multi .tbl-multi-list { max-width: calc(100vw - 2rem); }
  code, .mono, h1 code { overflow-wrap: anywhere; white-space: normal; }
  form.inline { flex-wrap: wrap; }
  form.inline input[type=text] { flex: 1 1 12rem; min-width: 0; }
  form.inline label { white-space: nowrap; }
  .estimate-actions .btn, .estimate-actions button { height: 2.125rem; font-size: var(--fs-sm); padding: 0 var(--sp-3); }
  form.inline > .sub, form.inline + .sub { flex: 1 1 100%; }
  .tbl-filters .tbl-filter:has(.range) { flex-basis: 100%; min-width: 100%; }
  .tbl-filters .tbl-filter .range input { min-width: 8rem; }
  /* Five tiles in two columns: the odd last one takes the row. */
  .stats .stat:last-child:nth-child(odd) { grid-column: 1 / -1; }
  /* A seven-digit sum fits a half-width tile only at a smaller size; it never wraps or clips. */
  .stat .v { font-size: 1.25rem; letter-spacing: -.01em; white-space: nowrap; }
  .stat { padding: var(--sp-3) var(--sp-3); min-width: 0; overflow: hidden; }
  a.stat::after { top: var(--sp-2); right: var(--sp-3); }
  /* The hub on the phone: two tiles per row, the hint only by hover/title. */
  .tiles { grid-template-columns: 1fr 1fr; }
  .quick-links { grid-template-columns: 1fr 1fr; }
  .tile .tile-hint { display: none; }
  /* The tour box keeps the top of the screen free. */
  .tour-box { max-height: 40vh; overflow-y: auto; }
  form.inline select { max-width: 100%; }
  .role-name input[type=text] { min-width: 0; width: 100%; }
  input, select, textarea { font-size: 16px; } /* no zoom-in on focus on the phone */
  .tbl-filters .tbl-actions { justify-content: flex-end; flex-direction: row; }
  .tour-box { left: var(--sp-3); right: var(--sp-3); bottom: var(--sp-3); max-width: none; }
  table.history { display: block; overflow-x: auto; }
  /* A navigation line on the phone is a grid of two columns: every pill the same
     width, orderly rows, nothing hidden behind a scroll (the owner's choice, 16.09.2026). */
  .toggle, .reference-nav { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2); }
  .toggle a, .reference-nav a, .reference-nav span { justify-content: center; text-align: center; padding: 0 var(--sp-2); }
  .head .toggle { display: flex; }
}

/* The rendered PDF page of the takeoff (task 6.4): clicked for the two-point calibration. */
#page-image { display: block; width: 100%; cursor: crosshair; border-radius: var(--radius-sm); }
tr.row-warn td:first-child { border-left: 3px solid var(--warn-text); }
blockquote { margin: var(--sp-2) 0; padding: var(--sp-2) var(--sp-3); border-left: 3px solid var(--line-2); background: var(--surface-2); border-radius: var(--radius-sm); }

/* The live line of a running agent (task 6.15). */
#agent-live .live-row { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
#agent-live .spinner { width: 14px; height: 14px; border: 2px solid var(--line-2); border-top-color: var(--accent, #3ddc97); border-radius: 50%; animation: agent-spin 0.9s linear infinite; }
#agent-live .live-bar { height: 4px; margin-top: var(--sp-2); background: var(--line); border-radius: 2px; overflow: hidden; }
#agent-live .live-fill { width: 30%; height: 100%; background: var(--accent, #3ddc97); animation: agent-slide 1.6s ease-in-out infinite; }
@keyframes agent-spin { to { transform: rotate(360deg); } }
@keyframes agent-slide { 0% { margin-left: -30%; } 100% { margin-left: 100%; } }

/* ---------- login: the face of the platform (task 0.21) ------------------ */
/* Two halves: the brand panel in the colours of the mark (never themed) and the card that
   follows the theme. No image and no outside font (ui-style.md, 9): the depth is gradients,
   the grid is drawn lines, the wordmark is a serif of the system. */
body.login main { max-width: none; margin: 0; padding: 0; min-height: 100vh; display: flex; }
body.login main > .messages { position: absolute; top: var(--sp-4); left: 50%; transform: translateX(-50%); z-index: 2; width: min(92vw, 480px); }
.login-screen { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); width: 100%; min-height: 100vh; }
.login-brand {
  position: relative; overflow: hidden; display: flex; align-items: center; color: var(--ident-paper);
  background:
    radial-gradient(ellipse 60% 50% at 18% 12%, color-mix(in srgb, var(--ident-gold) 22%, transparent), transparent 70%),
    radial-gradient(ellipse 50% 40% at 90% 95%, color-mix(in srgb, var(--ident-gold) 9%, transparent), transparent 70%),
    repeating-linear-gradient(0deg, color-mix(in srgb, var(--ident-paper) 5%, transparent) 0 1px, transparent 1px 48px),
    repeating-linear-gradient(90deg, color-mix(in srgb, var(--ident-paper) 5%, transparent) 0 1px, transparent 1px 48px),
    linear-gradient(160deg, var(--ident-green) 0%, var(--ident-dark) 75%);
}
/* The ring of the mark, huge and faint, behind the text: the plumb line as the room's architecture. */
.login-brand::after {
  content: ""; position: absolute; right: -14vw; bottom: -18vw; width: 48vw; height: 48vw; border-radius: 50%;
  border: 1.5px solid color-mix(in srgb, var(--ident-gold) 35%, transparent);
  box-shadow: inset 0 0 0 28px color-mix(in srgb, var(--ident-gold) 4%, transparent);
  pointer-events: none;
}
.login-brand-inner { position: relative; z-index: 1; max-width: 600px; padding: clamp(2.5rem, 6vw, 5.5rem); display: flex; flex-direction: column; gap: var(--sp-6); }
.login-mark { display: flex; align-items: center; gap: var(--sp-4); }
.login-mark svg { width: 64px; height: 64px; flex: 0 0 auto; color: var(--ident-paper); filter: drop-shadow(0 6px 18px color-mix(in srgb, var(--ident-dark) 60%, transparent)); }
.login-wordmark {
  font-family: "Cormorant Garamond", "EB Garamond", Garamond, "Palatino Linotype", "Book Antiqua", Georgia, serif;
  font-size: 2.125rem; font-weight: 600; letter-spacing: .22em; text-transform: uppercase; line-height: 1;
  color: var(--ident-paper); padding-left: .1em;
}
.login-tagline {
  font-family: "Cormorant Garamond", "EB Garamond", Garamond, "Palatino Linotype", "Book Antiqua", Georgia, serif;
  font-size: clamp(1.9rem, 3.2vw, 2.75rem); font-weight: 500; line-height: 1.12; letter-spacing: -.005em;
  margin: var(--sp-2) 0 0; color: var(--ident-paper); text-wrap: balance;
}
.login-lead { margin: 0; font-size: 1.0625rem; line-height: 1.6; color: color-mix(in srgb, var(--ident-paper) 78%, transparent); max-width: 34rem; }
.login-points { list-style: none; margin: var(--sp-2) 0 0; padding: var(--sp-5) 0 0; display: grid; gap: var(--sp-4); border-top: 1px solid color-mix(in srgb, var(--ident-gold) 30%, transparent); }
.login-points li { display: flex; gap: var(--sp-4); align-items: flex-start; font-size: var(--fs-sm); line-height: 1.5; color: color-mix(in srgb, var(--ident-paper) 70%, transparent); }
.login-points b { display: block; font-weight: 600; font-size: var(--fs-md); color: var(--ident-paper); margin-bottom: 1px; }
.login-point-ico {
  flex: 0 0 auto; width: 2.5rem; height: 2.5rem; display: grid; place-items: center; border-radius: var(--radius-sm);
  color: var(--ident-gold); border: 1px solid color-mix(in srgb, var(--ident-gold) 45%, transparent);
  background: color-mix(in srgb, var(--ident-gold) 8%, transparent);
}
.login-point-ico svg { width: 22px; height: 22px; }
.login-foot { margin: var(--sp-4) 0 0; font-size: var(--fs-xs); letter-spacing: .14em; text-transform: uppercase; color: color-mix(in srgb, var(--ident-paper) 50%, transparent); }

.login-side { display: grid; place-items: center; padding: var(--sp-8) var(--sp-6); background: var(--bg); }
.login-card { width: 100%; max-width: 440px; padding: var(--sp-8) var(--sp-8) var(--sp-6); box-shadow: var(--shadow); animation: login-in .5s ease-out both; }
.login-top { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-6); }
.login-card .langs { display: flex; gap: 2px; padding: 2px; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--line); }
.login-card .langs button {
  height: 1.75rem; min-width: 2.5rem; padding: 0 var(--sp-2); border: 0; border-radius: 999px; background: transparent;
  color: var(--text-2); font-size: var(--fs-xs); font-weight: 600; text-transform: uppercase; letter-spacing: .04em;
}
.login-card .langs button:hover { color: var(--text); background: var(--surface-3); }
.login-card .langs button.active { color: var(--on-brand); background: var(--brand); }
.login-card .theme { height: 1.75rem; padding: 0 var(--sp-2); font-size: var(--fs-xs); color: var(--text-2); background: transparent; border: 1px solid var(--line); border-radius: 999px; }
.login-card .theme:hover { color: var(--text); background: var(--surface-2); }
.login-card h1 { font-size: 1.75rem; margin-bottom: var(--sp-1); }
.login-card > .sub { margin-bottom: var(--sp-5); }
.login-error { margin: 0 0 var(--sp-4); padding: var(--sp-3) var(--sp-4); border-radius: var(--radius-sm); background: var(--danger-soft); color: var(--danger-text); font-size: var(--fs-sm); line-height: 1.45; }
.login-form input { height: 2.75rem; }
.login-submit { width: 100%; height: 2.75rem; margin-top: var(--sp-2); font-weight: 600; font-size: var(--fs-md); box-shadow: 0 6px 18px var(--brand-soft); }
.login-register { margin: var(--sp-5) 0 0; text-align: center; font-weight: 500; }
.login-note { margin: var(--sp-5) 0 0; padding-top: var(--sp-4); border-top: 1px solid var(--line); font-size: var(--fs-xs); color: var(--text-3); text-align: center; line-height: 1.5; }
@keyframes login-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .login-card { animation: none; } }

/* Tablet and phone: the halves stack; the brand panel is a header, not a room. */
@media (max-width: 900px) {
  .login-screen { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .login-brand { min-height: 0; }
  .login-brand::after { width: 70vw; height: 70vw; right: -30vw; bottom: -45vw; }
  .login-brand-inner { max-width: none; padding: clamp(1.75rem, 5vw, 3rem) var(--sp-5); gap: var(--sp-4); }
  .login-tagline { font-size: clamp(1.6rem, 5vw, 2.25rem); }
  .login-side { padding: var(--sp-5) var(--sp-4) var(--sp-8); align-items: start; }
  .login-card { padding: var(--sp-6) var(--sp-5); }
}
@media (max-width: 640px) {
  .login-points, .login-lead { display: none; }
  .login-mark svg { width: 48px; height: 48px; }
  .login-wordmark { font-size: 1.625rem; }
  .login-foot { margin-top: 0; }
  .login-card .langs button { min-width: 2.25rem; }
}

/* ---------- access request (task 0.22) ----------------------------------- */
.access-card { max-width: 560px; margin: 0 auto; }
.access-brand { display: inline-flex; align-items: center; gap: var(--sp-3); color: var(--text); margin-bottom: var(--sp-5); text-decoration: none; }
.access-brand:hover { text-decoration: none; }
.access-brand svg { width: 40px; height: 40px; }
.access-brand .login-wordmark { font-size: 1.375rem; color: var(--text); }
.access-form textarea { min-height: 6rem; }
/* The trap for bots: off the screen for a person, an ordinary field for a script. */
.access-trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.access-message { max-width: 28rem; white-space: normal; font-size: var(--fs-sm); }
.access-reject { margin-top: var(--sp-2); }
.access-reject input[type=text] { width: 14rem; height: 2rem; font-size: var(--fs-sm); }
.access-link { width: 100%; min-width: 14rem; font-size: var(--fs-xs); height: 2rem; margin-top: var(--sp-1); }
.menu-count { display: inline-flex; min-width: 1.25rem; height: 1.25rem; padding: 0 .35rem; margin-left: auto; align-items: center; justify-content: center; border-radius: 999px; background: var(--brand); color: var(--on-brand); font-size: var(--fs-xs); font-weight: 700; line-height: 1; }
.login-request { width: 100%; margin-top: var(--sp-4); }

/* ---------- rights tree (task 7.12) -------------------------------------- */
/* The roles screen: groups as the menu, screens, what lives under them — the depth is an indent. */
.rights-all { display: flex; flex-direction: row; align-items: center; gap: var(--sp-2); margin: 0 0 var(--sp-3); flex-wrap: wrap; }
.rights-all button { height: 2rem; font-size: var(--fs-sm); }
.rights table { width: 100%; }
.rights th.cell, .rights td.cell { text-align: center; width: 6.5rem; }
.rights th button, .rights td.row-label button, .rights .rights-group button[data-toggle-group] {
  height: auto; padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer;
}
.rights th button:hover, .rights td.row-label button:hover, .rights .rights-group button[data-toggle-group]:hover { color: var(--brand-text); text-decoration: underline; background: none; }
.rights tr.rights-group td { background: var(--surface-2); font-weight: 700; font-size: var(--fs-xs); letter-spacing: .06em; text-transform: uppercase; color: var(--text-2); padding: var(--sp-2) var(--sp-3); }
.rights .rights-fold { width: 1.5rem; height: 1.5rem; padding: 0; margin-right: var(--sp-2); border: 0; background: none; color: var(--text-3); font-size: var(--fs-sm); cursor: pointer; }
.rights .rights-fold:hover { color: var(--text); background: none; }
.rights tr.rights-row td.row-label { padding-left: var(--sp-3); }
.rights tr.depth-1 td.row-label { padding-left: calc(var(--sp-3) + 1.5rem); }
.rights tr.depth-2 td.row-label { padding-left: calc(var(--sp-3) + 3rem); }
.rights tr.area td.row-label, .rights tr.screen td.row-label { font-weight: 600; }
.rights tr.single td.row-label { color: var(--text-2); font-size: var(--fs-sm); }
.rights tr.single td.row-label button { color: var(--text-2); }
.rights td.cell input[type=checkbox] { width: 1.1rem; height: 1.1rem; margin: 0; }
.rights td.cell.is-changed { background: var(--brand-soft); box-shadow: inset 0 0 0 1px var(--brand); }
.rights tr.is-new td.row-label { border-left: 3px solid var(--ok); }
.new-rights { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-4); flex-wrap: wrap; margin-bottom: var(--sp-4); padding: var(--sp-3) var(--sp-4); border-radius: var(--radius-sm); background: var(--ok-soft); color: var(--ok-text); border: 1px solid transparent; font-size: var(--fs-sm); }
.new-rights .sub { display: block; margin-top: var(--sp-1); }

/* The «apply» row under the auditor's findings (task 6.17; the inline style found by the full run 20.09.2026). */
.apply-row { padding: var(--sp-2) var(--sp-4); }

/* Contract chapters in two levels (task 7.10): a sub-chapter row is indented. */
.chapters-grid tr.sub-chapter td:first-child, table tr.sub-chapter td:first-child { padding-left: var(--sp-6); }
.chapters-grid tr.sub-chapter td { color: var(--text-2); }
/* The percentage of a chapter in a draft certificate (task 7.10): a short field beside the figure. */
.estimate-form input[type=number] { width: 5.5rem; height: 2rem; font-size: var(--fs-sm); text-align: right; }
tr.chapter-head td { background: var(--surface-2); font-weight: 600; }

/* Flag families on the sheet (20.09.2026): the same hue on the card's row and on every flag of that family. */
.fg { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 6px; vertical-align: middle; background: var(--fg-color, transparent); }
.flag-line { border-left: 3px solid var(--fg-color, transparent); padding-left: 6px; }
.fg-0 { --fg-color: #ff9800; } .fg-1 { --fg-color: #29b6f6; } .fg-2 { --fg-color: #ab47bc; } .fg-3 { --fg-color: #66bb6a; }
.fg-4 { --fg-color: #ef5350; } .fg-5 { --fg-color: #ffee58; } .fg-6 { --fg-color: #26c6da; } .fg-7 { --fg-color: #8d6e63; }
tr.row-active > td { background: rgba(255, 255, 255, .06); }

/* A card that asks for an action: «цена не известна — найти в интернете» (task 4.5, 24.09.2026). */
.card.warn-box { border-left: 4px solid var(--warn); background: var(--warn-soft); }
.card.warn-box p { margin-top: 0; }

/* The takeoff sheet (05.10.2026): long flags and sources wrap inside their column instead of pushing the table past
   the screen, where the person saw half a sentence and no way to the rest. */
.takeoff-lines td.state { min-width: 220px; max-width: 380px; }
.takeoff-lines td.state .flag-line, .takeoff-lines td.src { overflow-wrap: anywhere; white-space: normal; }
.takeoff-lines td.src { max-width: 280px; }
.takeoff-lines td.state input[type=text] { max-width: 100%; box-sizing: border-box; }
.takeoff-lines td.state > div, .takeoff-lines td.state details { max-width: 380px; }

