/* =============================================================================
   design-system.css — the interface rulebook, in code.
   Owner-approved 2026-08-07 across seven forks; the rules themselves live in
   .ai/design-system/RULEBOOK.md and this file is their only implementation.
   Re-dressed 2026-09-25 to the owner-approved configurator design «c5»: Google
   Sans, the c5 palette and the c5 sizes became the rulebook (owner's choice after
   a side-by-side of c5 and the 07.08 rulebook).

   TWO INVARIANTS, both machine-checked by orderly/tests/test_design_system.py:

   1. EVERY selector here is scoped under `.ds`. Not one bare element selector,
      not one override of a legacy brick (.button/.table-list/.table-form/
      .status-chip/.page-menu/.sidebar/.messages). A screen opts in by putting
      `ds` on <body>; a screen that does not opt in cannot be touched by this
      file, no matter what we add to it later.

   2. Anything that sets `display` is paired with a [hidden] rule. This is not
      theory: it already broke in production once (see the comment in
      sitebase/templates/sitebase/execution.html) when an author's display:flex
      beat the browser's [hidden] and the red "saving is failing" strip hung
      permanently for the Execution team. The pairing lives at the bottom of
      this file and covers every brick at once.

   The palette lives in ONE place: the token block right below the font faces.
   A hex colour anywhere else in this file fails the build.
   ============================================================================= */

/* Google Sans, self-hosted (SIL OFL 1.1, fonts/google-sans/OFL.txt). Served from
   our own static files, not from Google: the browser-test sandbox denies all
   egress, and a screen must not change its typeface when a CDN is slow. */
@font-face {
    font-family: 'Google Sans';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('fonts/google-sans/google-sans-cyrillic-ext.woff2') format('woff2');
    unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
    font-family: 'Google Sans';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('fonts/google-sans/google-sans-cyrillic.woff2') format('woff2');
    unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
    font-family: 'Google Sans';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('fonts/google-sans/google-sans-symbols.woff2') format('woff2');
    unicode-range: U+2190, U+2192, U+2194-2199;
}
@font-face {
    font-family: 'Google Sans';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('fonts/google-sans/google-sans-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Google Sans';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('fonts/google-sans/google-sans-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ============ TOKENS — the only place a colour or a size is typed ============ */
.ds {
    /* Palette (c5). */
    --bg: #F4F4F5;
    --surface: #FFFFFF;
    --surface-2: #FAFAFA;
    --surface-3: #F4F4F5;
    --border: #E4E4E7;
    --border-strong: #D4D4D8;
    --text: #18181B;
    --text-2: #52525B;
    --text-3: #6B6B74;
    --accent: #0F766E;
    --accent-hover: #0B5E58;
    --accent-soft: #E7F3F1;
    --accent-line: #99CFC8;
    --warn: #A15C07;
    --warn-soft: #FDF5E6;
    --warn-line: #F0D49B;
    --danger: #C62828;
    --danger-soft: #FDF0F0;
    --ok: #15803D;
    --ok-soft: #EAF6EE;
    --row-hover: #F6F7F7;
    --row-sel: #F0F7F6;
    --row-sel-hover: #E5F1EF;
    --row-repl: #FEF9EF;
    --row-repl-hover: #FCF2DD;
    --row-repl-edge: #D99A2B;
    --row-gone: #FDF4F4;
    --row-gone-hover: #FAE9E9;
    --row-gone-edge: #E08E8E;
    --on-accent: #FFFFFF;
    --shadow: 0 1px 2px rgba(24, 24, 27, .05);
    --shadow-bar: 0 6px 16px rgba(24, 24, 27, .10);
    --shadow-pop: 0 20px 48px rgba(24, 24, 27, .22);
    --overlay: rgba(24, 24, 27, .42);

    /* Type (c5). One family; numbers use tabular figures. */
    --font: 'Google Sans', system-ui, sans-serif;
    --w-display: 600;
    --fs-cap: 11px;     /* uppercase section labels */
    --ls-cap: .08em;
    --fs-xs: 12px;      /* table headers, the «из ТЗ» line */
    --lh-xs: 16px;
    --fs-sm: 13px;      /* hints, secondary lines */
    --lh-sm: 18px;
    --fs-base: 14px;    /* working text, tables, inputs */
    --lh-base: 20px;
    --fs-h2: 18px;      /* dialog titles, the shortage headline */
    --fs-title: 22px;   /* screen title */
    --lh-title: 28px;
    --fs-kpi: 40px;     /* a secondary headline number */
    --fs-big: 56px;     /* THE number of a screen */

    /* Spacing and control heights (c5). */
    --s1: 4px;
    --s2: 8px;
    --s3: 12px;
    --s4: 16px;
    --s5: 20px;
    --s6: 24px;
    --s8: 32px;
    --s12: 48px;
    --h: 34px;
    --h-sm: 30px;
    --h-lg: 40px;
    --r: 6px;           /* controls */
    --r-card: 10px;     /* cards and bars */
}

/* The type and the ink reach only what the rulebook draws: a full-screen rulebook
   page, or the content block of a rulebook dialog inside the CRM shell. The shell
   itself (sidebar, menus) keeps its own look on every page. */
.ds.ds-full, .ds .ds-narrow {
    font-family: var(--font);
    font-size: var(--fs-base);
    line-height: var(--lh-base);
    color: var(--text);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* A full-screen rulebook page (the configurator) owns its background; a page that
   lives inside the CRM shell keeps the shell's. */
.ds.ds-full { margin: 0; background: var(--bg); }
.ds.ds-full *, .ds.ds-full *::before, .ds.ds-full *::after { box-sizing: border-box; }
.ds .ds-nw { white-space: nowrap; }
.ds .ds-muted { color: var(--text-3); }
.ds a.ds-a { color: var(--accent); text-decoration: none; text-underline-offset: 3px; }
.ds a.ds-a:hover { text-decoration-line: underline; }
.ds.ds-full :where(button), .ds.ds-full :where(input), .ds.ds-full :where(select), .ds.ds-full :where(textarea) { font: inherit; color: inherit; }
.ds.ds-full input::placeholder, .ds.ds-full textarea::placeholder { color: var(--text-3); opacity: 1; }
.ds.ds-full input[type=checkbox], .ds.ds-full input[type=radio] { accent-color: var(--accent); width: 15px; height: 15px; margin: 0; flex: none; }

/* digits line up under digits wherever a number is shown */
.ds .ds-num, .ds .ds-big, .ds .ds-kpi-v { font-variant-numeric: tabular-nums lining-nums; }

/* A {% region %} declaration is bookkeeping, not layout: its wrapper must never
   break the grid or the flex row it sits in. */
.ds .ds-region { display: contents; }

/* ============ BRICK: top crumbs (full-screen pages) ============ */
.ds .ds-crumbs {
    height: 32px;
    display: flex;
    align-items: center;
    gap: var(--s2);
    padding: 0 var(--s6);
    border-bottom: 1px solid var(--border);
    background: var(--surface);
    font-size: var(--fs-sm);
    line-height: var(--lh-sm);
    color: var(--text-3);
}
.ds .ds-crumbs b { color: var(--text); font-weight: 700; letter-spacing: .08em; }
.ds .ds-crumbs a { color: var(--text-2); text-decoration: none; }
.ds .ds-crumbs a:hover { color: var(--text); }
.ds .ds-crumbs .ds-sep { color: var(--border-strong); }

/* ============ BRICK: screen header (title + state + actions) ============ */
.ds .ds-head {
    display: flex;
    align-items: baseline;
    gap: 20px;
    padding: 18px var(--s6) var(--s4);
    background: var(--surface);
    border-bottom: 1px solid var(--border);
}
.ds .ds-head h1 {
    font-size: var(--fs-title);
    line-height: var(--lh-title);
    font-weight: var(--w-display);
    margin: 0;
    letter-spacing: -.015em;
    white-space: nowrap;
}
.ds .ds-head-links { display: flex; gap: 20px; font-weight: 500; white-space: nowrap; }
.ds .ds-head-right { margin-left: auto; display: flex; align-items: center; gap: var(--s3); align-self: center; }

/* ============ BRICK: section heading ============ */
.ds .ds-cap {
    font-size: var(--fs-cap);
    line-height: 16px;
    font-weight: 600;
    letter-spacing: var(--ls-cap);
    text-transform: uppercase;
    color: var(--text-3);
}
.ds .ds-sect {
    display: flex;
    gap: var(--s2);
    align-items: baseline;
    font-size: var(--fs-cap);
    font-weight: 600;
    letter-spacing: var(--ls-cap);
    text-transform: uppercase;
    color: var(--text-3);
    margin: var(--s6) 0 var(--s2);
    padding-bottom: var(--s1);
    border-bottom: 1px solid var(--border);
}
.ds .ds-sect .ds-n { color: var(--text); }

/* ============ BRICK: button ============
   ds-btn is THE action of a screen (filled, one per screen); ds-quiet is every
   other action; ds-plain is a link-like action that must not compete. */
.ds .ds-btn {
    height: var(--h);
    padding: 0 14px;
    border: 1px solid var(--accent);
    background: var(--accent);
    color: var(--on-accent);
    border-radius: var(--r);
    font: inherit;
    font-weight: 600;
    line-height: 1;
    letter-spacing: .005em;
    cursor: pointer;
    white-space: nowrap;
    flex: none;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--s2);
}
.ds .ds-btn:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.ds .ds-btn:disabled { background: var(--border-strong); border-color: var(--border-strong); color: var(--on-accent); cursor: not-allowed; }
.ds .ds-btn.ds-quiet { background: var(--surface); color: var(--text); border-color: var(--border-strong); font-weight: 500; }
.ds .ds-btn.ds-quiet:hover { background: var(--surface-3); }
.ds .ds-btn.ds-quiet:disabled { color: var(--text-3); background: var(--surface); }
.ds .ds-btn.ds-plain { background: transparent; border-color: transparent; color: var(--text-3); font-weight: 400; }
.ds .ds-btn.ds-plain:hover { background: var(--surface-3); color: var(--text-2); }
.ds .ds-btn.ds-ghost { background: var(--surface); color: var(--accent); border-color: var(--border-strong); }
.ds .ds-btn.ds-danger { background: var(--surface); color: var(--danger); border-color: var(--border-strong); }
/* Filled red is reserved for the ONE destructive action a confirm screen exists to
   ask about. Everywhere else a destructive control uses the outline form above, so
   that a page full of red never trains people to click through it. */
.ds .ds-btn.ds-danger-solid { background: var(--danger); border-color: var(--danger); color: var(--on-accent); }
/* Darkened on hover with a filter, not with a second red typed by hand. */
.ds .ds-btn.ds-danger-solid:hover { filter: brightness(0.92); }
.ds .ds-btn.ds-sm { height: var(--h-sm); padding: 0 10px; font-size: var(--fs-sm); }
.ds .ds-btn.ds-lg { height: var(--h-lg); padding: 0 20px; }
.ds .ds-btn.ds-wide { width: 100%; }

/* ============ BRICK: field (label + input + ONE hint) ============ */
.ds .ds-field { margin-bottom: var(--s3); }
.ds .ds-field > label {
    display: block;
    font-weight: 500;
    color: var(--text-2);
    font-size: var(--fs-sm);
    line-height: var(--lh-sm);
    margin-bottom: 6px;
}
.ds .ds-in {
    height: var(--h);
    width: 100%;
    border: 1px solid var(--border-strong);
    border-radius: var(--r);
    padding: 0 10px;
    font: inherit;
    background: var(--surface);
    color: var(--text);
    outline: none;
    font-variant-numeric: tabular-nums lining-nums;
}
.ds .ds-in.ds-in-num { text-align: right; }
.ds textarea.ds-in { height: auto; min-height: 56px; padding: 7px 10px; resize: vertical; line-height: var(--lh-base); }
.ds select.ds-in { padding: 0 6px 0 9px; }
.ds .ds-in:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.ds .ds-in[readonly], .ds .ds-in:disabled { background: var(--surface-2); color: var(--text-2); }
/* The hint is ONE short sentence. Anything longer belongs on the help page. */
.ds .ds-hint { font-size: var(--fs-sm); line-height: var(--lh-sm); color: var(--text-3); text-wrap: pretty; }
.ds .ds-src  { font-size: var(--fs-xs); line-height: var(--lh-xs); color: var(--text-3); }

.ds .ds-row2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s4); }
.ds .ds-row3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s4); }
.ds .ds-row4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s4); }

/* ============ BRICK: action bar ============ */
.ds .ds-actions {
    display: flex;
    gap: var(--s2);
    flex-wrap: wrap;
    align-items: center;
    margin: var(--s4) 0;
}

/* ============ BRICK: disclosure (the only way to fold rarely needed things) ============ */
.ds .ds-disc {
    display: flex;
    align-items: center;
    gap: var(--s2);
    width: 100%;
    border: 0;
    background: none;
    padding: var(--s2) 0;
    cursor: pointer;
    font: inherit;
    font-weight: 500;
    color: var(--text);
    text-align: left;
}
.ds .ds-disc::before {
    content: "";
    flex: none;
    width: 6px;
    height: 6px;
    border-right: 1.5px solid var(--text-3);
    border-bottom: 1.5px solid var(--text-3);
    transform: rotate(-45deg);
    transition: transform .15s;
    margin: 0 3px;
}
.ds .ds-disc[aria-expanded=true]::before { transform: rotate(45deg); }
.ds .ds-disc.ds-disc-sm { font-weight: 400; color: var(--text-2); padding: var(--s1) 0; font-size: var(--fs-sm); }

/* ============ BRICK: card ============ */
.ds .ds-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-card);
    box-shadow: var(--shadow);
    overflow: hidden;
}
.ds .ds-cardhead {
    display: flex;
    align-items: center;
    gap: var(--s3);
    padding: 14px var(--s4) var(--s3);
    border-bottom: 1px solid var(--border);
}
.ds .ds-cardhead .ds-cap { color: var(--text-2); }
.ds .ds-kv {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: var(--s2) var(--s4);
}
.ds .ds-kv dt { color: var(--text-2); }
.ds .ds-kv dd { font-weight: 600; margin: 0; }

/* ============ BRICK: table ============
   A row is 37px: 8 + 20 + 8 and the rule under it (c5). */
.ds .ds-tblwrap {
    border: 1px solid var(--border);
    border-radius: var(--r-card);
    overflow: auto;
    background: var(--surface);
}
.ds table.ds-tbl {
    width: 100%;
    border-collapse: collapse;
    background: var(--surface);
}
.ds table.ds-tbl.ds-fixed { table-layout: fixed; }
.ds table.ds-tbl th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--surface-2);
    text-align: left;
    font-weight: 500;
    font-size: var(--fs-xs);
    line-height: var(--lh-xs);
    letter-spacing: .01em;
    color: var(--text-2);
    padding: var(--s2) var(--s3);
    border-bottom: 1px solid var(--border-strong);
    white-space: nowrap;
}
.ds table.ds-tbl td {
    padding: var(--s2) var(--s3);
    line-height: var(--lh-base);
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-variant-numeric: tabular-nums lining-nums;
}
/* the first column lines up with the card title: 16px from the card edge */
.ds table.ds-tbl tr > td:first-child, .ds table.ds-tbl tr > th:first-child { padding-left: var(--s4); }
.ds table.ds-tbl td.ds-num, .ds table.ds-tbl th.ds-num { text-align: right; }
.ds table.ds-tbl tbody tr.ds-r:hover td { background: var(--row-hover); }
.ds table.ds-tbl tbody tr:last-child td { border-bottom: 0; }
.ds table.ds-tbl tbody tr.ds-total td { font-weight: 600; background: var(--surface-3); }
.ds table.ds-tbl tr.ds-grp td {
    background: var(--surface-3);
    font-weight: 600;
    font-size: var(--fs-sm);
    line-height: var(--lh-sm);
    color: var(--text-2);
    padding: 6px var(--s3) 6px var(--s4);
}
.ds table.ds-tbl tr.ds-grp .ds-muted { font-weight: 500; margin-left: var(--s2); font-variant-numeric: tabular-nums; }
.ds table.ds-tbl td.ds-sub { color: var(--text-2); }
.ds table.ds-tbl td.ds-site { font-weight: 500; }
.ds .ds-dash { color: var(--text-3); }
/* quality: a dot, filled for «Ценный», grey for the spares */
.ds .ds-q { display: inline-flex; align-items: center; gap: var(--s2); max-width: 100%; overflow: hidden; vertical-align: bottom; }
.ds .ds-q::before { content: ""; flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }
.ds .ds-q.ds-q-res::before { background: var(--border-strong); }
.ds .ds-q span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ds .ds-tag {
    display: inline-block;
    font-size: var(--fs-xs);
    line-height: 18px;
    padding: 0 6px;
    border-radius: 4px;
    background: var(--surface-3);
    color: var(--text-2);
    border: 1px solid var(--border);
    font-weight: 500;
}
.ds .ds-tag.ds-tag-w { background: var(--warn-soft); color: var(--warn); border-color: var(--warn-line); }
.ds .ds-tag + .ds-tag { margin-left: var(--s1); }

/* ============ BRICK: metric tile ============ */
.ds .ds-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 260px));
    gap: var(--s3);
    margin: var(--s3) 0;
}
.ds .ds-tile {
    border: 1px solid var(--border);
    border-radius: var(--r-card);
    background: var(--surface);
    box-shadow: var(--shadow);
    padding: var(--s4);
}
.ds .ds-tile .ds-k { font-size: var(--fs-cap); letter-spacing: var(--ls-cap); text-transform: uppercase; color: var(--text-3); font-weight: 600; }
.ds .ds-tile .ds-v { font-size: var(--fs-kpi); line-height: 1; font-weight: var(--w-display); letter-spacing: -.03em; margin-top: var(--s3); font-variant-numeric: tabular-nums; }
.ds .ds-tile .ds-s { font-size: var(--fs-sm); color: var(--text-3); }

/* ============ BRICKS: the five mandatory screen states ============ */
.ds .ds-empty {
    border: 1px dashed var(--border-strong);
    border-radius: var(--r-card);
    background: var(--surface);
    padding: var(--s8);
    text-align: center;
}
.ds .ds-empty h3 { font-size: var(--fs-h2); margin: 0 0 var(--s1); }
.ds .ds-empty p  { color: var(--text-2); margin: 0 0 var(--s3); }

.ds .ds-skel {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-card);
    padding: var(--s3);
}
.ds .ds-skel i {
    display: block;
    height: 12px;
    background: var(--surface-3);
    border-radius: 3px;
    margin-bottom: 9px;
}
.ds .ds-skel i:nth-child(1) { width: 72%; }
.ds .ds-skel i:nth-child(2) { width: 54%; }
.ds .ds-skel i:nth-child(3) { width: 66%; }
.ds .ds-skel i:nth-child(4) { width: 45%; }
.ds .ds-skel i:last-child   { margin-bottom: 0; }

.ds .ds-partial {
    background: var(--warn-soft);
    border-left: 3px solid var(--warn-line);
    border-radius: var(--r);
    padding: var(--s2) var(--s3);
    font-size: var(--fs-sm);
    margin-bottom: var(--s2);
}

/* An error MUST answer "is my data safe?". If it is, say so in words — that is
   the project's red line expressed in the interface layer. */
.ds .ds-error {
    background: var(--surface);
    border: 1px solid var(--danger);
    border-left-width: 3px;
    border-radius: var(--r);
    padding: var(--s3);
}
.ds .ds-error b    { display: block; margin-bottom: var(--s1); }
.ds .ds-error span { color: var(--text-2); }

/* ============ BRICK: no-access notice ============ */
.ds .ds-noaccess {
    border: 1px dashed var(--border-strong);
    border-radius: var(--r-card);
    background: var(--surface);
    padding: var(--s8);
    text-align: center;
    color: var(--text-2);
}
.ds .ds-noaccess b {
    display: block;
    color: var(--text);
    font-size: var(--fs-h2);
    margin-bottom: var(--s1);
}

/* ============ BRICK: screen notice (why an action is unavailable) ============
   One line under the header, in words; the blocked control stays visible and
   disabled, so the person sees what is waiting and why. */
.ds .ds-notice {
    padding: var(--s3) var(--s6);
    background: var(--warn-soft);
    border-bottom: 1px solid var(--warn-line);
    color: var(--text);
}

/* ============ BRICK: toast (the short message after an action) ============ */
.ds .ds-toasts {
    position: fixed;
    left: 50%;
    bottom: var(--s6);
    transform: translateX(-50%);
    z-index: 60;
    display: flex;
    flex-direction: column;
    gap: var(--s2);
    list-style: none;
    margin: 0;
    padding: 0;
    max-width: 720px;
}
.ds .ds-toast {
    background: var(--text);
    color: var(--on-accent);
    border-radius: var(--r-card);
    box-shadow: var(--shadow-pop);
    padding: var(--s3) var(--s4);
}
.ds .ds-toast.ds-toast-error { background: var(--danger); }

/* ============ BRICK: staging strip (test server only) ============ */
.ds .ds-staging {
    background: var(--warn-soft);
    color: var(--warn);
    border-bottom: 1px solid var(--warn-line);
    padding: 6px var(--s4);
    text-align: center;
    font-weight: 600;
    font-size: var(--fs-sm);
}

/* ============ CONFIGURATOR «before»: parameters rail + result ============ */
.ds .ds-work { display: grid; grid-template-columns: 420px 1fr; align-items: start; }
.ds .ds-rail {
    background: var(--surface);
    border-right: 1px solid var(--border);
    padding: 20px 20px 28px;
    min-height: 100%;
    align-self: stretch;
    margin: 0;
}
.ds .ds-rail > .ds-cap { margin: 0 0 var(--s2); }
.ds .ds-f { display: grid; grid-template-columns: 1fr 108px; align-items: center; gap: 6px 10px; padding: var(--s1) 0; }
.ds .ds-f > label, .ds .ds-f > .ds-lbl { color: var(--text-2); }
.ds .ds-f.ds-f-wide { grid-template-columns: 96px 1fr; }
.ds .ds-f.ds-f-stack { grid-template-columns: 1fr; }
.ds .ds-f.ds-f-check { grid-template-columns: 1fr auto; cursor: pointer; color: var(--text); }
.ds .ds-f.ds-f-check > span { color: var(--text); }
.ds .ds-err-msg { grid-column: 1 / -1; color: var(--danger); font-size: var(--fs-sm); line-height: var(--lh-sm); text-align: right; margin-top: -2px; }
.ds .ds-f.ds-f-stack .ds-err-msg { text-align: left; }
.ds .ds-f.ds-err .ds-in { border-color: var(--danger); background: var(--danger-soft); }
.ds .ds-hr { height: 1px; background: var(--border); margin: var(--s3) 0; }
.ds .ds-mm { display: grid; grid-template-columns: 1fr 108px 108px; gap: 6px 10px; align-items: center; padding: var(--s1) 0; }
.ds .ds-mm-h { font-size: var(--fs-xs); line-height: var(--lh-xs); color: var(--text-3); text-align: right; padding-right: 11px; }
.ds .ds-mm-rl { color: var(--text-2); }
.ds .ds-fromtz { grid-column: 2 / 4; font-size: var(--fs-xs); line-height: var(--lh-xs); color: var(--text-3); margin-top: -2px; }
.ds .ds-mm .ds-err-msg { grid-column: 2 / 4; text-align: left; }
/* a note under a field: what the screen did or what the PM should know there */
.ds .ds-note { grid-column: 1 / -1; color: var(--warn); font-size: var(--fs-sm); line-height: var(--lh-sm); }
.ds .ds-note .ds-btn { margin-top: var(--s1); }
.ds .ds-note.ds-note-err { color: var(--danger); margin-bottom: var(--s2); }
.ds .ds-note-slot { display: contents; }
/* a number that fails its check, marked on the input itself (grid rows hold two) */
.ds .ds-in.ds-in-err { border-color: var(--danger); background: var(--danger-soft); }
.ds .ds-fold { padding: 0 0 var(--s1); }
.ds .ds-fold .ds-f-stack { margin-top: 6px; }
/* «Язык площадки»: groups, «Остальные» with its languages in two columns (part 5) */
.ds .ds-lang { display: grid; gap: 4px; }
.ds .ds-lang label { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
.ds .ds-lang summary { cursor: pointer; }
.ds .ds-lang summary label { vertical-align: middle; }
.ds .ds-lang-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px 14px;
    margin: 4px 0 0 22px; font-size: var(--fs-sm); }

.ds .ds-cfg-main { padding: 20px var(--s6) var(--s8); min-width: 0; }
.ds .ds-rbar { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-card); box-shadow: var(--shadow); margin-bottom: var(--s4); }
.ds .ds-rrow { display: grid; grid-template-columns: 184px 1.1fr 1fr auto; align-items: stretch; }
.ds .ds-rrow > div { padding: var(--s4) var(--s4) 18px; }
.ds .ds-rrow > div + div { border-left: 1px solid var(--border); }
.ds .ds-rrow > .ds-span2 { grid-column: span 2; }
.ds .ds-rrow > .ds-act { display: flex; align-items: center; grid-column: 4; }
.ds .ds-big {
    font-size: var(--fs-big);
    font-weight: var(--w-display);
    line-height: 1;
    margin-top: var(--s3);
    letter-spacing: -.03em;
    display: flex;
    align-items: baseline;
    gap: 10px;
}
.ds .ds-calc { font-size: var(--fs-sm); font-weight: 400; color: var(--text-3); visibility: hidden; letter-spacing: 0; }
.ds .ds-calc.ds-on { visibility: visible; }
.ds .ds-ht { font-size: var(--fs-h2); line-height: 24px; font-weight: 600; color: var(--warn); }
.ds .ds-ht-text { margin-top: 10px; color: var(--text-2); font-size: var(--fs-sm); line-height: var(--lh-sm); }
.ds .ds-ht.ds-ht-next { margin-top: var(--s3); font-size: var(--fs-base); line-height: var(--lh-base); }
.ds .ds-sug {
    margin-top: 10px;
    display: flex;
    align-items: center;
    gap: var(--s3);
    border: 1px solid var(--border);
    background: var(--surface-2);
    border-radius: 8px;
    padding: 9px 10px 10px;
}
.ds .ds-sug > div { flex: 1; min-width: 0; }
.ds .ds-sug b { color: var(--accent); font-weight: 600; white-space: nowrap; }
.ds .ds-sug .ds-muted { display: block; font-size: var(--fs-sm); line-height: var(--lh-sm); margin-top: 2px; }
.ds .ds-calm { margin: 0; color: var(--text-2); font-size: var(--fs-xs); white-space: nowrap; }
.ds .ds-calm b { color: var(--ok); font-weight: 600; font-size: var(--fs-base); }
/* the slim bar: a zero-height sticky dock, so it overlays the table instead of
   pushing it; it shows only once the full bar has scrolled out of view */
.ds .ds-rmini-dock { position: sticky; top: 0; height: 0; z-index: 6; }
.ds .ds-rmini {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 48px;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 0 var(--s2) 0 var(--s4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-top: 0;
    border-radius: 0 0 var(--r-card) var(--r-card);
    box-shadow: var(--shadow-bar);
    opacity: 0;
    transform: translateY(-6px);
    pointer-events: none;
    transition: opacity .18s, transform .18s;
}
.ds .ds-rmini.ds-on { opacity: 1; transform: none; pointer-events: auto; }
.ds .ds-rmini-v { font-size: 22px; line-height: 1; font-weight: var(--w-display); letter-spacing: -.02em; margin: 0 var(--s1); font-variant-numeric: tabular-nums; }
.ds .ds-rmini-t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; padding-left: var(--s2); border-left: 1px solid var(--border); line-height: 24px; }
.ds .ds-rmini-t.ds-warn { color: var(--warn); }
.ds .ds-rmini-t.ds-ok { color: var(--ok); }
.ds .ds-rmini-t .ds-calm { font-weight: 400; }
.ds .ds-rfoot { border-top: 1px solid var(--border); padding: var(--s1) var(--s4); }
.ds .ds-chk { padding: 2px 0 var(--s3) 17px; }
.ds .ds-chk table { border-collapse: collapse; font-size: var(--fs-sm); line-height: var(--lh-sm); }
.ds .ds-chk td { padding: 3px 0; color: var(--text-2); font-variant-numeric: tabular-nums lining-nums; }
.ds .ds-chk td + td { text-align: right; padding-left: var(--s12); min-width: 96px; color: var(--text); }
.ds .ds-chk tr.ds-sum td { border-top: 1px solid var(--border-strong); font-weight: 600; padding-top: 6px; color: var(--text); }

/* picked sites: fixed column widths as in c5 */
.ds .ds-picks col.ds-c-dom { width: 17%; }
.ds .ds-picks col.ds-c-q { width: 27%; }
.ds .ds-picks col.ds-c-dr, .ds .ds-picks col.ds-c-da { width: 6%; }
.ds .ds-picks col.ds-c-iks { width: 8%; }
.ds .ds-picks col.ds-c-link { width: 10%; }
.ds .ds-picks col.ds-c-anc { width: 12%; }

/* ============ CONFIGURATOR «after»: the sites of a locked order (c5, second screen) ============ */
.ds .ds-status {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 24px;
    padding: 0 10px;
    border-radius: 12px;
    background: var(--accent-soft);
    color: var(--accent);
    font-weight: 500;
    font-size: var(--fs-sm);
    white-space: nowrap;
}
.ds .ds-status::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
/* the bottom line («Пересобрать базу заказа») must clear the «Сообщить» button that
   floats over the lower right corner, or it cannot be clicked at the end of the page */
.ds .ds-body2 { padding: 20px var(--s6) 72px; }
.ds .ds-kpis {
    display: inline-flex;
    flex-direction: column;
    gap: var(--s3);
    padding: var(--s4) var(--s4) 18px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-card);
    box-shadow: var(--shadow);
    margin-bottom: var(--s4);
}
.ds .ds-kpi-row { display: flex; align-items: center; gap: 28px; }
.ds .ds-kpi-v { font-size: var(--fs-kpi); font-weight: var(--w-display); letter-spacing: -.03em; line-height: 1; white-space: nowrap; }
.ds .ds-kpi-v small { font-size: 20px; color: var(--text-3); font-weight: 500; letter-spacing: 0; }
.ds .ds-kpi-warn .ds-ht { font-size: var(--fs-base); line-height: var(--lh-base); }
.ds .ds-kpi-warn .ds-ht-text { margin-top: 2px; }
/* «Сделано» as a bar: a <progress>, so the share needs no inline width */
.ds progress.ds-bar { -webkit-appearance: none; appearance: none; display: block; width: 320px; height: 8px; border: 0; border-radius: 4px; background: var(--surface-3); overflow: hidden; }
.ds progress.ds-bar::-webkit-progress-bar { background: var(--surface-3); border-radius: 4px; }
.ds progress.ds-bar::-webkit-progress-value { background: var(--accent); border-radius: 4px; }
.ds progress.ds-bar::-moz-progress-bar { background: var(--accent); border-radius: 4px; }
.ds .ds-tabs { display: flex; align-items: center; gap: var(--s1); padding: 6px var(--s2) 0 var(--s1); border-bottom: 1px solid var(--border); background: var(--surface); }
.ds .ds-tab {
    border: 0;
    background: none;
    padding: 10px var(--s3) 11px;
    cursor: pointer;
    color: var(--text-2);
    font-weight: 500;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    display: inline-flex;
    gap: var(--s2);
    align-items: center;
    white-space: nowrap;
}
.ds .ds-tab:hover { color: var(--text); }
.ds .ds-tab.ds-on { color: var(--text); border-bottom-color: var(--accent); }
.ds .ds-tab .ds-cnt { font-size: var(--fs-xs); line-height: 18px; color: var(--text-3); background: var(--surface-3); padding: 0 7px; border-radius: 9px; font-weight: 500; font-variant-numeric: tabular-nums; }
.ds .ds-tabs .ds-search { margin-left: auto; width: 420px; margin-bottom: 6px; font-size: var(--fs-sm); }
.ds .ds-tabs .ds-search.ds-off { visibility: hidden; }
.ds .ds-pad { padding: 18px var(--s4) 20px; }
.ds .ds-selbar { padding: 10px var(--s4); border-bottom: 1px solid var(--border); background: var(--surface-2); }
.ds .ds-selbar-acts { display: flex; align-items: center; gap: var(--s2); }
.ds .ds-selbar-acts > b { font-weight: 500; margin-right: var(--s2); }
.ds .ds-selbar .ds-hint { margin-top: 6px; }
/* the table: c5 widths, 10px cell sides, the checkbox column hugs the site */
.ds .ds-after col.ds-c-cb { width: 32px; }
.ds .ds-after col.ds-c-dom { width: 150px; }
.ds .ds-after col.ds-c-q { width: 258px; }
.ds .ds-after col.ds-c-dr, .ds .ds-after col.ds-c-da { width: 46px; }
.ds .ds-after col.ds-c-iks { width: 64px; }
.ds .ds-after col.ds-c-link { width: 84px; }
.ds .ds-after col.ds-c-anc { width: 112px; }
.ds .ds-after col.ds-c-st { width: 200px; }
.ds .ds-after col.ds-c-team { width: 78px; }
.ds .ds-after col.ds-c-when { width: 100px; }
.ds table.ds-after td, .ds table.ds-after th { padding-left: 10px; padding-right: 10px; }
.ds table.ds-after tr > td:first-child, .ds table.ds-after tr > th:first-child { padding-left: var(--s4); }
.ds table.ds-after .ds-cb { padding-right: 0; text-overflow: clip; }
.ds table.ds-after .ds-st { padding-right: 0; }
.ds table.ds-after .ds-cb input { vertical-align: middle; }
.ds .ds-pill { display: inline-block; font-size: var(--fs-xs); line-height: 20px; padding: 0 var(--s2); border-radius: 10px; background: var(--surface-3); color: var(--text-2); font-weight: 500; }
.ds .ds-pill.ds-pill-done { background: var(--ok-soft); color: var(--ok); }
.ds .ds-pill.ds-pill-w { background: var(--warn-soft); color: var(--warn); }
.ds .ds-lnk { color: var(--text-2); text-decoration: none; }
.ds .ds-lnk:hover { color: var(--accent); }
/* row states: ticked / на замене / удалена из отчёта — a tint for the whole row,
   an edge on the left for the two states */
.ds table.ds-tbl tbody tr.ds-r.ds-sel td { background: var(--row-sel); }
.ds table.ds-tbl tbody tr.ds-r.ds-sel:hover td { background: var(--row-sel-hover); }
.ds table.ds-tbl tbody tr.ds-r.ds-repl td { background: var(--row-repl); }
.ds table.ds-tbl tbody tr.ds-r.ds-repl:hover td { background: var(--row-repl-hover); }
.ds table.ds-tbl tbody tr.ds-r.ds-repl td:first-child { box-shadow: inset 3px 0 0 var(--row-repl-edge); }
.ds table.ds-tbl tbody tr.ds-r.ds-gone td { background: var(--row-gone); }
.ds table.ds-tbl tbody tr.ds-r.ds-gone:hover td { background: var(--row-gone-hover); }
.ds table.ds-tbl tbody tr.ds-r.ds-gone td:first-child { box-shadow: inset 3px 0 0 var(--row-gone-edge); }
.ds table.ds-tbl tr.ds-gone td, .ds table.ds-tbl tr.ds-gone .ds-lnk, .ds table.ds-tbl tr.ds-gone .ds-pill { color: var(--text-3); }
.ds table.ds-tbl tr.ds-gone .ds-lnk { text-decoration: line-through; }
.ds .ds-none { display: flex; align-items: center; gap: var(--s3); color: var(--text-2); }
/* a removed link with «Вернуть» next to it, in one cell */
.ds .ds-lk { display: flex; align-items: center; gap: var(--s2); }
.ds .ds-lk .ds-lnk { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.ds .ds-lk .ds-btn { margin: -5px 0; flex: none; }
/* top-up: the spares first (the quickest answer to the team), then new sites */
.ds .ds-spares { display: flex; align-items: center; gap: var(--s4); padding-bottom: var(--s4); margin: 0 0 var(--s4); border-bottom: 1px solid var(--border); }
.ds .ds-spares-t { margin-top: 6px; }
.ds .ds-topup { display: flex; align-items: center; gap: var(--s3); margin-top: var(--s2); }
.ds .ds-topup label { color: var(--text-2); }
.ds .ds-topup .ds-in { width: 88px; }
.ds .ds-topup-err { text-align: left; margin-top: 6px; }
.ds .ds-topup-full { margin: 0; color: var(--text-2); }
/* the sites a top-up will give, then «Отмена» / «Выдать N сайтов» on the right */
.ds .ds-topup-list { margin-top: var(--s4); border: 1px solid var(--border); border-radius: 8px; }
.ds .ds-topup-list .ds-actions { justify-content: flex-end; margin: var(--s3); }
.ds .ds-bottom { display: flex; align-items: center; gap: var(--s4); margin-top: var(--s3); font-size: var(--fs-sm); }
.ds .ds-bottom .ds-right { margin-left: auto; }

/* ============ Spacing utilities ============ */
.ds .ds-list { list-style: disc; padding-left: 20px; margin-bottom: var(--s3); }
.ds .ds-list li { margin-bottom: var(--s1); }
.ds .ds-list li:last-child { margin-bottom: 0; }

.ds .ds-mb2 { margin-bottom: var(--s2); }
.ds .ds-mb3 { margin-bottom: var(--s3); }
.ds .ds-mb4 { margin-bottom: var(--s4); }
.ds .ds-mb6 { margin-bottom: var(--s6); }
.ds .ds-narrow { max-width: 560px; }
.ds .ds-center { justify-content: center; }

/* Return-for-rework panel (2026-09-26): the reason block on the project manager
   and Execution screens, plus the return forms. Amber when it asks for action,
   plain (`ds-ret-calm`) for a form. Placed on legacy CRM pages inside a `.ds` box. */
.ds .ds-ret { background: var(--warn-soft); border: 1px solid var(--warn-line); border-radius: var(--r-card); padding: var(--s3) var(--s4); margin: 0 0 var(--s3); max-width: 760px; color: var(--text); font-size: var(--fs-base); line-height: var(--lh-base); }
.ds .ds-ret.ds-ret-calm { background: var(--surface); border-color: var(--border); }
.ds .ds-ret-h { display: block; font-weight: 600; margin-bottom: var(--s1); }
.ds .ds-ret-t { white-space: pre-wrap; overflow-wrap: anywhere; }
.ds .ds-ret-m { font-size: var(--fs-xs); line-height: var(--lh-xs); color: var(--text-3); }
.ds .ds-ret .ds-hint { margin-bottom: var(--s2); }
.ds .ds-ret .ds-err-msg { text-align: left; margin-top: var(--s1); }
.ds .ds-ret .ds-btn { margin-top: var(--s2); }

/* ============ INVARIANT 2: the [hidden] pairing ============
   Every brick above that sets `display` is overridden here when the element
   carries [hidden]. Without this a brick's display:flex silently beats the
   browser default and a hidden warning becomes a permanently visible one —
   which is exactly the production incident this rule exists to prevent.
   Keep this block LAST so it wins on equal specificity, and never remove it. */
.ds [hidden] { display: none !important; }
