/* app/public/app.css — our additions to the prototype stylesheet. styles.css stays a byte copy of the prototype. */

/* menu items that are not built yet */
.side-link.is-soon{color:var(--muted);opacity:.55;cursor:default}
.side-link.is-soon:hover{background:transparent;color:var(--muted)}
.side-link.is-soon>span:not(.nav-count){white-space:nowrap}                            /* V1: the label never wraps onto two lines */
.nav-soon{color:var(--muted)}
/* V1: in the sidebar the badge is plain small muted text, not a chip - .nav-count's chip width is what breaks the
   longer Russian labels. `.settings-nav .nav-soon` below is unaffected: it has no `.side-link` ancestor to match. */
.side-link .nav-soon{flex:none;font-size:10px;padding:0;border-color:transparent;background:transparent;color:var(--muted)}
@media (min-width:761px) and (max-width:1250px){.side-link .nav-soon{display:none}}    /* V1: no room for label + badge at 190px; the hint moves to the item's title attribute */
.side-link-gap{margin-top:26px}

/* phone: the open menu goes above the page. The prototype stylesheet raises .workspace (z-index 26) over the sidebar (25),
   so a tap on a menu link lands on the page and the page text shows through the menu. The sidebar's shadow still dims the
   page. */
@media (max-width:760px){.mobile-nav-open .sidebar{z-index:27}}
/* The open phone menu (owner, 2026-09-28; src/components/shell/mobile-menu.ts): a tap anywhere beside it - on the page or
   the header - lands on the backdrop, over the page (26, placed after it) and under the menu (27), and closes it; the
   menu scrolls on its own when it is taller than the screen, never handing the scroll on to the page, which is held
   still meanwhile (the class on <html>). The desktop's "Collapse sidebar" has no meaning in a menu that slides in:
   it is gone here, and a sidebar collapsed on a desktop (the cookie is the account's, not the device's) opens as the
   full menu - the prototype's collapsed rules, which know no widths, undone. The menu itself takes the focus when it
   opens (tabindex -1): no ring on it. */
.mobile-nav-backdrop{display:none}
html.mobile-nav-lock,html.mobile-nav-lock body{overflow:hidden}
.sidebar:focus{outline:none}
@media (max-width:760px){
  .mobile-nav-backdrop{display:block;position:fixed;inset:0;z-index:26;background:transparent}
  .sidebar{overflow-y:auto;overscroll-behavior:contain}
  .collapse-button{display:none}
  .sidebar-collapsed .sidebar{width:216px;padding-left:16px;padding-right:16px}
  .sidebar-collapsed .brand{padding:0 8px}
  .sidebar-collapsed nav{margin-top:28px}
  .sidebar-collapsed .side-link{padding:0 12px}
  .sidebar-collapsed .brand>span:last-child,.sidebar-collapsed .side-link>span,.sidebar-collapsed .profile-button>span:not(.avatar),.sidebar-collapsed .profile-button>.icon{display:inline}
  .sidebar-collapsed .demo-note{display:block}
  .sidebar-collapsed .profile-button{justify-content:flex-start}
}

/* The sidebar's bottom (owner, 2026-09-28): the collapse toggle stands on the initials' axis, and neither moves when the
   sidebar collapses. The toggle's icon gets the avatar's 34px box (17px icon, 8.5px each side) and both buttons the same
   4px side padding, so the axis is 16 + 4 + 17 = 37px from the left in the open sidebar; collapsed, both are centred
   in its 74px (12 + 4 + 42 / 2 = 37px). Collapsed, the icon turns round: it now opens the sidebar. */
.profile-button{padding-left:4px;padding-right:4px}
.collapse-button{width:100%;padding-left:4px;padding-right:4px}
.collapse-button>.icon{margin:0 8.5px}
.sidebar-collapsed .collapse-button>.icon{transform:scaleX(-1)}

/* Focus rings (owner, 2026-09-28: "the thick blue frame" around a window's close button and around the tenant list).
   The prototype's ring is 3px of solid accent 3px off every button, link, field and row the keyboard reaches - and a
   browser lights it up after a click too where the focus is moved by the page (a window opening on its first control)
   or where a field is typed in. The windows now take the focus themselves (src/components/Dialog.tsx), and the ring
   left for the keyboard is a thin, softer one; a text field shows its focus by its border and a soft halo instead,
   the tenant list (a bare word in the header) by a thin underline. */
button:focus-visible,a:focus-visible,input:focus-visible,select:focus-visible,tr:focus-visible{outline:2px solid color-mix(in srgb,var(--accent) 55%,transparent);outline-offset:2px}
tr:focus-visible{outline-offset:-2px}
.form-control:focus,.form-select:focus{border-color:var(--accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 14%,transparent)}
.form-control:focus-visible,.form-select:focus-visible{outline:none}
.sd-dialog:focus{outline:none}
.tenant-select:focus{outline:none}
.tenant-select:focus-visible{outline:none;box-shadow:inset 0 -2px 0 color-mix(in srgb,var(--accent) 55%,transparent)}
/* ...and only for the keyboard, whatever the browser guesses (the owner, 2026-10-06: after deleting an account the
   heading «Учётные записи» stood in a blue frame - «в обычном пользовании данный элемент экрана не выделяется»). Where a
   change takes away the button it was made from, the page moves the focus to a heading, a card or a row nearby, and
   Safari - after a window has been open - rings such a focus as a keyboard one (src/components/input-modality.ts).
   While the last input was a mouse, a finger or a pen (<html data-input="pointer">), no focused element is ringed:
   neither by an outline - the one `!important` here outranks every element's own keyboard ring, ids included - nor by
   the shadow rings Tabler draws on its buttons and check boxes instead. A text field keeps its look (its border and
   halo above, or the outline of a field without them): it shows where the typing goes. With no input yet, or after a
   key, every ring is as before. */
html[data-input="pointer"] :focus-visible:not(:read-write){outline:none!important}
html[data-input="pointer"] .btn{--tblr-btn-focus-box-shadow:0 0 0 transparent}
html[data-input="pointer"] .form-check-input:focus{box-shadow:var(--tblr-shadow-input)}
html[data-input="pointer"] .tenant-select:focus-visible{box-shadow:none}
html[data-input="pointer"] .weekdays input:focus-visible+span{outline:none}

/* the service pages link stands where the prototype has its demo note */
.service-note a{color:inherit;text-decoration:none;display:block}
.service-note a:hover strong{color:var(--accent)}
.service-note small{margin-left:0}

/* the header's avatar is a button that opens the profile window (part 5a spec A2), as in the prototype: no padding of
   its own, the avatar's box is the button's */
button.top-avatar{padding:0}

/* freshness is a button now (spec 2026-09-23 A5), not a link to the sync page - kept the same understated look */
.freshness{text-decoration:none}
.freshness:hover{color:var(--ink)}
.freshness.is-warning{color:var(--orange)}
.freshness .icon.spin{animation:sd-spin 1.2s linear infinite}
@keyframes sd-spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.freshness .icon.spin{animation:none}}
/* an executor's and a viewer's badge (part 5b R2): the same look, no button - "sync everything" is not theirs */
.freshness.is-static{cursor:default}
.freshness.is-static:hover{color:var(--muted)}
.freshness.is-static.is-warning:hover{color:var(--orange)}
/* narrow screens (fix wave of part A): the prototype hides the badge at <=760px, which left the owner's ~756px
   window and every phone without it. Here it stays as an icon-only button - the same refresh or warning icon,
   spinning while a sync runs - sized like the header's other icon buttons (`.icon-button`). Its text is gone from
   view but not lost: it names the button (aria-label) and is the first line of its title
   (src/components/shell/Freshness.tsx). Same specificity as the prototype's hiding rule, later in the cascade. */
@media (max-width:760px){
  .freshness{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;gap:0;border-radius:5px;flex-shrink:0}
  .freshness>span{display:none}
  .freshness .icon{width:17px;height:17px}
  .freshness:hover{background:var(--canvas)}
  .freshness.is-static:hover{background:transparent}
  /* the static badge (an executor's, a viewer's) is no button: no aria-label names it, so its text is hidden from view
     only - the pattern of `.visually-hidden` - and a screen reader still reads it (review of part 5b) */
  .freshness.is-static{position:relative}
  .freshness.is-static>span{display:block;position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
  /* while the phone menu is open the prototype pushes the topbar 216px right and its tools already run off the
     screen (a horizontal overflow of its own); the badge sits that out rather than lengthen it */
  .mobile-nav-open .freshness{display:none}
}

/* settings sections are links (the prototype styles buttons) */
.settings-nav a,.settings-nav span[aria-disabled]{padding:12px;color:var(--muted);text-align:left;display:flex;align-items:center;justify-content:space-between;border-radius:6px;font-size:13px;text-decoration:none}
.settings-nav a:hover{color:var(--ink)}
.settings-nav a.active{color:var(--accent);background:var(--accent-soft)}
.settings-nav span[aria-disabled]{opacity:.55;cursor:default}
.settings-nav .nav-soon{font-size:11px}

/* the report dims while the server recomputes */
.kpi-report{transition:opacity .15s}
.kpi-report[aria-busy="true"]{opacity:.55;pointer-events:none}
@media (prefers-reduced-motion:reduce){.kpi-report{transition:none}}

/* the Attention queue dims the same way while the server recomputes it (spec 2026-09-19 §5); the My tasks
   "choose an employee" prompt (fix F5) shares the same rule instead of a second one, since it is the same card in
   every way that matters here - just without a queue to show yet */
.queue-card,.mytasks-pick{transition:opacity .15s}
.queue-card[aria-busy="true"],.mytasks-pick[aria-busy="true"]{opacity:.55;pointer-events:none}
@media (prefers-reduced-motion:reduce){.queue-card,.mytasks-pick{transition:none}}

/* the Tickets catalog explorer dims the same way while the server recomputes it (spec 2026-09-19-tickets-catalog-design §6) */
.ticket-explorer{transition:opacity .15s}
.ticket-explorer[aria-busy="true"]{opacity:.55;pointer-events:none}
@media (prefers-reduced-motion:reduce){.ticket-explorer{transition:none}}
/* the explorer toolbar's "Excel" link (spec 2026-09-23 C2) is a .btn among the toolbar's 15px icons (styles.css
   .queue-controls .icon); Tabler's own .btn .icon min-width would stretch its icon's box to 20px */
.queue-controls .btn{--tblr-btn-icon-size:15px}

/* the Statistics report card dims the same way while the server recomputes it (spec 2026-09-20-statistics-design §5) */
.statistics-report{transition:opacity .15s}
.statistics-report[aria-busy="true"]{opacity:.55;pointer-events:none}
@media (prefers-reduced-motion:reduce){.statistics-report{transition:none}}

/* the Statistics table's own row/total link icon (spec 2026-09-20-statistics-design §2.6): same size as the KPI
   performance tables' branch-ticket-link icon - styles.css scopes that rule to .performance-table only, and the
   statistics-table is a .generic-table instead. */
.statistics-table .branch-ticket-link .icon{width:16px;height:16px;opacity:1}
/* service-forms spec 2026-10-07 §12.2: under the table, a grouping by a field service forms do not have. The card pads
   none of its own (its heading, controls and cells pad themselves): the cells' inset, its text under theirs (review
   S3-UX-4). */
.stats-group-note{margin:0;padding:12px 20px 16px;font-size:12px}
/* Service-forms spec 2026-10-07 §12.2: a service group's row says «группа» beside its name, a service's row under a filter
   of one service the group it is in - under the name; neither is part of the name the link and the file take. */
.stats-unit-group{display:inline-block;margin-left:8px;padding:0 6px;border-radius:5px;font-size:11px;font-weight:500;line-height:18px;color:var(--accent);background:var(--accent-soft);vertical-align:1px;white-space:nowrap}
.stats-unit-note{display:block;font-size:12px;color:var(--muted);font-weight:400}

/* sortable column headers (spec 2026-09-23 A7, src/components/SortHeader.tsx): the look styles.css gives the KPI
   tables' own (`.performance-table thead th button`, which still applies there, with the same values), now for the
   Statistics, Tickets and Attention tables too - a bare button with the label and the sort icon, the sorted column in
   the accent colour. The icon keeps its size where a long label wraps (Statistics' last column). */
.sort-button{border:0;background:none;color:inherit;font:inherit;padding:0;display:flex;align-items:center;gap:4px}
.sort-button .icon{width:12px;height:12px;opacity:.5;flex-shrink:0}
th[aria-sort] .sort-button{color:var(--accent)}
/* the Attention and Tasks queues on a narrow screen (fix wave of part A; Tasks sorts since part B): at <=760px the
   prototype turns the queue table into cards and hides its header row (`.ticket-table thead{display:none}`), and the
   sort buttons with it - the owner's ~756px window among others. The header comes back as a wrapping row of those
   buttons above the cards, only where it has them (`:has(.sort-button)`): a table with plain headers keeps the
   prototype's look.
   "Age" stays in the row although the prototype hides the Age cells here (the `!important` answers the prototype's
   own `.age-col{display:none!important}`); between 761 and 1550px the prototype hides the whole Age column, header
   included, and that is left as it is. The owner cell's phone position (absolute, then static with a bottom margin)
   is a cell's, taken back for the header. */
@media (max-width:760px){
  .ticket-table thead:has(.sort-button){display:block;border-bottom:1px solid var(--line)}
  .ticket-table thead:has(.sort-button) tr{display:flex;flex-wrap:wrap;align-items:center;gap:8px 18px;padding:12px 16px;border:0}
  .ticket-table thead:has(.sort-button) th{display:block;width:auto!important;padding:0;margin:0;border:0;position:static;background:none}
  .ticket-table thead:has(.sort-button) th.age-col{display:block!important}
  .ticket-table thead:has(.sort-button) th.row-arrow{display:none!important}
}

/* the Tasks screen's "view as" performer selector, in the heading (spec 2026-09-20-my-tasks-design §6), and since
   spec 2026-09-23 B4 the Attention screen's own performer FILTER beside it (`.attention-person`) - the prototype
   heading has no such control on either screen, so nothing already fits it: an inline label instead of the stacked
   .kpi-filter-field, and a field width that fits a person's name. The width is fixed by default: some Pyrus names
   are long, and a field left to size itself on content pulls in its widest name's width, which overflowed the
   viewport on a phone. 320px (min 260px) rather than the screen's own text width (spec 2026-09-23 A3: wide enough
   that a long name is rarely cut) - the Attention field's extra "All performers" entry is no longer than a real
   name, so it needs no width of its own. At phone width `.my-heading`/`.attention-heading` (below) let the field flex
   instead - safe only because of its `min-width:0`. Since spec 2026-09-23 A1 the field is a searchable list
   (.search-select below): the width sits on its `.search-select-control`, the box around the button and its panel. */
.my-person,.attention-person{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--muted)}
.my-person .search-select-control,.attention-person .search-select-control{width:320px;min-width:260px}

/* fix P1: `.page-heading` (styles.css) is `display:flex;justify-content:space-between` with no wrap, so the
   selector used to sit squeezed beside the title, wrapping «Задачи» onto two lines and the subtitle onto four.
   `.my-heading` (this screen's own modifier class) lets the heading wrap instead - folding in the `.my-person`
   phone rule this screen briefly had, which fixed the selector's own width but not the still-unwrapped heading
   around it. `.heading-actions` then takes the freed second row, and within it the selector - the wider of its two
   controls since the KPI report button left the heading (spec 2026-09-23 A8) - grows to fill whatever the date
   leaves free, the field itself included (`min-width:0` is what lets a flex item actually shrink to its own
   ellipsis instead of overflowing). `.attention-heading` (spec 2026-09-23 B4) gives the Attention screen's own
   performer filter the identical treatment, for the identical reason - the same rules, just under the two screens'
   own heading classes, so this stays one definition instead of two copies.
   The wrap itself reaches up to 900px (fix wave of part A): between 761 and 900px the 190px sidebar leaves the
   heading too little room beside the 320px picker, and the subtitle squeezed into three lines - the picker now
   takes the second row there too, at its own width; only a phone stretches it across the row. */
@media(max-width:900px){.my-heading,.attention-heading{flex-wrap:wrap}}
@media(max-width:760px){
  .my-heading .heading-actions,.attention-heading .heading-actions{width:100%;justify-content:space-between}
  .my-heading .my-person,.attention-heading .attention-person{flex:1;min-width:0}
  .my-heading .my-person .search-select-control,.attention-heading .attention-person .search-select-control{width:auto;flex:1;min-width:0}
}

/* spec 2026-09-23 A4: while a dialog is open (the ticket's window, but "any window on top of the page" - every
   <dialog class="sd-dialog"> the app opens with showModal()) the page behind it must not scroll on a phone. styles.css
   bounds .sd-dialog's own height (max-height:90vh; the ticket's window and the People card's side panel set their own
   below) and gives THAT element `overflow:auto` - .dialog-body has no height or overflow of its own - so .sd-dialog,
   not .dialog-body, is what actually scrolls, and so is where `overscroll-behavior` belongs: it stops a scroll gesture
   that reaches the dialog's own top/bottom edge from chaining to whatever is behind it. `html:has(dialog[open])` belts
   that by removing the document's own scroll entirely while any dialog is open, so there is nothing left behind it to
   chain into. `:has()` ships in Safari >= 15.4 and Chrome >= 105; both engines have shipped `overscroll-behavior` for
   longer than that. No `touch-action` or JS: showModal() already makes the rest of the document non-interactive (no
   click or tap reaches it), which is most of why CSS alone should be enough on iOS too - worth confirming on a real
   phone after deploy, same as this list's other device-only items. */
html:has(dialog[open]){overflow:hidden}
.sd-dialog{overscroll-behavior:contain}
/* the People card's side panel (src/components/people/EmployeeDrawer.tsx; the ticket card's too until 2026-10-06) is
   as tall as the VISIBLE viewport (fix wave of part A): on iOS `100vh` is the height with the address bar hidden, so
   while the bar shows the panel's bottom - the end of the card - sits below the screen and cannot be scrolled to. `dvh`
   follows the bar; the `vh` lines stay as the fallback for a browser without it (the prototype's own values,
   styles.css). */
.detail-panel{height:100vh;height:100dvh;max-height:100vh;max-height:100dvh}
/* The heading of a window that names a thing - the ticket's window, the People card: the number (or name) and its chips
   on the left, wrapping onto a second line rather than pushing the buttons off; on the right the close button and, in
   the ticket's window, «Открыть в Pyrus» (the owner, 2026-09-30; src/components/ticket/PyrusLink.tsx), in sight without
   scrolling. Its short caption, «Pyrus», only where the full one would not fit beside the number (a phone). */
.dialog-heading-tools{display:flex;align-items:center;gap:8px;flex:none}
.detail-panel .dialog-heading,.ticket-dialog .dialog-heading{gap:12px}
.detail-panel .dialog-heading h2,.ticket-dialog .dialog-heading h2{display:flex;flex-wrap:wrap;align-items:center;gap:6px;min-width:0;margin:0}
/* The ticket's chips by the number are its queue row's (2026-10-08), and a chip is one line (styles.css `.status-chip`):
   the pause's - «Пауза · Ожидание пользователя · 12 дн.» - is wider than the number's room beside the buttons on a phone
   and ran under «Pyrus» and the close button (review PR70-SLA-1); on the ticket's own page (`.ticket-heading-title`,
   below) it ran under «Открыть в Pyrus» from 761 to about 800 px, where the buttons stand beside the number. In both
   headings the row of chips may be narrower than its widest chip, and a chip wraps inside itself; where it fits - a
   wide window - it is one line, as before. */
.ticket-dialog .dialog-heading .status-chips,.ticket-heading-title .status-chips{min-width:0}
.ticket-dialog .dialog-heading .status-chip,.ticket-heading-title .status-chip{white-space:normal}
.pyrus-link{white-space:nowrap}
.pyrus-link-short{display:none}
@media (max-width:560px){
  .detail-panel .dialog-heading{padding:14px 16px}
  .ticket-dialog .pyrus-link-full{display:none}
  .ticket-dialog .pyrus-link-short{display:inline}
}

/* The ticket's window (the owner, 2026-10-06: «один попап»; src/components/ticket/TicketDialog.tsx): the prototype's
   modal (`.sd-dialog`, its `catalog-ticket-detail`) centred across the screen at 720px - room for the key facts two to
   a row. Not centred top to bottom, as the prototype's short windows are: it stands a little below the top (8% of the
   height, 64px at most) and grows downwards, so a section opened under the pointer unfolds where it is instead of the
   whole window jumping up by half of what it gained; at most the visible viewport less that and 24px below. The window
   itself still scrolls (styles.css `overflow:auto`), so the focus it takes on opening (Dialog.tsx) lets the keyboard
   scroll it; its heading stays on top while the body passes under it (`sticky`, on the window's own surface, above the
   bar's marker and the ribbon). Its scrollbar's room is kept from the start (`scrollbar-gutter`, review of 2026-10-06):
   with a scrollbar that takes room (Windows; macOS set to show them always) a section whose opening first makes the
   window scroll would otherwise narrow the content by the bar, wrap it again and move the line just clicked from under
   the pointer - a second click then opened the next section instead of folding this one. On a phone (600px and less)
   it is the whole screen: no frame, no corners, as tall as the visible viewport (`dvh`, as the side panel above, `vh`
   the fallback); a tap on its empty part below the content is the window's, not the backdrop's (Dialog.tsx
   `isBackdropClick`). */
.sd-dialog.ticket-dialog{width:min(720px,calc(100vw - 32px));max-width:720px;margin:min(8vh,64px) auto 24px;max-height:calc(100vh - min(8vh,64px) - 24px);max-height:calc(100dvh - min(8vh,64px) - 24px);scrollbar-gutter:stable}
.ticket-dialog .dialog-heading{position:sticky;top:0;z-index:2;background:var(--surface);padding:16px 24px}
.ticket-dialog .dialog-body{padding:20px 24px 24px}
@media (max-width:600px){
  .sd-dialog.ticket-dialog{width:100%;max-width:100%;height:100vh;height:100dvh;max-height:100vh;max-height:100dvh;margin:0;border:0;border-radius:0}
  .ticket-dialog .dialog-heading{padding:12px 12px 12px 16px}
  .ticket-dialog .dialog-body{padding:16px 16px 28px}
}

/* A link to a ticket on the screens that name tickets (the notifications journal, the letters, a digest's check, an SLA
   matrix's tickets) while its window is being asked of the server (src/components/ticket/open-in-pyrus.tsx
   `TicketAnchor`, review of 2026-10-06): the pointer says so. */
a[aria-busy="true"]{cursor:progress}

/* The ticket's own page (src/app/[tenant]/tickets/[ticket]/page.tsx), where links from outside lead: the window's view
   in a centred column of the window's width - on a phone the page's own gutters. The heading: the number and the status
   chip, then its two buttons side by side, never one under the other beside the number. On a phone the prototype
   shrinks heading buttons to a bare icon; here the two keep their captions on a row of their own under the number -
   the whole of «Открыть в Pyrus» in sight. */
.ticket-page{max-width:720px;margin:0 auto}
.ticket-heading-title{display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px;min-width:0}
.ticket-heading-title h1{margin:0}
.ticket-heading-title .status-chip{font-size:12px;padding:3px 8px}
.ticket-heading .heading-actions{flex:none;gap:8px}
.ticket-page-card .card-body{padding:20px 24px 24px}
@media (max-width:760px){
  .ticket-heading{flex-wrap:wrap;gap:12px}
  .ticket-heading .heading-actions{width:100%;gap:8px}
  .ticket-heading .heading-actions .btn{font-size:var(--tblr-btn-font-size);width:auto;padding:var(--tblr-btn-padding-y) var(--tblr-btn-padding-x);gap:7px}
  .ticket-heading .heading-actions .btn .icon{margin:0 calc(var(--tblr-btn-padding-x)/ 2) 0 calc(var(--tblr-btn-padding-x)/ -4)}
}
@media (max-width:600px){.ticket-page-card .card-body{padding:16px 16px 20px}}

/* The compact view itself (src/components/ticket/TicketView.tsx), the same in the window and on the page. Main
   information first: the subject - a long one wraps, even a long word or an address - the service line, then the four
   key facts two to a row, one row only on a very narrow phone (under 360px). A fact never widens the view: a long name,
   a long Pyrus status, a long first-response text wrap inside their column (the prototype's `.person` is one line, set
   for the queue's owner column). On a phone the facts' text is a size smaller and the performer has no avatar - as the
   prototype's own queue drops it there (`.owner-col .avatar`) - so a long surname («Константинопольский») fits its
   column whole instead of breaking in the middle. */
.ticket-view-title{font-size:20px;line-height:1.35;font-weight:600;letter-spacing:-.3px;margin:0 0 6px;overflow-wrap:anywhere}
.ticket-view-meta{margin:0;font-size:13px;overflow-wrap:anywhere}
/* service-forms spec 2026-10-07 §13: a service form's ticket names its form under the subject, small */
.ticket-form-mark{margin:-2px 0 4px;font-size:12px;overflow-wrap:anywhere}
.ticket-view .unanswered-flag{font-size:12px;margin-top:8px}
.ticket-facts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px 20px;margin:18px 0 0}
.ticket-facts>div{min-width:0}
.ticket-facts dt{font-size:12px;font-weight:400;color:var(--muted);margin:0 0 4px}
.ticket-facts dd{margin:0;font-size:14px;overflow-wrap:anywhere}
.ticket-facts dd small{display:block;font-size:12px;color:var(--muted);margin-top:2px}
.ticket-facts .person{font-size:14px;white-space:normal}
.ticket-facts .person>span:last-child{min-width:0}
.ticket-facts .avatar-xs{flex:none}
.ticket-facts .unassigned{font-size:14px}
@media (max-width:359px){.ticket-facts{grid-template-columns:minmax(0,1fr)}}
@media (max-width:600px){
  .ticket-view-title{font-size:18px}
  .ticket-facts{column-gap:16px}
  .ticket-facts dd,.ticket-facts .person,.ticket-facts .unassigned{font-size:13px}
  .ticket-facts .person .avatar{display:none}
}
/* The SLA bar and its time text in one row on the canvas tone (the prototype's `.detail-sla` box, smaller), the time
   going under the bar only where the row has no room for both (a phone, a long "overdue by …"). */
.ticket-sla{display:flex;align-items:center;gap:14px;margin:18px 0 0;padding:12px 16px;background:var(--canvas);border:1px solid var(--line);border-radius:8px}
.ticket-sla-label{flex:none;font-size:12px;color:var(--muted)}
.ticket-sla .sla-cell{flex:1;min-width:0;max-width:none;display:flex;flex-wrap:wrap;align-items:center;gap:4px 14px}
.ticket-sla .sla-track{flex:1 1 160px;height:6px;margin:0}
.ticket-sla .sla-time{flex:none;font-size:13px;white-space:normal}
/* The folded sections, closed by default: one line each - the name in the accent colour after a turning arrow, the
   look of Settings → Synchronization's folded block (`.sync-params`) - with a line between them; the description's
   first line follows its name, muted and cut to one line, until it is opened. The body is indented under the name. */
.ticket-folds{margin-top:20px;border-bottom:1px solid var(--line)}
.ticket-fold{border-top:1px solid var(--line)}
.ticket-fold>summary{display:flex;align-items:baseline;gap:10px;padding:12px 0;cursor:pointer;list-style:none;min-width:0}
.ticket-fold>summary::-webkit-details-marker{display:none}
.ticket-fold>summary::before{content:"";flex:none;width:7px;height:7px;border-right:1.5px solid var(--muted);border-bottom:1.5px solid var(--muted);transform:rotate(-45deg);align-self:center;margin:0 2px;transition:transform .15s}
.ticket-fold[open]>summary::before{transform:rotate(45deg)}
.ticket-fold>summary strong{flex:none;font-size:14px;font-weight:500;color:var(--accent)}
.ticket-fold-hint{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;color:var(--muted)}
.ticket-fold[open]>summary .ticket-fold-hint{display:none}
.ticket-fold-body{padding:0 0 18px 21px;font-size:13px}
.ticket-fold-body>:first-child{margin-top:0}
.ticket-fold-body>:last-child{margin-bottom:0}
.ticket-fold-body h3{font-size:12px;font-weight:600;color:var(--muted);margin:18px 0 8px}
.ticket-fold-body .ticket-facts{margin:2px 0 0}
.ticket-how p{font-size:12px;color:var(--muted);margin:0 0 6px}
.ticket-description{white-space:pre-wrap;margin:0;overflow-wrap:anywhere}
.ticket-view .route-chain{flex-wrap:wrap;row-gap:6px;margin-top:0;font-size:11px}
.ticket-view .route-chain span{white-space:normal;overflow-wrap:anywhere}
.ticket-view .route-chain em{font-size:10px}
.ticket-view .lifetime-labels{gap:12px}
.ticket-view .timeline{margin:4px 0 0}
.ticket-view .timeline li{padding-bottom:14px}
.ticket-view .timeline li:last-child{padding-bottom:2px}

/* the extra Attention button, "No answer" (docs/07 §7; fourth of five since 2026-09-29, before "On pause"). The prototype's own attention row has four
   buttons and styles.css pins `.attention-metrics` to four columns; five is the prototype's DEFAULT
   (`.status-metrics`), which the prototype's five-button My tasks row (`.task-metrics`) used - so this only takes the
   four-column override back off.
   A media query adds no specificity, so every width is settled by source order inside this file: the plain rule
   beats styles.css everywhere, and the blocks below beat the plain rule at their own widths. Scoping the plain rule
   to `min-width:761px` instead would leave the widths between 760 and 761 (reachable by browser zoom) to the
   prototype's four-column rule. */
.status-metrics.attention-metrics{grid-template-columns:repeat(5,minmax(0,1fr))}
/* 600-760px: the five buttons stay in ONE row (owner's decision 2026-09-21 - his browser window is about 756px,
   half of a 1512px laptop screen, and the last button alone on a row of its own reads as a different thing). The
   prototype's phone rules make the cards too large for five columns there, so this band tightens them: less
   padding, a smaller label and value, and the icon dropped - the prototype drops it itself between 761 and 1050px,
   for the same lack of room. The labels then take two lines and the cards keep equal heights, because grid items
   stretch and `.metric-bottom` is pushed down by its own `margin-top:auto` (styles.css). */
@media(min-width:600px) and (max-width:760px){
  .status-metrics.attention-metrics{gap:8px}
  .status-metrics.attention-metrics .metric-card,
  .status-metrics.attention-metrics .metric-card:last-child{padding:11px 10px 12px;gap:8px}
  .status-metrics.attention-metrics .metric-label{font-size:11px;line-height:1.35}
  .status-metrics.attention-metrics .metric-label .icon{display:none}
  .status-metrics.attention-metrics .metric-bottom strong{font-size:24px}
}
/* below 600px the prototype's phone layout stands: two, two, and the odd fifth card across the full width, as the
   prototype's five-button My tasks row had it - styles.css gives every `.status-metrics .metric-card:last-child`
   that `grid-column:1/-1` and only the four-button attention row cancels it. */
@media(max-width:599px){
  .status-metrics.attention-metrics{grid-template-columns:repeat(2,minmax(0,1fr))}
  .status-metrics.attention-metrics .metric-card:last-child{grid-column:1/-1}
}

/* the Tasks screen's four buttons (spec 2026-09-23 B1: "To do (mine)", "To do (my group)", "On pause"; "Discussions"
   since the owner's word of 2026-10-03 - the prototype's row had five): the same cards, four to a row on a wide
   screen. The default five columns would leave an empty slot, and the prototype's phone layout (two, then the last card
   across the full width as a strip of its own) would set "Discussions" apart as a different kind of thing. */
.status-metrics.task-metrics{grid-template-columns:repeat(4,minmax(0,1fr))}
/* <=760px: styles.css makes the LAST card of any row that full-width strip (`.metric-card:last-child`: across the
   grid, a row inside, less padding, a smaller value, no icon; `.task-metrics` already undoes the row). Here it stays
   one card of four, exactly like its neighbours. */
@media(max-width:760px){
  .status-metrics.task-metrics .metric-card:last-child{grid-column:auto;padding:15px 13px}
  .status-metrics.task-metrics .metric-card:last-child .metric-bottom strong{font-size:32px}
  .status-metrics.task-metrics .metric-card:last-child .metric-label .icon{display:block}
}
/* 600-760px: the four stay in ONE row, as Attention's five do there (owner's decision 2026-09-21, a browser window of
   about 756px), with the tightening Attention's cards get in that band - less padding, a smaller label and value, no
   icon. The labels take two lines and the cards keep equal heights (grid items stretch; `.metric-bottom` sits at the
   bottom by its own `margin-top:auto`). */
@media(min-width:600px) and (max-width:760px){
  .status-metrics.task-metrics{gap:8px}
  .status-metrics.task-metrics .metric-card,
  .status-metrics.task-metrics .metric-card:last-child{padding:11px 10px 12px;gap:8px}
  .status-metrics.task-metrics .metric-label{font-size:12px;line-height:1.35}
  .status-metrics.task-metrics .metric-label .icon,
  .status-metrics.task-metrics .metric-card:last-child .metric-label .icon{display:none}
  .status-metrics.task-metrics .metric-bottom strong,
  .status-metrics.task-metrics .metric-card:last-child .metric-bottom strong{font-size:24px}
}
/* below 600px: two and two, the prototype's own phone grid for its four-button Attention row (styles.css
   `.attention-metrics`), in the prototype's phone cards - about 165px each at 375px, room for the icon and a label on
   two lines. */
@media(max-width:599px){
  .status-metrics.task-metrics{grid-template-columns:repeat(2,minmax(0,1fr))}
}

/* the discussion line of a "Discussions" row (2026-10-03): in place of the button's name under the title, who last
   mentioned the performer and when they last wrote - the row's `.personal-status` size and rhythm, its two parts side
   by side, the second going under the first where the row is narrow (a phone), a long name wrapping inside its part.
   The mention, a question put to the performer, reads in the ink colour; "you wrote" stays muted. */
.personal-status.discussion{display:flex;flex-wrap:wrap;column-gap:14px;row-gap:2px}
.personal-status.discussion .mentioned{color:var(--ink);font-weight:500}

/* "No response" gets a colour of its own (owner's decision 2026-09-21). The prototype paints it the same red as
   "breached" (`.status-chip.noresponse`, `.sla-track.noresponse span`, `.sla-time.noresponse`) and left the two
   states indistinguishable on the screen. Violet is far enough from the red, the orange and the accent blue to
   read at a glance. Both tones are picked to sit beside the existing red/orange pairs in contrast - light:
   ~5.4:1 on white, where the red is ~4.6:1; dark: ~6.6:1 on the surface, where the red is ~6.1:1 - and the dark
   theme is declared the way styles.css declares it, on `[data-bs-theme=dark]`. */
:root{--violet:#7d4fc7;--violet-soft:#f3eeff}
[data-bs-theme=dark]{--violet:#b79cf5;--violet-soft:#332a4d}
.status-chip.noresponse{color:var(--violet);background:var(--violet-soft)}
.sla-track.noresponse span{background:var(--violet)}
.sla-time.noresponse{color:var(--violet)}
.metric-card.noresponse strong,.metric-card.noresponse .icon{color:var(--violet)}
.metric-card.noresponse .metric-underline{background:var(--violet);opacity:.6}

/* the "message without a reply" flag: under the ticket title in a queue row, and under the heading on the card
   (docs/07 §7). Same size and rhythm as the row's own `.personal-status` line, in the colour the product uses for
   "somebody is waiting". */
.unanswered-flag{font-size:11px;color:var(--orange);margin:7px 0 0;font-weight:500}

/* Every status chip of a queue row (2026-09-28, src/components/ticket/StatusChip.tsx `StatusChips`): side by side in
   their fixed order, each in its state's own colour (styles.css; "No response" violet above, "Paused" the plain grey
   chip), wrapping onto a second line where the SLA column is narrow - on a phone too. The unanswered message of a
   closed row is a chip now, in the orange its flag has always had; a chip never shares a row with "At risk" (that one
   is always open, this one always closed). The row's "Due" line under the bar keeps the prototype's `.pyrus-due` look
   but may wrap: "Срок: на паузе, осталось 5 ч" is longer than a date. */
.status-chips{display:flex;flex-wrap:wrap;gap:4px}
.status-chip.unanswered{color:var(--orange);background:var(--orange-soft)}
.sla-due{white-space:normal}

/* the "Technical service" tag at the end of the ticket card's service line (spec 2026-09-23 C4): the catalog's own
   status badge (`.neutral-badge`, styles.css), set off from the text before it; `middle` keeps its 11px box from
   pushing the line taller than the text around it. Fix wave 2026-09-23 C item 4: when the card has neither a service
   nor a priority the tag is the only thing on the line (TicketView.tsx then adds `.is-solo`) and gets no left
   margin - a plain sibling selector cannot key off "the text before it is empty", since that text is a bare string,
   never an element, so the tag is `.muted`'s only child ELEMENT (and would match `:first-child`/`:only-child`) in
   both cases alike; `.is-solo` is the one bit the component adds to tell them apart. */
.technical-mark{margin-left:8px;vertical-align:middle;white-space:nowrap}
.technical-mark.is-solo{margin-left:0}

/* the ticket's current Pyrus status in a queue row's meta line, after the service name (owner's decision
   2026-09-21): a small muted label, quieter than the service and never translated - it is Pyrus's own word.
   `.service-name` (styles.css) is the neighbour whose muted tone it matches; unlike it, this one is never cut with
   an ellipsis - «Pending User Response» half-shown would be worse than not shown at all.
   `.ticket-meta` is a single-line flex row in the prototype, so a fourth item would widen the table's own
   min-content instead of giving way. Not a narrow viewport band, as first measured (760-1050 px): `styles.css`
   caps the table's own first column at `max-width:400px` (`.ticket-table td:first-child`), so once a long service
   name and a long status together outgrow that fixed width, the meta line needs two lines AT ANY WINDOW WIDTH.
   Letting it wrap puts the status on its own second line there instead of forcing a horizontal PAGE scroll
   (measured: 898 px of content in an 865 px window), and changes nothing at any width where it already fits. */
.ticket-meta{flex-wrap:wrap}
.pyrus-status{color:var(--muted);white-space:nowrap}

/* the tenant a queue row, a "since yesterday" block or a ticket card belongs to, on the screens of every tenant (spec
   2026-09-23 D5; QueueTable.tsx, DigestCard.tsx, TicketDialog.tsx): the catalog's own badge (`.neutral-badge`,
   styles.css) in the accent's tone and the size of the row's priority chip - a label, not one more status. `middle`
   keeps it on the line of the heading text beside it. */
.tenant-tag{color:var(--accent);background:var(--accent-soft);border-color:transparent;padding:1px 6px;font-size:10px;font-weight:500;line-height:1.5;white-space:nowrap;vertical-align:middle}

/* the searchable filter lists (spec 2026-09-23 A1, src/components/SearchSelect.tsx): the filters of KPI,
   Statistics and Tickets, and the Tasks performer picker.
   The closed field is the same `.form-select` as the native select it replaced, only a <button> now - and a button
   centres its text and wraps it, where a select starts it at the left and cuts it off - so just those two are taken
   back. Its caption is a <label> now, where it was a <span>: it gets the spacing styles.css gives
   `.kpi-filter-field>span`. A field with a help text (`help`) puts the caption and the prototype's help icon in one
   row, `.search-select-caption`, which takes that spacing over. */
.search-select-control{position:relative;min-width:0}
.search-select-toggle{text-align:start}
.search-select-value{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.search-select-toggle[aria-expanded="true"]{border-color:var(--accent)}
.kpi-filter-field.search-select>label{display:block;margin-bottom:6px}
.search-select-caption{display:flex;align-items:center;gap:6px;margin-bottom:6px}
/* its help opens to the right of the icon, not centred on it: a caption starts at its field's left edge, which on a
   phone is the card's own, so a centred text would run off the screen */
.search-select-caption .help-tooltip>span{left:-10px;transform:none;max-width:calc(100vw - 48px)}
/* The open panel: right under the field, at least as wide as the field, at most 28rem or the viewport less a 16px
   gutter on each side - the page's own phone gutter, PANEL_GUTTER in src/lib/search-select.ts, which also moves the
   panel left when it would cross the right gutter - so it never widens the page. The entries wrap rather than widen
   it. Above the cards and the sticky table columns (z-index 1-2), under the sidebar (25) and the help tooltips (30).
   The prototype's own tokens throughout, so the dark theme needs only a deeper shadow. */
.search-select-panel{position:absolute;top:calc(100% + 4px);left:0;z-index:20;min-width:100%;width:max-content;max-width:max(100%,min(28rem,calc(100vw - 32px)));background:var(--surface);color:var(--ink);border:1px solid var(--line);border-radius:8px;box-shadow:0 10px 30px #1828401f;font-size:13px;line-height:1.4;overflow:hidden}
[data-bs-theme=dark] .search-select-panel{box-shadow:0 10px 30px #0009}
.search-select-search{display:flex;align-items:center;gap:6px;padding:8px 10px;border-bottom:1px solid var(--line)}
.search-select-search:focus-within{border-bottom-color:var(--accent)}
.search-select-search .icon{width:15px;height:15px;color:var(--muted)}
.search-select-search input{flex:1;width:0;min-width:0;border:0;outline:none;padding:2px 0;background:transparent;color:var(--ink);font-size:13px}
.search-select-search input::placeholder{color:var(--muted);opacity:1}
/* iOS zooms the page into a text box whose text is smaller than 16px; on a touch screen the search box is that size */
@media (pointer:coarse){.search-select-search input{font-size:16px}}
/* position:relative makes the list its entries' offsetParent: the component scrolls a highlighted entry into view by
   its offsetTop, which must count from the list, not from the panel above it */
.search-select-list{position:relative;list-style:none;margin:0;padding:4px;max-height:min(300px,45vh);overflow-y:auto}
.search-select-list>li{padding:7px 10px;border-radius:5px;cursor:pointer;overflow-wrap:anywhere}
.search-select-list>li.active{background:var(--accent-soft)}
.search-select-list>li[aria-selected="true"]{color:var(--accent);font-weight:600}
/* "All …" stays on top whatever is typed; a thin line keeps it apart from the matches below it */
.search-select-list>li.search-select-all{position:relative;margin-bottom:9px}
.search-select-list>li.search-select-all::after{content:'';position:absolute;left:10px;right:10px;bottom:-5px;border-top:1px solid var(--line)}
.search-select-empty{margin:0;padding:2px 14px 10px;color:var(--muted)}
.search-select-empty:empty{padding:0}

/* The Tickets period row (spec 2026-09-23 C1): KPI's own row (`.report-controls.kpi-period-row` in styles.css) with
   KPI's own control (src/components/PeriodControl.tsx), the dates it resolved to under it, and "Include tickets" on
   the right with its caption level with the control's. It replaces the prototype's `.ticket-period-filters` grid of
   two date fields and that list. Two rules of the Tickets card would make the control differ from KPI's, so they are
   taken back here: `.ticket-filter-card .form-select` (13px, full width) over the year select, and styles.css scoping
   its phone rules for the segments to `.kpi-filter-card`. The one difference left is the year list's width: KPI's
   102px, or its widest entry - "All years" / «Все годы», which 102px would cut. Below 760px each part takes the whole
   row, as KPI's tools do. */
.ticket-period-row{align-items:flex-start}
.ticket-period-row .period-dates{margin-top:10px}
.ticket-period-row .ticket-basis{flex:0 1 320px;min-width:220px}
.ticket-filter-card .kpi-period-tools .kpi-report-year{width:auto;min-width:102px;padding-right:36px;font-size:.875rem}
@media(max-width:760px){.ticket-period-row>*,.ticket-period-row .ticket-basis{flex:1 1 100%;min-width:0}.ticket-filter-card .kpi-period-tools .kpi-report-year{width:100%;min-width:0}}
@media(max-width:700px){.ticket-filter-card .period-segments{gap:0}.ticket-filter-card .period-segments button{padding:7px 12px}}
@media(max-width:380px){.ticket-filter-card .period-segments button{padding:7px 9px}}
/* The Tickets filters (the owner, 2026-09-30): no "Additional filters" disclosure and no "People" / "Data" groups any
   more - every filter in one grid under the period row, as many columns as fit (five at 1100 px with the sidebar, two on
   a phone), so the whole set is in sight in a few rows. A caption that wraps (the longer Russian ones) keeps its field
   level with its neighbours': the fields sit on the row's bottom line. */
.ticket-filter-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(148px,1fr));gap:12px 14px;align-items:end;padding:18px 22px}
@media(max-width:760px){.ticket-filter-grid{grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:12px;padding:16px}}
/* narrow fields, so less room kept around the value: the chevron closer to the edge, the text starting nearer it */
.ticket-filter-card .ticket-filter-grid .search-select-toggle{padding-left:10px;padding-right:28px;background-position:right 8px center}

/* The saved variants of Tickets (the owner, 2026-10-14; src/components/tickets/TicketVariants.tsx): a button of the page
   heading, left of «Колонки» and like it - a bookmark and «Варианты», or, a variant on, the bookmark filled and its name,
   cut with an ellipsis (the full name is the button's name and tooltip) at 220px, or less on a narrow desktop (18vw), so
   the pair never pushes the page sideways; the pair is never wrapped under itself - the heading's text gives way. Below
   760px the heading's buttons are their icons alone (styles.css `.heading-actions .btn`), the filled bookmark still saying
   a variant is on.
   The window is rendered where the button is - inside `.page-heading`, whose prototype rule `.page-heading p` (grey,
   14px, no margin) would win over a bare class: every rule of the window's own texts is scoped by
   `.ticket-variants-dialog` (review of 2026-10-14). The list: each row the name - up to two lines, the «по умолчанию»
   mark beside it or under it - the one on highlighted, its star and «Удалить» 36px targets; then «Сохранить текущие
   фильтры». */
.tickets-heading .heading-actions{flex:none;gap:8px}
.ticket-variants-label{display:inline-block;max-width:min(220px,18vw);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}
.ticket-variants-button.is-on .icon,.ticket-variant-apply .icon.is-filled{color:var(--accent)}
.ticket-variants-button .icon.is-filled,.ticket-variant-apply .icon.is-filled,.ticket-variant-default[aria-pressed="true"] .icon{fill:currentColor}
.ticket-variants-body{transition:opacity .15s}
.ticket-variants-body[aria-busy="true"]{opacity:.7}
.ticket-variants-dialog .ticket-variant-empty{margin:0 0 12px;font-size:14px;color:var(--muted)}
.ticket-variant-list{list-style:none;margin:0 0 10px;padding:0;border:1px solid var(--line);border-radius:8px}
.ticket-variant-item{display:flex;align-items:center;gap:2px;min-width:0;padding:3px 4px 3px 3px;border-top:1px solid var(--line)}
.ticket-variant-item:first-child{border-top:0}
.ticket-variant-item.is-current{background:var(--accent-soft)}
.ticket-variant-apply{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:8px;padding:7px 8px;border:0;border-radius:6px;background:transparent;color:var(--ink);text-align:left}
.ticket-variant-apply .icon{flex:none;width:16px;height:16px}
.ticket-variant-text{display:flex;flex-wrap:wrap;align-items:center;gap:2px 8px;min-width:0}
.ticket-variant-title{min-width:0;overflow:hidden;white-space:normal;overflow-wrap:anywhere;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2}
.ticket-variant-item.is-current .ticket-variant-apply{color:var(--accent);font-weight:600}
.ticket-variant-mark{flex:none}
.ticket-variant-item .icon-button{flex:none;width:36px;height:36px}
.ticket-variant-default[aria-pressed="true"]{color:var(--accent)}
.ticket-variants-dialog .ticket-variant-status{margin:0 0 10px;font-size:12px;color:var(--muted)}
.ticket-variants-dialog .ticket-variant-status:empty{display:none}
.ticket-variants-dialog .ticket-variant-status.is-ok{color:var(--green)}
.ticket-variants-dialog .ticket-variant-status.is-error{color:var(--red)}
.ticket-variant-form{border-top:1px solid var(--line);padding-top:14px}
.ticket-variants-dialog .ticket-variant-save-title{margin:0 0 4px;font-size:14px}
.ticket-variants-dialog .ticket-variant-intro{margin:0 0 10px;font-size:12px;color:var(--muted)}
.ticket-variant-save-row{display:flex;gap:8px;margin-bottom:6px}
.ticket-variant-save-row .form-control{flex:1 1 auto;min-width:0}
.ticket-variant-save-row .btn{flex:none}
.ticket-variants-dialog .ticket-variant-error{margin:0 0 6px;font-size:12px;color:var(--red)}
.ticket-variant-form .form-check{display:flex;align-items:flex-start;gap:8px;margin-top:10px}

/* The People screen (spec 2026-09-23 D2, D3, D4; src/components/people/*). The prototype's peoplePage() is one card
   with a plain table; here the merge suggestions come first, then the employee table with its search and two filters,
   and the employee card is the ticket card's side panel. Built from the prototype's own parts - card, card-heading,
   queue-toolbar/search-field, generic-table, person/avatar, neutral-badge, status-chip - and its tokens, so the dark
   theme needs nothing of its own. A card dims while its change or its navigation is on the way, like the queues. */
.people-suggestions,.people-directory{margin-bottom:22px}
.people-suggestions,.people-directory,.people-card-panel .dialog-body>div{transition:opacity .15s}
.people-suggestions[aria-busy="true"],.people-directory[aria-busy="true"],.people-card-panel .dialog-body>div[aria-busy="true"]{opacity:.55;pointer-events:none}
@media (prefers-reduced-motion:reduce){.people-suggestions,.people-directory,.people-card-panel .dialog-body>div{transition:none}}
.people-suggestions h2 .number-badge,.people-directory h2 .number-badge{margin-left:8px}
/* the outcome of the last change: a line of its own, no room at all while there is none */
.people-status{margin:0 20px 12px;font-size:13px}
.people-status:empty{display:none}
.people-status.is-ok{color:var(--green)}
.people-status.is-error{color:var(--red)}
.people-card-panel .people-status{margin:0 0 12px}

/* a suggestion: its reason on top, then the two employees side by side and the two buttons */
.people-suggestions-none{margin:0;padding:0 20px 20px;color:var(--muted);font-size:13px}
.people-suggestion-list{list-style:none;margin:0;padding:0}
.people-suggestion{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:10px 16px;padding:14px 20px;border-top:1px solid var(--line)}
.people-reason{grid-column:1/-1;justify-self:start}
.people-reason.is-similar{color:var(--orange);background:var(--orange-soft);border-color:transparent}
.people-pair{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
.people-side{border:1px solid var(--line);border-radius:8px;padding:10px 12px;min-width:0}
.people-side-name{display:block;font-weight:600;font-size:14px;margin-bottom:6px;overflow-wrap:anywhere}
.people-side-accounts{list-style:none;margin:0;padding:0;display:grid;gap:6px;font-size:12px}
.people-side-accounts>li{display:flex;flex-wrap:wrap;align-items:center;gap:4px 8px;color:var(--muted)}
.people-side-accounts>li.is-evidence{color:var(--ink)}
.people-account-name{font-weight:500}
.people-email{overflow-wrap:anywhere}
.people-suggestion-actions{align-self:center}
.people-suggestions-more{padding:12px 20px;border-top:1px solid var(--line)}

/* the table's search and filters: the catalog's toolbar, with "Tenant", "State", "Team", "Pyrus roles" and "Only
   merged" on the right - the three of 2026-09-25 narrower than "Tenant", their values being short */
.people-toolbar .search-field{flex:1 1 260px;max-width:450px}
.people-toolbar .search-field input{font-size:14px;padding:2px 0;min-height:24px;box-shadow:none}
.people-filters{display:flex;align-items:center;flex-wrap:wrap;gap:10px 18px}
.people-tenant,.people-filter{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--muted)}
.people-tenant .search-select-control{width:190px}
.people-filter .search-select-control{width:150px}
.people-merged{display:flex;align-items:center;gap:7px;margin:0;padding:0;min-height:0;font-size:13px;white-space:nowrap}
.people-merged .form-check-input{float:none;margin:0}
.people-table .person{white-space:normal}
.people-table .person small{display:block}
.people-open{font-size:13px;font-weight:500;text-align:start}
/* a cell's tenants, teams and e-mails never break inside: a narrow window scrolls the table sideways (.table-responsive)
   rather than squeezing an address into a column a few letters wide, or "UAE · Ashon" onto two lines */
.people-badges{display:inline-flex;gap:4px}
.people-badges .neutral-badge{white-space:nowrap}
.people-email-list{list-style:none;margin:0;padding:0;font-size:12px;color:var(--muted);white-space:nowrap}
.people-tickets{font-variant-numeric:tabular-nums}

/* the employee card: accounts, then e-mails, then the field to add one */
.people-accounts,.people-emails{list-style:none;margin:0;padding:0}
.people-accounts>li,.people-emails>li{padding:12px 0;border-bottom:1px solid var(--line)}
.people-account-head,.people-email-head{display:flex;align-items:center;flex-wrap:wrap;gap:6px 8px}
.people-account-head strong{font-weight:600;overflow-wrap:anywhere}
.people-detach,.people-remove{margin-left:auto}
.people-account-facts{display:flex;flex-wrap:wrap;gap:4px 14px;margin-top:6px;font-size:12px;color:var(--muted)}
.people-account-facts>*{overflow-wrap:anywhere}
/* "Merge with…": the searchable list of the other employees and its button, set apart in a box of its own - it joins
   two employees for good, whatever the program suggested */
.people-merge-with{margin-top:16px;padding:12px 14px;border:1px solid var(--line);border-radius:8px}
.people-merge-with-row{display:flex;align-items:flex-end;flex-wrap:wrap;gap:8px}
.people-merge-with-field{flex:1 1 240px;min-width:0}
.people-merge-with-field>label{display:block;margin-bottom:6px;font-size:13px;font-weight:500}
.people-merge-with>p{font-size:12px;margin:8px 0 0}
.people-email-head .people-email{font-weight:500}
.people-email-tenants{display:flex;flex-wrap:wrap;gap:4px;margin-top:6px}
.people-no-tenant{display:inline-flex;align-items:center;gap:5px;font-size:12px;color:var(--orange)}
.people-no-tenant .icon{width:14px;height:14px;flex-shrink:0}
.people-domains-note{font-size:12px;margin:10px 0 0}
.people-email-form{margin-top:18px}
.people-email-row{display:flex;gap:8px}
.people-email-row .form-control{flex:1;min-width:0}
/* iOS zooms the page into a text box whose text is smaller than 16px */
@media (pointer:coarse){.people-email-row .form-control{font-size:16px}}

/* <=760px: the prototype's phone gutters (15px), the two employees of a suggestion one under the other, the buttons
   under them; the search, each filter's list and "Only merged" each take a row of their own */
@media(max-width:760px){
  .people-suggestion{grid-template-columns:minmax(0,1fr);padding:14px 15px}
  .people-pair{grid-template-columns:minmax(0,1fr)}
  .people-suggestions-none,.people-suggestions-more{padding-left:15px;padding-right:15px}
  .people-status{margin-left:15px;margin-right:15px}
  .people-toolbar .search-field{flex-basis:100%;max-width:none}
  .people-filters{width:100%}
  .people-tenant,.people-filter{flex:1 1 100%;min-width:0}
  .people-tenant .search-select-control,.people-filter .search-select-control{width:auto;flex:1;min-width:0}
  .people-filters .search-select>label{flex:0 0 76px}
}

/* The team editor in People (spec 2026-09-24 T6-T9; the owner's 2026-09-30: "Teams" - a list and one team open beside
   it, no tenant choice of its own): the prototype's `.page-tabs`, `.team-totals` and `.workload-row` (styles.css), plus
   what the prototype's read-only cards never needed - the list of teams (a column of buttons, the one open marked as
   the menu marks its item), the team's editing controls (a remove button per member, "Add member", "Rename" in place,
   "Delete") and the employee card's "Pyrus roles" and "Team" rows. Tokens only, so both themes follow. */
.people-intro{margin:0 0 18px;font-size:13px;color:var(--muted)}
.people-teams{transition:opacity .15s}
.people-teams[aria-busy="true"],.people-team[aria-busy="true"]{opacity:.55;pointer-events:none}
@media (prefers-reduced-motion:reduce){.people-teams{transition:none}}
/* "Create team": its refusal above the fields, the form dimmed while the server answers */
.people-create-team .people-status{margin:0 0 12px}
.people-create-team form[aria-busy="true"]{opacity:.55;pointer-events:none}
.people-create-team .form-hint{margin:10px 0 0}
/* the list and the team open: side by side from 901px, stacked below - the list first */
.people-teams-layout{display:grid;grid-template-columns:minmax(260px,320px) minmax(0,1fr);gap:20px;align-items:start;margin-bottom:22px}
.people-teams-layout.is-empty{grid-template-columns:minmax(0,1fr)}
.people-teams-layout.is-empty .people-team-detail{display:none}
.people-teams-list .card-heading{flex-wrap:wrap;align-items:flex-start}
.people-teams-list .card-heading>div{min-width:0}
.people-teams-list .card-heading h2{display:flex;align-items:center}
.people-teams-list .card-heading .btn{white-space:nowrap}
/* the heading takes the focus when the last team is deleted: marked only for a keyboard (never after a mouse or a
   finger, the `data-input` rule at the top) */
#people-teams-heading:focus{outline:none}
#people-teams-heading:focus-visible{outline:2px solid color-mix(in srgb,var(--accent) 55%,transparent);outline-offset:2px}
.people-teams-empty{margin:0 20px 20px;padding:18px 20px;border:1px dashed var(--line);border-radius:8px;color:var(--muted);font-size:13px}
.people-teams-search{padding:0 20px 12px}
.people-teams-search .search-field{max-width:none}
.people-teams-search .search-field input{font-size:14px;padding:2px 0;min-height:24px;box-shadow:none}
.people-teams-none{margin:0;padding:4px 20px 20px;font-size:13px}
.people-teams-items{list-style:none;margin:0;padding:0 10px 10px}
.people-teams-item{display:grid;gap:2px;width:100%;text-align:start;border:0;border-radius:6px;background:transparent;color:var(--ink);padding:9px 10px;margin:1px 0}
.people-teams-item:hover{background:var(--canvas)}
.people-teams-item.active{background:var(--accent-soft)}
.people-teams-item.active .people-teams-item-name{color:var(--accent)}
.people-teams-item:focus-visible{outline:2px solid color-mix(in srgb,var(--accent) 55%,transparent);outline-offset:-2px}
.people-teams-item-name{font-weight:600;overflow-wrap:anywhere}
.people-teams-item-facts{display:flex;flex-wrap:wrap;gap:0 12px;font-size:12px;color:var(--muted)}
.people-teams-item-facts .is-breached{color:var(--red)}
@media (min-width:901px){.people-teams-items{max-height:calc(100vh - 290px);min-height:120px;overflow-y:auto}}
@media (max-width:900px){.people-teams-layout{grid-template-columns:minmax(0,1fr)}}
/* the team open */
.people-team-detail{min-width:0;scroll-margin-top:80px}
.people-team:focus{outline:none}
.people-team:focus-visible{outline:2px solid color-mix(in srgb,var(--accent) 55%,transparent);outline-offset:2px}
.people-team .card-heading{flex-wrap:wrap}
.people-team-title{display:flex;align-items:center;flex-wrap:wrap;gap:4px 8px;min-width:0}
.people-team-title h2{margin:0;overflow-wrap:anywhere}
/* "N people" beside a long name: the name wraps, the badge keeps its size and its one line */
.people-team-title .number-badge{white-space:nowrap;flex-shrink:0;margin-left:0}
.people-team-actions{display:flex;flex-wrap:wrap;gap:8px;margin-left:auto}
.people-team .people-status{margin:0 0 12px}
.team-totals strong.is-breached{color:var(--red)}
.people-team-members{font-size:13px;font-weight:600;margin:0 0 12px;padding-top:16px;border-top:1px solid var(--line)}
.people-team-none{margin:0 0 16px}
/* a member: the name may wrap next to its "Inactive" chip; the bar takes what is left, then the count and the remove button */
.people-team .workload-row{margin-bottom:14px}
.people-team .workload-row .person{flex:0 1 48%;min-width:0;white-space:normal}
.people-team .workload-row .person .avatar{flex-shrink:0}
.people-member-name{display:flex;flex-wrap:wrap;align-items:center;gap:2px 6px;min-width:0}
.people-member-name .people-open{font-size:13px;font-weight:500;text-align:start;overflow-wrap:anywhere}
.people-team .workload-track{min-width:24px}
.people-team .workload-row>strong{min-width:20px;text-align:right;font-variant-numeric:tabular-nums}
.people-team-remove{width:24px;height:24px;flex-shrink:0}
.people-team-remove .icon{width:13px;height:13px}
.people-team-add{display:flex;align-items:flex-end;gap:8px;margin:0 0 18px}
.people-team-add-field{flex:1 1 auto;min-width:0}
.people-team-add-field>label{display:block;margin-bottom:6px;font-size:12px;font-weight:500}
/* spec 2026-09-24 T13: an open count split by tenant ("Ashon 5 · FertiStream 2"), each number a link into its tenant's
   catalog - on a line of its own: under the total's label, and under a member's name, so the bars stay one column */
.people-team-tenants{display:block;font-size:12px;font-weight:400;color:var(--muted);white-space:normal;margin-top:3px}
.people-team-tenants>span{white-space:nowrap}
.people-member-name .people-team-tenants{flex-basis:100%;margin-top:0;font-size:11px}
/* "Rename": the field and "Save" / "Cancel" beside it, on a row of their own when the heading is narrow */
.people-team-rename{display:flex;align-items:center;flex-wrap:wrap;gap:6px;flex:1;min-width:0}
.people-team-rename .form-control{flex:1 1 220px;min-width:0}
@media (pointer:coarse){.people-team-rename .form-control{font-size:16px}}
@media(max-width:760px){.people-teams-search{padding:0 15px 12px}.people-teams-items{padding:0 5px 8px}.people-teams-empty{margin:0 15px 15px}.people-teams-none{padding:4px 15px 15px}.team-totals{gap:28px}}
/* the employee card: an account's "Pyrus roles" and "Team", a caption and its value on one row */
.people-account-row{display:flex;align-items:center;flex-wrap:wrap;gap:4px 10px;margin-top:8px;font-size:12px}
.people-account-label,.people-account-row>label{flex:0 0 90px;color:var(--muted)}
.people-account-roles{flex:1;min-width:0;overflow-wrap:anywhere}
.people-account-team .search-select-control{flex:1 1 200px;min-width:0;max-width:280px}

/* Settings → Tenants: one tenant's mail domains (spec 2026-09-23 D4; src/components/settings/MailDomains.tsx) - a
   column of its own in the tenants table: chips with a remove button, a field to add one, and the domains its own
   people's e-mails suggest, as clickable chips with their counts. Built from the People card's own e-mail list and
   `.neutral-badge`, so nothing here needs a color of its own besides the status line's ok/error (`.people-status`). */
.tenant-domains{min-width:220px}
.tenant-alias{min-width:200px}
.tenant-domains-hint{font-size:11px;margin:0 0 8px}
.tenant-domains-status{margin:0 0 8px;font-size:12px}
.tenant-domains-status:empty{display:none}
.tenant-domains-status.is-ok{color:var(--green)}
.tenant-domains-status.is-error{color:var(--red)}
.tenant-domain-chips{list-style:none;margin:0 0 10px;padding:0;display:flex;flex-wrap:wrap;gap:6px}
.tenant-domain-chip{display:inline-flex;align-items:center;gap:4px;color:var(--muted);background:var(--canvas);border:1px solid var(--line);border-radius:4px;padding:3px 4px 3px 8px;font-size:11px}
.tenant-domain-remove{width:18px;height:18px;display:inline-flex;align-items:center;justify-content:center;border:0;border-radius:4px;color:var(--muted);background:transparent;flex-shrink:0}
.tenant-domain-remove:hover{color:var(--ink);background:var(--surface)}
.tenant-domain-remove .icon{width:11px;height:11px}
.tenant-domain-add .form-label{font-size:11px;margin-bottom:4px}
.tenant-domain-add-row{display:flex;gap:6px}
.tenant-domain-add-row .form-control{flex:1;min-width:0;font-size:12px;min-height:30px;padding:4px 8px}
.tenant-domain-add-row .btn{font-size:12px;min-height:30px;padding:4px 9px}
@media (pointer:coarse){.tenant-domain-add-row .form-control{font-size:16px}}
.tenant-domain-suggestions{margin-top:10px;font-size:11px}
.tenant-domain-suggestions>.muted{display:block;margin-bottom:5px}
.tenant-domain-suggestion-list{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:6px}
.tenant-domain-suggestion{border:1px dashed var(--line);border-radius:4px;background:transparent;color:var(--accent);padding:3px 7px;font-size:11px}

/* fix wave of part D, m3: text present for touch and screen-reader users (a "one-tenant screen" menu item's reason,
   src/components/shell/Sidebar.tsx) but not painted - unlike the visible "soon" badge, four such hints in a row
   would be clutter. The standard clip-to-nothing technique, not display:none/visibility:hidden, which assistive
   tech skips too. */
.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.tenant-domain-suggestion:hover{background:var(--accent-soft)}

/* The sign-in's pages (part 5a spec A2, A3; src/components/sign-in/*): the prototype's `.auth-page` and `.auth-card`
   (styles.css), without its demo parts. What they lacked: the links under the card are links here, not buttons; a
   form's refusal sits over its fields (Tabler's alert); the first run groups its fields in two sets; the password's
   rule is a hint under its field. */
.auth-links a{font-size:12px}
.auth-card .alert{margin-bottom:20px;font-size:13px}
.auth-card .form-hint{display:block;margin-top:6px;font-size:11px;font-weight:400}
.auth-fieldset{border:0;margin:0 0 6px;padding:0;min-width:0}
.auth-fieldset>legend{float:none;width:auto;font-size:13px;font-weight:600;margin:0 0 14px;padding:0}
/* the language switch sits in the card's top right corner (owner, 2026-09-28), level with the card's padding and above
   its title (30px of padding and the title's 18px margin leave 48px, 41px on a phone), in the look of the header's
   switch with a light frame of its own - on the card it is no longer beside the header's other tools */
.auth-frame{position:relative}
.auth-tools{position:absolute;top:14px;right:14px;z-index:1}
.auth-tools .language-button{display:inline-flex;align-items:center;justify-content:center;min-width:36px;height:28px;padding:0 9px;border:1px solid var(--line);border-radius:6px;color:var(--muted);background:var(--surface)}
.auth-tools .language-button:hover{color:var(--ink);background:var(--canvas)}
@media (max-width:760px){.auth-tools{top:10px;right:10px}}
/* iOS zooms the page into a text box whose text is smaller than 16px */
@media (pointer:coarse){.auth-card .form-control,.auth-card .form-select{font-size:16px}}

/* the red button of a question that takes something away ("Block", "Reject" - the prototype's `btn btn-danger`,
   which styles.css leaves as a plain button): Tabler's own look is overridden there by the prototype's `.btn` */
.btn-danger{background:var(--red);color:#fff;border-color:var(--red)}
.btn-danger:hover{background:var(--red);color:#fff;border-color:var(--red);filter:brightness(.92)}


/* The Access section (part 5a spec A4; src/components/access/*): the prototype's accessPage() card with its
   generic-table and `.account-actions` (styles.css), plus what it did not have - the requests awaiting approval, the
   search over the table, the section's status line and the windows' lines. Tokens only, so both themes follow. */
.access-status{margin:0 0 16px;font-size:13px}
.access-status:empty{display:none}
.access-status.is-ok{color:var(--green)}
.access-status.is-error{color:var(--red)}
.access-dialog .access-status{margin:0 0 12px}
.access-dialog form[aria-busy="true"]{opacity:.55;pointer-events:none}
.access-dialog .form-hint{margin:10px 0 0}
.access-dialog-email{margin:-6px 0 16px;font-size:13px}
.access-requests,.access-accounts{margin-bottom:22px;transition:opacity .15s}
.access-accounts[aria-busy="true"]{opacity:.55;pointer-events:none}
@media (prefers-reduced-motion:reduce){.access-requests,.access-accounts{transition:none}}
.access-requests h2 .number-badge,.access-accounts h2 .number-badge{margin-left:8px}
/* People's "Access" tab (the owner, 2026-09-30): "Change history" and "Create account" in the accounts card's heading -
   under the heading on a phone */
.access-accounts .card-heading{flex-wrap:wrap}
.access-heading-actions{display:flex;flex-wrap:wrap;gap:8px;margin-left:auto}
.access-heading-actions .btn{white-space:nowrap}
/* the heading takes the focus after an approval, a rejection or a deletion of an account the table shows no row of:
   marked only for a keyboard, as the team editor's headings - never after a mouse or a finger (the `data-input` rule at
   the top; the owner's screenshot of 2026-10-06 was Safari ringing it after "Delete") */
#access-accounts-title:focus{outline:none}
#access-accounts-title:focus-visible{outline:2px solid color-mix(in srgb,var(--accent) 55%,transparent);outline-offset:2px}
.access-request-list{list-style:none;margin:0;padding:0}
.access-request-list>li{display:grid;gap:8px;padding:14px 20px;border-top:1px solid var(--line)}
.access-request-who strong{font-weight:600;overflow-wrap:anywhere}
.access-request-who small{display:block;font-size:12px;color:var(--muted);overflow-wrap:anywhere}
.access-request-facts{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:4px 14px;margin:0;font-size:13px}
.access-request-facts dt{font-weight:500;color:var(--muted)}
.access-request-facts dd{margin:0;white-space:pre-wrap;overflow-wrap:anywhere}
.access-request-list small.muted{font-size:12px}
.access-toolbar .search-field{flex:1 1 260px;max-width:450px}
.access-toolbar .search-field input{font-size:14px;padding:2px 0;min-height:24px;box-shadow:none}
.access-table td>.muted{font-size:12px}
.access-table .account-actions{white-space:nowrap}
.access-link .form-control{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}
.access-history pre{max-height:260px;overflow:auto}
/* the roles of an account (part 5b spec R5): the administrator's mark, then one list per tenant - the tenant's name
   beside its list; a warning line (an executor without an employee) in the orange of a warning, as on the page's line */
.access-status.is-warn{color:var(--orange)}
.access-grant{border:0;margin:0;padding:0;min-width:0}
.access-grant>legend,.form-grid .access-grant>legend{float:none;width:auto;padding:0;margin:0 0 6px;font-size:inherit}
.access-grant .form-check{margin:4px 0 10px}
.access-grant .form-check-label .muted{font-size:12px}
.access-tenant-roles{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:8px 14px;align-items:center}
.access-tenant-role{display:contents}
.access-tenant-role>span{font-size:13px;overflow-wrap:anywhere}
.access-grant .access-warning{color:var(--orange)}
/* "Create account" (the owner, 2026-09-24): who it is for - an employee of People or typed by hand - as the period's
   segmented switch, its two halves the dialog's width; a warning under a field (an employee without an e-mail) orange */
.access-create-mode{margin:0 0 16px}
.access-create-mode button{flex:1 1 0;min-width:0}
.access-dialog .form-hint.access-warning{color:var(--orange)}
/* "Edit" of an account without an employee: «Присылать сюда» of its sign-in address (the owner, 2026-09-29: the
   letters are opt-in), below the form - the address and the switch on one line, as a People card's mail rows */
.access-mail{margin-top:18px;padding-top:14px;border-top:1px solid var(--line)}
.access-mail>h3{margin:0 0 8px}
.access-mail-row{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:6px 14px}
.access-mail-row .people-email{font-size:13px;min-width:0}
.access-dialog .access-mail .form-hint{margin:6px 0 0}
.access-dialog .access-mail .access-status{margin:8px 0 0}
.access-dialog .access-mail-note{margin:16px 0 0}
@media(max-width:760px){
  .access-request-list>li{padding-left:15px;padding-right:15px}
  .access-request-facts{grid-template-columns:minmax(0,1fr)}
  .access-toolbar .search-field{flex-basis:100%;max-width:none}
  .access-tenant-roles{grid-template-columns:minmax(0,1fr);gap:4px}
  .access-tenant-role>select{margin-bottom:6px}
}

/* Settings → Calculation rules and Synchronization (part 5c spec S2, S5; src/components/settings/RulesForm.tsx,
   SyncSettingsForm.tsx): the prototype's `.number-setting` row gets the one-line hint under its label that its
   `.setting-toggle` row has, and a line for a refused value or a warning. On a phone the field goes under the label. */
.number-setting>label{flex:1;min-width:0;margin:0;cursor:default}
.number-setting>label strong{font-weight:500;font-size:14px;display:block}
.number-setting>label small{color:var(--muted);font-size:12px;display:block;margin-top:5px}
.number-setting>label small.setting-error{color:var(--red)}
.number-setting>label small.setting-warning{color:var(--orange);display:flex;gap:5px;align-items:flex-start}
.number-setting>label small.setting-warning .icon{width:14px;height:14px;flex-shrink:0;margin-top:1px}
.number-setting .input-group{align-self:center}
.settings-form>.alert{margin-bottom:10px}
@media(max-width:560px){.number-setting{flex-direction:column;align-items:stretch;gap:10px}.number-setting .input-group{width:100%;align-self:stretch}.number-setting>label strong{font-size:13px}.number-setting>label small{font-size:11px}}
/* A button of Settings busy with a change says so without being disabled - a disabled one would drop the keyboard
   focus (review of part 5c): the click is ignored, the look is a disabled one's. */
.sync-buttons [aria-disabled="true"],.calendar-holidays [aria-disabled="true"],.sla-matrix [aria-disabled="true"],
.notify-test [aria-disabled="true"],.notify-recipients [aria-disabled="true"]{opacity:.55;cursor:progress}
.notify-mail-retry[aria-busy="false"] [aria-disabled="true"]{cursor:default}
/* Synchronization: the queue buttons' status line (like the Tenants page's), and each form's status and run log. */
.sync-buttons-hint{font-size:12px;margin:8px 0 0}
.sync-buttons-status{margin:8px 0 0;font-size:12px}
.sync-buttons-status:empty{display:none}
.sync-buttons-status.is-ok{color:var(--green)}
.sync-buttons-status.is-error{color:var(--red)}
/* Synchronization, restructured (the owner's item 10 of 2026-09-30; src/app/[tenant]/settings/sync/page.tsx): each
   form's state first - a tile with its result chip and a few facts, problems only when there are some - then the
   tenant's buttons, then its settings folded under «Параметры» with the saved values in one line. Under the cards one
   run log: the filters, a compact table, the pager; on a phone each run folds into two lines. */
.sync-forms{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:12px;margin-bottom:16px}
.sync-form-state{border:1px solid var(--line);border-radius:6px;padding:12px 14px;min-width:0}
.sync-form-title{display:flex;gap:10px;align-items:flex-start;justify-content:space-between;margin-bottom:6px}
.sync-form-title>h3{font-size:14px;font-weight:600;margin:0;min-width:0;overflow-wrap:anywhere}
.sync-state{display:inline-flex;align-items:center;font-size:12px;line-height:1.5;font-weight:500;padding:1px 7px;border-radius:4px;white-space:nowrap;background:var(--canvas);color:var(--muted)}
.sync-state.is-ok{color:var(--green);background:var(--green-soft)}
.sync-state.is-error{color:var(--red);background:var(--red-soft)}
.sync-state.is-running{color:var(--accent);background:var(--accent-soft)}
.sync-facts{display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:6px 14px;margin:0;font-size:12px}
.sync-facts>div{min-width:0}
.sync-facts dt{font-weight:400;color:var(--muted)}
.sync-facts dd{margin:0;color:var(--ink);font-weight:500;overflow-wrap:anywhere}
.sync-facts>.is-bad dd{color:var(--red)}
.sync-facts .sync-fact-note{display:block;font-weight:400;color:var(--muted)}
.sync-last-error{margin:8px 0 0;font-size:12px;color:var(--red);overflow-wrap:anywhere}
.sync-last-error strong{font-weight:500}
.sync-buttons .help-tooltip>span{left:auto;right:-8px;transform:none;max-width:calc(100vw - 48px)}
.sync-params{margin-top:16px;border-top:1px solid var(--line);padding-top:12px}
.sync-params>summary{cursor:pointer;display:flex;flex-wrap:wrap;gap:4px 10px;align-items:baseline;list-style:none}
.sync-params>summary::-webkit-details-marker{display:none}
.sync-params>summary::before{content:"";width:7px;height:7px;border-right:1.5px solid var(--muted);border-bottom:1.5px solid var(--muted);transform:rotate(-45deg);align-self:center;margin-right:2px;transition:transform .15s}
.sync-params[open]>summary::before{transform:rotate(45deg)}
.sync-params>summary strong{font-weight:500;color:var(--accent)}
.sync-params>summary span{font-size:12px}
.sync-params>summary:focus-visible{outline:2px solid color-mix(in srgb,var(--accent) 55%,transparent);outline-offset:2px;border-radius:4px}
.sync-params>.settings-form{margin-top:8px}
.sync-log-filters{display:flex;flex-wrap:wrap;gap:10px 18px;align-items:center;padding:14px 18px;border-bottom:1px solid var(--line)}
.sync-log-scope{width:min(100%,340px)}
.sync-log-errors{margin:0;font-size:13px}
.sync-log-none{margin:0;padding:16px 18px}
.sync-runs{margin:0}
.sync-runs td{padding:9px 12px;white-space:nowrap;font-size:12px}
.sync-runs tr.has-error>td{border-bottom:0}
.sync-runs td.sync-run-error{padding-top:0;white-space:normal;color:var(--red);font-size:11px;overflow-wrap:anywhere}
@media(max-width:760px){
  .sync-runs thead{display:none}
  .sync-runs,.sync-runs tbody{display:block}
  .sync-runs tr{display:flex;flex-wrap:wrap;gap:2px 10px;padding:10px 16px;border-bottom:1px solid var(--line)}
  .sync-runs td{border:0;padding:0;white-space:normal}
  .sync-runs td.sync-run-form{order:1;flex:1 1 0;font-weight:500;font-size:13px;min-width:0;overflow-wrap:anywhere}
  .sync-runs td.sync-run-result{order:2;min-width:0;flex:0 1 auto}
  .sync-runs tr.has-error{border-bottom:0;padding-bottom:2px}
  .sync-runs tr.sync-run-error-row{padding-top:0}
  .sync-runs tr::before{content:"";order:3;flex-basis:100%;height:0}
  .sync-runs td.sync-run-started,.sync-runs td.sync-run-kind,.sync-runs td.sync-run-tickets,.sync-runs td.sync-run-duration{order:4;color:var(--muted)}
  .sync-log-footer{flex-wrap:wrap;gap:8px}
}
@media(max-width:420px){.sync-facts{grid-template-columns:1fr 1fr}}
/* "Change history" (part 5c spec S1; src/components/settings/SettingsHistory.tsx): the prototype's dialog of
   `.history-entry` blocks, wider for the JSON, with the section filter on top and the changes as short lines. */
.sd-dialog.settings-history{width:min(720px,calc(100vw - 32px));max-width:720px}
.settings-history-filter{display:flex;align-items:center;gap:10px;margin-bottom:18px;font-size:12px;color:var(--muted)}
.settings-history-filter .form-select{width:auto;min-width:200px}
.history-entry>strong{font-weight:500}
.history-entry>p{margin:4px 0 0;overflow-wrap:anywhere}
.history-changes{margin:8px 0 0;padding-left:18px;font-size:12px}
.history-changes li{overflow-wrap:anywhere}
.history-changes code{font-size:11px}
.history-entry details{margin-top:8px;font-size:12px}
.history-entry summary{cursor:pointer;color:var(--accent)}
.history-entry pre{max-height:320px;overflow:auto;margin:8px 0 0}   /* Tabler's own dark block, as in the prototype */

/* Settings → Calendars (part 5c spec S3; src/components/settings/CalendarSettingsForm.tsx, CalendarHolidays.tsx): the
   prototype's `.calendar-controls`, `.time-pair`, `.weekdays` and `.calendar-mini`, with a line for a refused value, the
   weekday names above the grid and the leading blanks of its first week, holidays marked red (a day off stays muted,
   today the prototype's accent), and the holidays of a year with a remove button and a field pair to add one. */
.setting-lead{font-size:12px;margin:0 0 18px}
.calendar-settings .calendar-controls>label{display:block;margin:0}
.calendar-settings .calendar-controls>label>.form-select{margin-top:7px}
.calendar-hours>span{display:block;font-size:12px;color:var(--muted)}
.calendar-hours .time-pair{margin-top:7px}
.calendar-settings small.setting-error,.rule-editor .setting-error{display:block;color:var(--red);font-size:12px;margin-top:5px}
.calendar-weekdays{border:0;margin:22px 0 0;padding:0;min-width:0}
.calendar-weekdays>legend{float:none;width:auto;font-size:12px;color:var(--muted);margin:0 0 7px;padding:0}
.calendar-weekdays .weekdays{margin:0;flex-wrap:wrap}
.calendar-weekdays .weekdays label{position:relative;margin:0}
.calendar-holidays{margin-top:28px}
.calendar-weekday-names{margin-bottom:5px}
.calendar-weekday-names>span{height:auto;font-size:10px;color:var(--muted)}
.calendar-days .holiday{background:var(--red-soft);color:var(--red);font-weight:600}
.calendar-days .today.holiday{background:var(--accent);color:#fff}
.calendar-legend{display:flex;flex-wrap:wrap;gap:6px 14px;margin-top:12px;font-size:11px;color:var(--muted)}
.calendar-legend i{display:inline-block;width:10px;height:10px;border-radius:3px;margin-right:5px;vertical-align:-1px}
.calendar-legend .is-holiday{background:var(--red-soft);border:1px solid var(--red)}
.calendar-legend .is-off{background:transparent;border:1px solid var(--muted)}
.calendar-legend .is-today{background:var(--accent)}
.calendar-year{flex-wrap:wrap;row-gap:8px}
.calendar-year h3{font-size:14px;margin:0;white-space:nowrap}
.calendar-year>div{margin-left:auto;display:flex;gap:5px;flex-wrap:wrap;justify-content:flex-end}
.calendar-year .btn-icon,.calendar-mini .btn-icon{width:30px;min-height:30px}
.calendar-status,.sla-status{margin:0 0 8px;font-size:12px}
.calendar-status:empty,.sla-status:empty{display:none}
.calendar-status.is-ok,.sla-status.is-ok{color:var(--green)}
.calendar-status.is-error,.sla-status.is-error{color:var(--red)}
.holiday-list{list-style:none;margin:0;padding:0}
.holiday-list>li>span:first-child{overflow-wrap:anywhere}
.holiday-when{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
.holiday-when .icon-button{width:28px;height:28px}
.holiday-when .icon-button .icon{width:16px;height:16px}
.holiday-add{display:grid;grid-template-columns:170px minmax(0,1fr) auto;gap:10px;align-items:end;margin-top:16px}
.holiday-add label{font-size:12px;color:var(--muted);margin:0}
.holiday-add label .form-control{margin-top:5px}
.holiday-add .holiday-add-error{grid-column:1 / -1;margin:0;color:var(--red);font-size:12px}
.sd-dialog.holiday-copy{width:min(720px,calc(100vw - 32px));max-width:720px}
.holiday-copy-list{list-style:none;padding:0;margin:14px 0 0;display:grid;gap:10px}
.holiday-copy-list>li{display:grid;grid-template-columns:auto 160px minmax(0,1fr);gap:6px 10px;align-items:center;padding-bottom:10px;border-bottom:1px solid var(--line)}
.holiday-copy-list>li>small{grid-column:2 / -1;font-size:11px}
.holiday-copy-list .form-check{margin:0;padding:0;min-height:0;display:flex;gap:6px;align-items:center}
.holiday-copy-list .form-check .form-check-input{float:none;margin:0}
@media(max-width:560px){
  .holiday-add{grid-template-columns:minmax(0,1fr)}
  .holiday-copy-list>li{grid-template-columns:auto minmax(0,1fr)}
  .holiday-copy-list>li>input[type=text],.holiday-copy-list>li>small{grid-column:1 / -1}
}

/* Settings → SLA matrices (part 5c spec S4; src/components/settings/SlaMatrix.tsx, SlaRuleEditor.tsx): the prototype's
   `.rules-table` with the order and its arrows in the first cell (the up arrow is the down one turned), the name above
   the condition tags, the norm's `.inline-input` wide enough for 10000; "No SLA" as a callout with a warning's edge; the
   rule editor's conditions a row each - attribute, check, value(s), remove - and "one of" as chips. */
.rules-table td{vertical-align:middle}
.rules-table td.rule-order{width:1%;white-space:nowrap}
.rule-order>span{display:inline-block;min-width:18px;text-align:right;margin-right:4px}
.rule-order .icon-button,.rule-actions .icon-button{width:28px;height:28px}
.rule-order .icon-button .icon,.rule-actions .icon-button .icon{width:16px;height:16px}
.rule-order .icon-button:disabled{opacity:.35}
.rule-up .icon{transform:rotate(180deg)}
.rule-what{min-width:220px}
.rule-what>strong{display:block;font-weight:500;margin-bottom:6px}
.rule-conditions-list{display:flex;flex-wrap:wrap;gap:6px}
.rule-conditions-list .condition-tag{line-height:1.4;overflow-wrap:anywhere}
.rules-table .inline-input{width:66px}
.rule-hours,.rule-frt,.rule-matches{white-space:nowrap}
.rule-actions{white-space:nowrap;text-align:right}
.sla-no-policy{border-left:3px solid var(--orange)}
.sla-no-policy>.icon{color:var(--orange)}
.sd-dialog.sla-rule-dialog{width:min(780px,calc(100vw - 32px));max-width:780px}
.rule-editor .form-grid{grid-template-columns:minmax(0,1fr) 200px;margin-bottom:20px}
.rule-editor .form-label>.form-control{margin-top:5px}
.rule-conditions{border:0;padding:0;margin:0;min-width:0}
.rule-conditions>legend{float:none;width:auto;font-size:13px;margin:0 0 10px;padding:0}
.rule-condition{display:grid;grid-template-columns:236px 136px minmax(0,1fr) 32px;gap:8px;align-items:start;margin-bottom:10px}
.rule-condition-yes{align-self:center;color:var(--muted);font-size:13px}
.rule-condition-error{grid-column:1 / -1;margin-top:0!important}
.rule-values-hint{font-size:11px;margin:8px 0 0}
.rule-value-chips{list-style:none;margin:0 0 6px;padding:0;display:flex;flex-wrap:wrap;gap:6px}
.rule-value-chips>li{display:inline-flex;align-items:center;gap:4px;background:var(--canvas);border:1px solid var(--line);border-radius:5px;padding:2px 4px 2px 8px;font-size:12px;overflow-wrap:anywhere}
.rule-value-remove{border:0;background:transparent;color:var(--muted);padding:0;display:inline-flex}
.rule-value-remove .icon{width:13px;height:13px}
.rule-value-add{display:flex;gap:6px}
.rule-value-add .btn{white-space:nowrap}
.sd-dialog.sla-matches-dialog{width:min(640px,calc(100vw - 32px));max-width:640px}
/* A norm the server refused, said under its field (review of part 5c). */
.rules-table .inline-input.is-invalid{border-color:var(--red)}
.rule-hours .rule-hours-error{display:block;white-space:normal;color:var(--red);font-size:12px;margin-top:4px;min-width:180px;max-width:240px}
.sla-matches-tenant h3{font-size:13px;margin:14px 0 8px}
.sla-ticket-list{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap;gap:6px 14px;font-size:13px}
@media(max-width:640px){
  .rule-editor .form-grid{grid-template-columns:minmax(0,1fr)}
  .rule-condition{grid-template-columns:minmax(0,1fr) 32px}
  .rule-condition>:not(.icon-button){grid-column:1}
  .rule-condition>.icon-button{grid-column:2;grid-row:1}
}

/* Settings → Forms (part 5c spec S6; src/app/[tenant]/settings/forms/page.tsx, src/components/settings/FormSettingsForm.tsx):
   the warnings of what the classes leave out, the form's facts as `.split-line` rows, the calendar and the matrix side by
   side (the calendars' `.calendar-controls`), the class tables - a select a row, the tickets on the right - and the field
   map folded under its summary line, open when a field is not found in Pyrus. */
/* several cards of one section (a form each; a tenant each on Synchronization) stand apart */
.settings-layout .setting-card+.setting-card{margin-top:22px}
.form-warnings ul{margin:6px 0;padding-left:18px}
.form-warnings small{display:block}
.form-facts{margin:0 0 8px}
.form-settings .calendar-controls{margin:18px 0 6px}
.form-settings .calendar-controls>label{display:block;margin:0}
.form-settings .calendar-controls .form-select{margin-top:7px}
.form-settings small.setting-error{display:block;color:var(--red);font-size:12px;margin-top:5px}
.form-classes{margin-top:26px}
.form-classes>h3{font-size:14px;font-weight:600;margin:0 0 4px}
.form-classes>p{font-size:12px;margin:0 0 10px}
.form-class-errors{margin:0 0 8px}
.form-class-warnings{margin:0 0 8px}
.form-settings small.setting-warning{font-size:12px;margin-top:5px}
.form-class-table td{padding:10px 12px}
.form-class-table td:first-child small{display:block;margin-top:3px}
.form-class-table .form-select{min-width:230px}
.form-class-tickets{text-align:right;white-space:nowrap;width:1%}
.form-fields{margin-top:24px;font-size:13px}
.form-fields>summary{cursor:pointer;color:var(--accent);font-weight:500}
.form-fields>summary.text-danger{color:var(--red)}
.form-fields>p{font-size:12px;margin:8px 0 0}
.form-field-table td{padding:10px 12px}
.form-field-ok{display:inline-flex;align-items:center;gap:5px;color:var(--green)}
.form-field-ok .icon{width:14px;height:14px}
.form-field-missing strong{display:block;color:var(--red);font-weight:600}
.form-field-missing small{color:var(--muted);font-size:11px}
@media(max-width:560px){.form-class-table .form-select{min-width:0}.form-class-table td{padding:8px}}

/* The profile window (the owner 2026-09-28: tabs «Общие» / «Уведомления», one style; src/components/shell/
   ProfileDialog.tsx, TelegramBlock.tsx). The prototype's `.page-tabs` across the top of the body, edge to edge; the
   prototype's `.profile-intro`; then sections, each a small caps title over rows - a label (and a hint under it) at
   the left, its value, badge, select, switch or one button at the right, a hairline between rows. Three text sizes
   only: 13 px a row, 12 px a hint, 11 px a section's title. Tokens only, so both themes follow. */
.sd-dialog.profile-dialog{max-width:500px}
.profile-dialog .dialog-body{padding:0 24px 24px}
.profile-dialog .dialog-body>:first-child:not(.profile-tabs){margin-top:24px}
.profile-tabs{margin:0 -24px 22px;padding:14px 24px 0}
.profile-panel[hidden]{display:none}
.profile-dialog .profile-intro{margin-bottom:22px}
.profile-dialog .profile-intro .avatar{width:44px;height:44px;border-radius:10px;font-size:14px;flex-shrink:0}
.profile-dialog .profile-intro>div{min-width:0}
.profile-dialog .profile-intro h3{font-size:16px;font-weight:600;line-height:1.3}
.profile-dialog .profile-intro p{font-size:13px;margin:2px 0 0;overflow-wrap:anywhere}
.profile-section{margin:0 0 22px}
.profile-section:last-child{margin-bottom:0}
.profile-section-title{font-size:11px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--muted);margin:0 0 4px;line-height:1.4}
.profile-hint{font-size:12px;line-height:1.45;color:var(--muted);margin:0 0 6px}
.profile-empty{font-size:13px;margin:8px 0 0}
.profile-roles,.profile-toggles{list-style:none;margin:0;padding:0}
.profile-row,.profile-toggle{display:flex;align-items:center;justify-content:space-between;gap:14px;min-height:44px;margin:0;padding:8px 0;border-bottom:1px solid var(--line);font-size:13px;font-weight:400;color:var(--ink)}
.profile-section>.profile-row:last-child,.profile-roles>li:last-child,.profile-toggles>li:last-child>.profile-toggle{border-bottom:0}
.profile-row-text{display:flex;flex-direction:column;gap:2px;min-width:0}
.profile-row-text>small{font-size:12px;line-height:1.4;color:var(--muted)}
.profile-row>.btn,.profile-row>.neutral-badge{flex-shrink:0}
.profile-row>.form-select{width:auto;min-width:130px;flex-shrink:0}
.profile-toggle{cursor:pointer}
.profile-toggle .form-check{margin:0;padding:0;min-height:0;flex-shrink:0}
.profile-toggle .form-check-input{float:none;margin:0;width:34px;height:20px;cursor:pointer}
.profile-toggle .form-check-input:disabled{opacity:.6;cursor:default}
.profile-group{margin-top:10px}
.profile-group-title{font-size:12px;font-weight:600;color:var(--ink);margin:0;padding-top:4px}
.profile-status{display:inline-flex;align-items:center;gap:8px;font-weight:500}
.profile-status::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--muted);flex-shrink:0}
.profile-status.is-ok::before{background:var(--green)}
.profile-status.is-error{color:var(--red)}
.profile-status.is-error::before{background:var(--red)}
.profile-actions{display:flex;justify-content:flex-end;padding-top:6px;border-top:1px solid var(--line);margin-top:4px}
.profile-actions>.btn{margin-top:14px}
.profile-dialog .alert{font-size:13px}
.profile-telegram[aria-busy="true"]{opacity:.7}
.profile-telegram [aria-disabled="true"]{cursor:progress}
.telegram-status{margin:4px 0 8px;font-size:12px;line-height:1.45}
.telegram-status.is-ok{color:var(--green)}
.telegram-status.is-error{color:var(--red)}
@media (max-width:560px){
  .profile-dialog .dialog-body{padding:0 16px 20px}
  .profile-dialog .dialog-body>:first-child:not(.profile-tabs){margin-top:16px}
  .profile-tabs{margin:0 -16px 18px;padding:12px 16px 0}
  .profile-row{flex-wrap:wrap;row-gap:8px}
  .profile-row>.form-select{min-width:0;flex:1 1 140px}
}
.people-telegram{margin-top:18px}
.people-telegram>p{font-size:13px;margin:0 0 10px}
/* Part 6b: the card's letters switch (a switch and its words, in the actions' row) and the profile's channel switch as a
   section's last row. */
.people-mail-switch{display:inline-flex;align-items:center;gap:8px;margin:0;font-size:13px;cursor:pointer}
.people-mail-switch .form-check{margin:0;padding:0;min-height:0}
.people-mail-switch .form-check-input{float:none;margin:0;width:34px;height:20px;cursor:pointer}
.profile-section>.profile-toggle:last-child{border-bottom:0}
.connect-link{margin-top:12px}
.connect-link-row{display:flex;gap:8px;align-items:center}
.connect-link-row>.form-control{flex:1;min-width:0;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}
.connect-link .form-hint{font-size:12px;color:var(--muted);margin:6px 0 0}
.connect-link .people-status{margin:6px 0 0}
/* Settings → Notifications (src/app/[tenant]/settings/notifications): the bot's badge in its colour, the rules table
   (an event per row - not the SLA matrix's narrow first column), the quiet hours beside their zone, the test button */
.integration-status .neutral-badge.is-ok{color:var(--green);border-color:var(--green)}
.integration-status .neutral-badge.is-error{color:var(--red);border-color:var(--red)}
.integration-status>div>p+p{margin-top:2px}
/* The Mail card's facts (2026-09-29): what the worker signs in with, apart from the state, smaller; a long login wraps */
.integration-status .mail-login{margin-top:6px;padding-top:6px;border-top:1px solid var(--line);font-size:12px;color:var(--muted);overflow-wrap:anywhere}
.integration-status .mail-login p+p{margin-top:2px}
/* The tables' scroll box holds what is absolutely positioned inside (a header's `.visually-hidden` text): without it
   that text sits where the header would be - past the card when the table scrolls - and widens the page itself. */
.notify-scroll{position:relative}
/* Settings → Notifications in tabs (the owner, 2026-09-30, item 3). «Каналы»: a card per channel - its state (the
   prototype's `.integration-status`), a line of what it is for, its master switch (the prototype's `.setting-toggle`
   between two rules) with its answer under it, its test send; the quiet hours' card. */
.notify-channel-card .setting-lead{margin:0 0 6px}
.notify-channel-switch{margin-top:10px}
.notify-channel-switch .setting-toggle{padding:14px 0;margin:0;border-top:1px solid var(--line)}
.notify-channel-switch .setting-toggle .form-check-input{cursor:pointer}
.notify-quiet-form .setting-toggle{padding-top:0}
.notify-quiet-form .calendar-controls{margin:0 0 6px}
.notify-quiet-form .calendar-controls>label{display:block;margin:0}
.notify-quiet-form .calendar-controls .form-select{margin-top:7px}
.notify-quiet-form small.setting-error{display:block;color:var(--red);font-size:12px;margin-top:5px}
/* The quiet days (the owner, 2026-10-19) under the hours: the Calendars' chips (`.calendar-weekdays`, wrapping on a
   phone), their hint under them. */
.notify-quiet-form .notify-quiet-days{margin-top:18px}
.notify-quiet-days>small.muted{display:block;font-size:12px;margin-top:8px;max-width:640px}
/* ── The mail's letters and copies (the owner, 2026-10-01) ──────────────────────────────────────────────────────────
   «Каналы»: «Сохранять копии писем в „Отправленных“» under the mail's master switch - the same row (.setting-toggle),
   one rule between the two; its hint is the whole explanation, so the switch stays at the top beside it.
   «Журнал» → «Письма»: the filters in a row (on a phone one under another, each the card's width), then
   the table - four columns that fit the card of a desktop window (721 px at 1280) without a sideways scroll: the moment
   (two lines when the card is narrow), the letter (its kind, its subject, what it is about), the addresses (each on
   its own line; a long one breaks), the outcome with the moment it was sent. Why a letter waits or did not go is a
   line of its own under its row, the table's width (as .sync-run-error). Narrower than its columns' least widths
   (620 px) the table scrolls inside its box (.table-responsive, .notify-scroll) - the page never does. */
.mail-copies-switch{margin-top:0}
.mail-copies-switch .setting-toggle{align-items:flex-start;border-top:0}
.mail-letters-filters{display:flex;flex-wrap:wrap;gap:10px;margin:0 0 14px}
.mail-letters-filters label{margin:0;min-width:0;flex:0 1 auto}
.mail-letters-filters .form-select{width:230px;max-width:100%}
.mail-letters-filters .mail-letters-search{flex:1 1 180px}
.mail-letters-filters .form-control{width:100%}
.mail-letters[aria-busy="true"] .mail-letters-table{opacity:.6}
.mail-letters-table{margin:0;min-width:620px}
.mail-letters-table thead th{padding:11px 8px;white-space:nowrap}
.mail-letters-table td{padding:10px 8px;vertical-align:top;font-size:13px}
.mail-letters-table td small{display:block;font-size:11px;color:var(--muted);margin-top:3px}
.mail-letters-table .mail-letter-time{width:1%;min-width:116px;color:var(--muted)}
.mail-letters-table .mail-letter-kind{min-width:170px}
.mail-letters-table .mail-letter-kind strong{display:block;font-weight:500}
.mail-letters-table .mail-letter-subject{display:block;font-size:12px;color:var(--muted);overflow-wrap:anywhere;margin-top:2px}
.mail-letters-table .mail-letter-to{min-width:150px}
.mail-letters-table .mail-letter-to span{display:block;overflow-wrap:anywhere}
.mail-letters-table .mail-letter-to small{overflow-wrap:anywhere}
.mail-letters-table .mail-letter-outcome{width:1%;min-width:120px}
.mail-letters-table tr.has-reason>td{border-bottom:0;padding-bottom:4px}
.mail-letters-table td.mail-letter-reason{padding-top:0;font-size:12px;color:var(--muted);overflow-wrap:anywhere}
.mail-letters-table td.mail-letter-reason.is-failed,.mail-letters-table td.mail-letter-reason.is-expired{color:var(--red)}
.mail-letters-more{margin-top:14px}
.mail-letters-more [aria-disabled="true"]{opacity:.55;cursor:progress}
.mail-letters-bound{margin:14px 0 0}
.mail-letters-none{margin:0}
@media (max-width:560px){
  .mail-letters-filters{flex-direction:column}
  .mail-letters-filters .form-select{width:100%}
  .mail-letters-filters .mail-letters-search{flex:0 0 auto}
}
@media (pointer:coarse){.mail-letters-filters .form-control,.mail-letters-filters .form-select{font-size:16px}}
/* ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────── */
/* «События»: the events' list at the left, the chosen one's form at the right, in one bordered box (642 px inside the
   card at 1100, the sidebar open: a 230 px list, the form the rest). Each line of the list - a dot of its state (on -
   green, off - an empty ring, nothing would go - orange, a value to fix - red), the name and its summary; the chosen one
   white with the accent's bar. The form: when it happens, its switch, whom and by which channels as pill checkboxes,
   the delay and the repeat side by side while they fit. An event switched off greys its fields (they keep their
   values). The card narrower than 560 px (a phone) stacks the list over the form; nothing scrolls sideways. */
.notify-events-form{container-type:inline-size}
.notify-md{display:grid;grid-template-columns:230px minmax(0,1fr);border:1px solid var(--line);border-radius:8px;background:var(--surface)}
.notify-md-list{display:flex;flex-direction:column;gap:2px;padding:6px;background:var(--canvas);border-right:1px solid var(--line);border-radius:8px 0 0 8px}
.notify-md-item{display:flex;gap:10px;align-items:flex-start;width:100%;padding:9px 10px;border:0;border-radius:6px;background:transparent;color:var(--ink);text-align:left}
.notify-md-item:hover{background:var(--surface)}
.notify-md-item:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.notify-md-item[aria-selected="true"]{background:var(--surface);box-shadow:inset 3px 0 0 var(--accent),0 1px 2px #0d234014}
.notify-md-text{min-width:0}
.notify-md-item strong{display:block;font-weight:500;font-size:13px;line-height:18px}
.notify-md-item[aria-selected="true"] strong{color:var(--accent)}
.notify-md-item small{display:block;margin-top:2px;font-size:11.5px;line-height:1.35;color:var(--muted)}
.notify-md-dot{flex:0 0 8px;width:8px;height:8px;margin-top:5px;border-radius:50%;background:var(--green)}
.notify-md-item[data-state="off"] .notify-md-dot{background:transparent;box-shadow:inset 0 0 0 1.5px var(--muted)}
.notify-md-item[data-state="off"] strong{color:var(--muted)}
.notify-md-item[data-state="empty"] .notify-md-dot{background:var(--orange)}
.notify-md-item[data-state="error"] .notify-md-dot{background:var(--red)}
.notify-md-detail{min-width:0;padding:16px 18px}
.notify-md-panel[hidden]{display:none}
.notify-md-head h3{margin:0 0 3px;font-size:15px}
.notify-md-head p{margin:0;font-size:12px;line-height:1.4}
.notify-md-enabled{padding:12px 0;margin:0}
.notify-md-group{min-width:0;margin:14px 0 0;padding:0;border:0}
.notify-md-group legend{display:flex;align-items:center;gap:6px;float:none;width:auto;margin:0 0 7px;padding:0;font-size:12px;font-weight:600;color:var(--muted);line-height:1.3}
.notify-audiences{display:flex;flex-wrap:wrap;align-items:center;gap:6px 8px}
.notify-audience{display:inline-flex;align-items:center;gap:7px;margin:0;padding:4px 11px 4px 8px;border:1px solid var(--line);border-radius:999px;font-size:12px;line-height:18px;cursor:pointer;background:var(--surface);color:var(--ink)}
.notify-audience .form-check-input{margin:0;float:none;width:14px;height:14px;cursor:pointer}
.notify-audience:has(.form-check-input:checked){border-color:var(--accent);background:var(--accent-soft)}
.notify-channel-off{font-size:11px;color:var(--orange)}
.notify-md-note{display:block;margin-top:7px;font-size:11.5px;line-height:1.4}
.notify-md-timing{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px 18px;margin-top:16px}
.notify-md-amount{display:flex;flex-direction:column;gap:5px;min-width:0}
.notify-md-amount-label{display:flex;align-items:center;gap:4px;font-size:12px;color:var(--muted);line-height:1.3}
.notify-md-amount-label label{margin:0}
.notify-md-amount .input-group{width:100%;max-width:210px;flex-wrap:nowrap}
.notify-md-amount .input-group .form-select{flex:0 0 84px;width:84px;padding-inline-end:26px;background-position:right 8px center}
.notify-md-amount .form-control{text-align:right}
.notify-md-panel:has(.notify-enabled:not(:checked)) .notify-md-fields{opacity:.45}
.notify-md-warning{margin:14px 0 0;padding:8px 10px;border-radius:6px;background:var(--orange-soft);color:var(--orange);font-size:12px;line-height:1.4}
.notify-events-form small.setting-error{display:block;color:var(--red);font-size:12px}
.notify-md-lead{margin:12px 0 0}
@container (max-width:560px){
  .notify-md{grid-template-columns:minmax(0,1fr)}
  .notify-md-list{border-right:0;border-bottom:1px solid var(--line);border-radius:8px 8px 0 0}
  .notify-md-detail{padding:14px 12px;scroll-margin-top:12px}
}
.notify-test{margin-top:20px}
/* Templates v2 (the owner, 2026-09-30, item 3: «сделай единый редактор в поле зрения, без прокрутки»): the event and
   the channel in one row (the card's heading); under it the editor and its live preview side by side once the card is
   680 px wide (a container query: the settings' own menu takes part of the screen) - at 1280 x 800 both whole in the
   window as the tab opens. Narrower, the two stack and a sticky switch shows one
   of them (`data-view`). Placeholders are marked in the fields themselves (HighlightField: a transparent field over a
   backdrop with the same text and box, the marks behind the glyphs). Nothing scrolls sideways: the preview wraps. */
.tpl-card-title{display:flex;align-items:center;gap:6px}
.tpl-card-title .help-tooltip>span{width:min(320px,calc(100vw - 48px));transform:translateX(-30%)}
.tpl-top{display:flex;flex-wrap:wrap;align-items:center;gap:8px 18px;margin:0 0 14px}
/* the templates' card: its heading is the row of the event, the channel, the state, the way back and the help, with the
   saving's status at its end (wrapping under them when the card is narrow) - one row less above the editor */
.settings-card-heading.tpl-heading{align-items:center;gap:8px 16px;padding:14px 20px}
.tpl-heading .tpl-top{margin:0;flex:1 1 auto;min-width:0;gap:8px 14px}
.tpl-heading>.autosave-status{margin-left:auto}
.tpl-top .help-tooltip>span{left:auto;right:-8px;transform:none;width:min(320px,calc(100vw - 96px))}
.tpl-pick{display:flex;align-items:center;gap:8px;margin:0;font-size:13px;min-width:0}
.tpl-pick>span{color:var(--muted)}
.tpl-pick .form-select{width:240px;max-width:100%;text-overflow:ellipsis}
.tpl-top .neutral-badge.is-ok{color:var(--green);border-color:var(--green)}
.tpl-top .neutral-badge.is-unsaved{color:var(--orange);border-color:var(--orange);background:var(--orange-soft)}
.tpl-reset{padding:0 2px;min-height:0;font-size:12px;display:inline-flex;align-items:center;gap:4px;border:0;background:transparent;box-shadow:none;color:var(--accent)}
.tpl-reset .icon{width:14px;height:14px}
.tpl-switch{display:inline-flex;flex-wrap:wrap;gap:3px;padding:3px;border:1px solid var(--line);border-radius:7px;background:var(--surface);max-width:100%}
.tpl-switch button{border:0;background:transparent;color:var(--muted);padding:4px 10px;border-radius:4px;font-size:12px;white-space:nowrap}
.tpl-switch button.is-on{background:var(--accent-soft);color:var(--accent);font-weight:600}
.tpl-switch button:focus-visible{outline-offset:-2px}
.tpl-switch-one{font-size:13px}
.tpl-page,.tpl-container{container:tpl/inline-size}
.tpl-layout{display:grid;grid-template-columns:minmax(0,1fr);gap:14px 20px;align-items:start}
.tpl-view-toggle{position:sticky;top:0;z-index:3;padding:6px 0;background:var(--surface)}
.tpl-layout[data-view=edit] .tpl-preview-col,.tpl-layout[data-view=preview] .tpl-edit-col{display:none}
.tpl-editor{display:flex;flex-direction:column;gap:10px;min-width:0}
.tpl-part{display:flex;flex-direction:column;gap:4px;min-width:0}
.tpl-part-label{margin:0;font-weight:500;font-size:13px}
.tpl-part small{font-size:12px;line-height:1.4}
.tpl-toolbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.tpl-toolbar .btn{min-height:30px;font-size:12px;padding:4px 9px;gap:5px}
.tpl-toolbar .icon{width:15px;height:15px}
.tpl-editor small.setting-error,.mailing-editor .tpl-editor small.setting-error{display:block;color:var(--red);font-size:12px;margin:0}
/* the field over its marks: the same font, box and wrapping on both */
.tpl-hl{position:relative;border-radius:6px;background:var(--surface)}
.tpl-hl-back,.tpl-hl-input{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12.5px;line-height:1.55;letter-spacing:0;padding:7px 11px;border:1px solid transparent;tab-size:4}
.tpl-hl-back{position:absolute;inset:0;overflow:hidden;color:transparent;pointer-events:none;border-radius:6px}
.tpl-hl-text{white-space:pre;overflow-wrap:normal}
.tpl-hl.is-multi .tpl-hl-text{white-space:pre-wrap;overflow-wrap:anywhere}
.tpl-hl-input{position:relative;display:block;width:100%;background:transparent!important;border-color:var(--line);color:var(--ink)}
textarea.tpl-hl-input{resize:vertical;overflow-wrap:anywhere;min-height:180px}
input.tpl-hl-input{min-height:0;height:auto}
.tpl-hl.is-multi .tpl-hl-back,textarea.tpl-hl-input{scrollbar-gutter:stable}
.tpl-mark{padding:0;margin:0;border-radius:3px;color:transparent;background:var(--accent-soft);box-shadow:0 0 0 1px var(--accent-soft)}
.tpl-mark.is-list{background:var(--green-soft);box-shadow:0 0 0 1px var(--green-soft)}
.tpl-mark.is-bad{background:var(--red-soft);box-shadow:0 0 0 1px var(--red)}
/* the insert menu */
.tpl-menu{position:relative}
.tpl-menu-panel{position:absolute;z-index:40;top:calc(100% + 4px);left:0;width:min(400px,calc(100vw - 48px));padding:8px;border:1px solid var(--line);border-radius:8px;background:var(--surface);box-shadow:0 10px 30px #0d23401f;display:flex;flex-direction:column;gap:6px}
.tpl-menu-for{font-size:11px}
.tpl-menu-list{max-height:320px;overflow-y:auto;overscroll-behavior:contain}
.tpl-menu-heading{padding:6px 6px 2px;font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
.tpl-menu-option{display:grid;grid-template-columns:150px minmax(0,1fr);gap:0 10px;padding:6px;border-radius:5px;cursor:pointer;font-size:12.5px;line-height:1.35}
.tpl-menu-option code{grid-row:span 2;align-self:start;justify-self:start;font-size:12px;color:var(--accent);background:var(--accent-soft);padding:1px 5px;border-radius:4px;white-space:nowrap}
.tpl-menu-option small{grid-column:2;font-size:11px;overflow-wrap:anywhere}
.tpl-menu-option.is-active{background:var(--canvas);outline:1px solid var(--accent)}
.tpl-menu-option.is-unfit{cursor:default;opacity:.55}
.tpl-menu-text{min-width:0;overflow-wrap:anywhere}
.tpl-menu-none{padding:8px 6px;font-size:12px}
/* the preview */
.tpl-preview-col{display:flex;flex-direction:column;gap:8px;min-width:0;padding:12px;border:1px solid var(--line);border-radius:8px;background:var(--canvas)}
.tpl-preview-head{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px}
.tpl-preview-head h3{margin:0;font-size:13px}
.tpl-preview-title{display:flex;align-items:center;gap:5px}
.tpl-preview-title .help-tooltip>span{transform:translateX(-30%)}
/* the switches flow with the heading: «1 ticket / several» beside it in a 300 px column */
.tpl-page .tpl-preview-switches{display:contents}
.tpl-preview-switches{display:flex;flex-wrap:wrap;gap:6px;min-width:0}
.tpl-preview-switches .tpl-switch{padding:2px}
.tpl-preview-switches .tpl-switch button{padding:3px 8px;font-size:11.5px}
.tpl-preview-body{display:flex;flex-direction:column;gap:8px;min-width:0;max-height:430px;overflow-y:auto}
.tpl-preview-col>small{font-size:12px}
.tpl-bubble{align-self:flex-start;max-width:100%;padding:9px 12px;border-radius:12px 12px 12px 4px;border:1px solid var(--line);background:var(--surface);font-size:13px;line-height:1.45;overflow-wrap:anywhere}
.tpl-bubble-line{min-height:1em}
.tpl-letter{display:flex;flex-direction:column;gap:6px;min-width:0}
.tpl-letter-head{display:flex;flex-direction:column;gap:2px;margin:0;font-size:12.5px;overflow-wrap:anywhere}
.tpl-letter-frame{display:block;width:100%;height:340px;border:1px solid var(--line);border-radius:6px;background:#fff}
/* the rows' window */
.sd-dialog.tpl-rows-dialog{max-width:760px}
.tpl-rows{list-style:none;margin:0 0 14px;padding:0;display:flex;flex-direction:column;gap:6px}
/* the heading row and each field row are grids of the same tracks - the label's and the buttons' of fixed widths, so
   the flexible ones split the same width in every row and each heading stands over its column */
.tpl-rows-head,.tpl-row{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1.3fr) 112px 100px;gap:8px 10px;align-items:center}
.tpl-rows.is-mail .tpl-rows-head,.tpl-rows.is-mail .tpl-row{grid-template-columns:minmax(0,.9fr) minmax(0,1fr) 104px minmax(0,1.25fr) 100px}
.tpl-rows-head{font-size:11px;color:var(--muted);padding:0 0 2px}
.tpl-row{padding:4px 0;border-top:1px solid var(--line)}
.tpl-rows .form-control,.tpl-rows .form-select{min-height:32px;padding-top:4px;padding-bottom:4px}
.tpl-row-name{font-size:13px;overflow-wrap:anywhere}
.tpl-row-heading,.tpl-row-where{margin:0;min-width:0}
.tpl-row-label{margin:0;display:flex;align-items:center;gap:6px;padding:0;min-height:0}
.tpl-row-label .form-check-input{margin:0;float:none}
.tpl-row-caption{display:none;font-size:12px}
.tpl-row-actions{display:flex;gap:2px}
.tpl-row-actions .icon{width:16px;height:16px}
.tpl-row-actions .is-up{transform:rotate(180deg)}
.tpl-rows-add{display:flex;align-items:center;gap:10px;margin:0 0 14px;font-size:13px}
.tpl-rows-add .form-select{width:auto;min-width:220px;max-width:100%}
.tpl-rows-sample{display:flex;flex-direction:column;gap:6px;font-size:12px;margin-top:12px}
.tpl-rows-sample+.tpl-rows-sample{margin-top:10px}
.tpl-chat-line{white-space:pre-wrap;min-height:1em}
/* {TABLE} of a letter: the headings over the sample tickets, as the letter's table (it scrolls inside itself when
   wider than the window, never the page) */
.tpl-rows-table-wrap{max-width:100%;overflow-x:auto}
.tpl-rows-table{border-collapse:collapse;font-size:12.5px;background:var(--surface)}
.tpl-rows-table th,.tpl-rows-table td{border:1px solid var(--line);padding:4px 8px;text-align:left;vertical-align:top;overflow-wrap:break-word}
.tpl-rows-table th{background:var(--canvas);font-weight:600}
.tpl-chat{padding:9px 12px;border-radius:8px;border:1px solid var(--line);background:var(--canvas);font-size:13px;line-height:1.45;overflow-wrap:anywhere}
@container tpl (min-width:680px){
  .tpl-layout{grid-template-columns:minmax(0,1.25fr) minmax(0,1fr)}
  .tpl-layout.is-digest{grid-template-columns:minmax(0,1fr) minmax(0,1.15fr)}
  .tpl-view-toggle{display:none}
  .tpl-layout[data-view] .tpl-preview-col,.tpl-layout[data-view] .tpl-edit-col{display:flex}
  .tpl-layout[data-view] .tpl-edit-col{display:block}
  .tpl-preview-col{position:sticky;top:12px}
  /* the templates of the notifications: the editor and the letter sized to the window, so both are whole in it as the
     tab opens at 1280 x 800 and 1366 x 768 (the page's heading, tabs and the card's row take ~390 px above them); the
     letter scrolls inside its frame, a Telegram message inside the preview */
  .tpl-page .tpl-letter-frame{height:clamp(180px,calc(100vh - 587px),560px)}
  .tpl-page .tpl-preview-body{max-height:clamp(220px,calc(100vh - 470px),720px)}
}
/* in the editor's heading the ⓘ may land anywhere once the row wraps (from ~760 px down - at the left edge too, where
   a help opening leftwards would run off the window): its help opens under the heading, card-wide */
@media (max-width:800px){
  .tpl-heading{position:relative}
  .tpl-heading .help-tooltip{position:static}
  .tpl-heading .help-tooltip>span{top:calc(100% - 6px);bottom:auto;left:16px;right:16px;width:auto;max-width:none;transform:none}
}
@media (max-width:600px){
  /* the help of the templates' card: from the title's left edge, as wide as the screen allows - never past its edge */
  .tpl-card-title{position:relative}
  .tpl-card-title .help-tooltip{position:static}
  .tpl-card-title .help-tooltip>span{left:0;right:auto;transform:none;width:min(320px,calc(100vw - 64px))}
  .tpl-rows-head{display:none}
  .tpl-row,.tpl-rows.is-mail .tpl-row{grid-template-columns:minmax(0,1fr) auto}
  .tpl-row-name{grid-column:1/-1;font-weight:500}
  .tpl-row-heading{grid-column:1}
  .tpl-row-label{grid-column:1/-1}
  .tpl-row-caption{display:inline}
  .tpl-row-where{grid-column:1}
  .tpl-row-actions{grid-column:2;grid-row:2}
  .tpl-pick{flex-wrap:wrap}
  .tpl-pick .form-select{min-width:0;width:100%}
}
/* The recipients and the journal: tight cells, like the Synchronization run log's (.sync-runs); the page never scrolls
   sideways (.notify-scroll). The recipients by both channels (the owner, 2026-10-01): a person a row - the name, the
   Telegram chat, the letters' addresses - each chat and each address a line with its action at the right, the
   prototype's text button (as «Доступ»'s row actions); the cells start at the top, so a person with three addresses
   still reads from his name. Calmer since the owner's 2026-10-06 «Слишком перегружена»: a chat says its Telegram name
   and its state only, an address only itself; the rest - since when and how a chat was connected, its last message,
   what goes to an address and who switched it on, the person's last letter - is under «Подробнее» below the name: a
   row across the table on the canvas, as the journal's «Кому», a line per chat or address - what it is, then its
   facts in muted columns. Above the table: a line per channel that sends nothing now (orange, as
   `.notify-channel-off`), then the totals and the period's segmented switch as the filter, wrapping under the totals
   on a phone.
   The card is narrow not only on a phone: beside the Settings menu its box is 295 px at a 768 px screen, 551 px at
   1024 and 627 px at 1100 - narrower than at 700, where the menu goes above. So what a narrow box needs follows the
   box, not the screen: the list's box and the journal's scroll box are size containers (`notify-box`). Under 700 px
   of it each action of the list goes under its text and a line of «Подробнее» stands its facts one under another -
   the three columns then read down to 520 px, the table's least width. In a box narrower still (a phone, a tablet
   upright: 307 and 295 px) a sideways scroll would leave the letters - what the list is for - off the screen behind
   the Telegram column, with nothing to say they are there. So there a person's three cells stand one under another,
   as the import's table does on a phone (`.import-table`): the name, then each channel under its column's name (the
   cell's `data-label`; the header row is kept for a screen reader only), each action beside its text again, the
   details under them while open - nothing of the list scrolls sideways. */
.notify-recipients-box,.notify-journal-box{container:notify-box/inline-size}
.notify-recipients thead th,.notify-journal thead th{padding:11px 10px;white-space:normal}
.notify-recipients td,.notify-journal td{padding:10px}
.notify-recipients{min-width:520px}
.notify-recipients td{vertical-align:top}
.notify-recipients td small{display:block;font-size:11px;color:var(--muted);margin-top:3px;overflow-wrap:anywhere}
.notify-recipients td small.text-danger{color:var(--red)}
.notify-recipients .notify-who-cell{width:24%;overflow-wrap:anywhere}
.notify-recipients .notify-who-cell strong{font-weight:500}
.notify-recipients .notify-chat-cell{width:36%}
.notify-recipients .notify-none{font-size:12px;color:var(--muted)}
.notify-chat,.notify-letters>li{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.notify-chat+.notify-chat,.notify-letters>li+li{margin-top:8px;padding-top:8px;border-top:1px solid var(--line)}
.notify-chat-text,.notify-letters .people-email{min-width:0}
.notify-chat-name{display:block;overflow-wrap:anywhere}
.notify-chat .text-button,.notify-letters .text-button{flex:0 0 auto;white-space:nowrap}
.notify-letters{list-style:none;margin:0;padding:0}
.notify-recipients .notify-more-toggle{display:flex;gap:0;margin-top:5px;color:var(--muted);font-weight:400}
.notify-recipients .notify-more-toggle:hover,.notify-recipients .notify-more-toggle[aria-expanded="true"]{color:var(--accent)}
.notify-more-toggle::after{content:"";display:inline-block;margin-left:5px;border:4px solid transparent;border-top-color:currentColor;border-bottom-width:0;transition:transform .15s}
.notify-more-toggle[aria-expanded="true"]::after{transform:rotate(180deg)}
.notify-more-toggle:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.notify-recipients .notify-recipient-more>td{padding:2px 10px 8px;background:var(--canvas)}
.notify-more{list-style:none;margin:0;padding:0;font-size:12px;line-height:1.4}
.notify-more>li{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1.9fr) minmax(0,1.5fr);gap:2px 14px;align-items:baseline;padding:6px 0}
.notify-more>li+li{border-top:1px solid var(--line)}
.notify-more>li>span{overflow-wrap:anywhere;color:var(--muted)}
.notify-more>li>.notify-more-what{color:var(--ink)}
.notify-recipients-note{margin:0 0 8px;font-size:12px;line-height:1.4;color:var(--orange)}
.notify-recipients-bar{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px 16px}
.notify-recipients-totals{margin:0;font-size:13px}
.notify-recipients-filter{flex:0 0 auto}
.notify-recipients-filter button:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
@media (max-width:560px){.notify-recipients-filter{width:100%}.notify-recipients-filter button{flex:1 1 0}}
@media (prefers-reduced-motion:reduce){.notify-more-toggle::after{transition:none}}
/* «Журнал» (the owner, 2026-10-06: «Журнал я бы вообще вынес в отдельную вкладку»): one list at a time, chosen by the
   switch at the right of the card's heading - two links drawn as the period's segmented switch draws its buttons
   (`.period-segments`), the current one marked; under the heading's text on a phone, its two halves the card's width. */
.notify-journal-heading{flex-wrap:wrap;align-items:flex-start;gap:12px 16px}
.notify-journal-heading>div:first-child{flex:1 1 280px;min-width:0}
.notify-journal-views{flex:0 0 auto}
.notify-journal-views a{color:var(--muted);padding:7px 13px;border-radius:4px;font-size:13px;text-decoration:none;white-space:nowrap;text-align:center}
.notify-journal-views a:hover{color:var(--ink)}
.notify-journal-views a.active{background:var(--accent-soft);color:var(--accent);font-weight:600}
.notify-journal-views a:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
@media (max-width:760px){.notify-journal-views{width:auto}.notify-journal-views a{font-size:12px}}
@media (max-width:560px){.notify-journal-views{width:100%}.notify-journal-views a{flex:1 1 0}}
/* «Журнал»: the search by ticket number above either list (the owner, 2026-10-19) - the Tickets toolbar's box, wider
   (as People's); the whole width on a phone; the list dimmed while the new one comes. */
.notify-journal-search{display:flex;margin:0 0 14px}
.notify-journal-search .search-field{flex:0 1 320px;max-width:100%}
.notify-journal-search .search-field input{font-size:14px;padding:2px 0;min-height:24px;box-shadow:none}
.notify-journal-list[aria-busy="true"]{opacity:.55;pointer-events:none}
@media (max-width:560px){.notify-journal-search .search-field{flex-basis:100%}}
@media (pointer:coarse){.notify-journal-search .search-field input{font-size:16px}}
/* The journal's «Кому» (the owner, 2026-10-01): a button in a last narrow column - its caret turns when the row under
   it is open - and that row across the table, on the canvas: a recipient a line - the person, the channel (a letter
   with its addresses), the round, how it went (green - taken, orange - waiting, red - not delivered, muted - no longer
   true), when. In a box under 700 px (`notify-box` above: a phone, or the card beside the Settings menu up to about
   1170 px of the screen) the line folds - the person and the channel a line each, then the round and the outcome -
   and the button's column stays at the box's right edge while the table scrolls under it, so «Кому» is always in
   reach; its shadow only under 620 px, where the table is surely wider than its box (it cannot be narrower than
   about 600 px), never beside a table that fits. In a box of 700 px and more (the card of a desktop window) the moment
   takes two lines, as the letters' does (2026-10-06), and leaves its room to how the messages went. */
.notify-journal td:first-child{white-space:nowrap}
@container notify-box (min-width:700px){.notify-journal td:first-child{white-space:normal;width:1%;min-width:116px}}
.notify-journal td.notify-journal-open{width:1%;white-space:nowrap;text-align:right}
.notify-journal-toggle::after{content:"";display:inline-block;margin-left:6px;border:4px solid transparent;border-top-color:currentColor;border-bottom-width:0;vertical-align:middle;transition:transform .15s}
.notify-journal-toggle[aria-expanded="true"]::after{transform:rotate(180deg)}
.notify-journal-toggle:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.notify-journal .notify-journal-who>td{padding:4px 10px 8px;background:var(--canvas);white-space:normal}
.notify-who{list-style:none;margin:0;padding:0;font-size:12px;line-height:1.4}
.notify-who>li{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,2.2fr) minmax(0,1fr) minmax(0,1fr) 160px;gap:2px 14px;align-items:baseline;padding:6px 0}
.notify-who>li+li{border-top:1px solid var(--line)}
.notify-who-name,.notify-who-channel{overflow-wrap:anywhere}
.notify-who-round{color:var(--muted)}
.notify-who-outcome.is-sent{color:var(--green)}
.notify-who-outcome.is-waiting{color:var(--orange)}
.notify-who-outcome.is-failed{color:var(--red)}
.notify-who-outcome.is-obsolete{color:var(--muted)}
.notify-who-at{color:var(--muted);white-space:nowrap;text-align:right}
@media (prefers-reduced-motion:reduce){.notify-journal-toggle::after{transition:none}}
@container notify-box (max-width:699px){
  .notify-chat,.notify-letters>li{flex-direction:column;align-items:flex-start;justify-content:flex-start;gap:4px}
  .notify-more>li{grid-template-columns:minmax(0,1fr)}
  .notify-who>li{grid-template-columns:auto minmax(0,1fr)}
  .notify-who-name,.notify-who-channel,.notify-who-at{grid-column:1/-1}
  .notify-who-at{text-align:left}
  .notify-journal td.notify-journal-open{position:sticky;right:0;background:var(--surface)}
}
@container notify-box (max-width:619px){
  .notify-journal td.notify-journal-open{box-shadow:-8px 0 8px -8px #0d234026}
}
@container notify-box (max-width:519px){
  .notify-recipients thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
  .notify-recipients,.notify-recipients tbody,.notify-recipients tr,.notify-recipients td{display:block;width:auto;min-width:0}
  .notify-recipients tr{padding:10px 0;border-bottom:1px solid var(--line)}
  .notify-recipients tr[hidden]{display:none}
  .notify-recipients tr.notify-recipient-more{padding:0 0 10px}
  .notify-recipients .notify-recipient-more>td{padding:2px 10px 6px}
  .notify-recipients td,.notify-recipients .notify-who-cell,.notify-recipients .notify-chat-cell{width:auto;padding:5px 10px;border-bottom:0}
  .notify-recipients td[data-label]::before{content:attr(data-label);display:block;margin-bottom:4px;font-size:11px;font-weight:600;color:var(--muted)}
  .notify-chat,.notify-letters>li{flex-direction:row;align-items:baseline;justify-content:space-between;gap:10px}
}
@media(max-width:560px){.connect-link-row{flex-wrap:wrap}}

/* At 760px and below the prototype shrinks a page heading's buttons to their icon (`.heading-actions .btn{font-size:0;
   width:36px}`), but Tabler's `.btn .icon` keeps its uneven side margins (-1/4 and +1/2 of the button's padding), so the
   icon stood off centre - the Tickets "Columns" button's three lines among them (owner, 2026-09-28). */
@media (max-width:760px){.heading-actions .btn{justify-content:center}.heading-actions .btn .icon{margin:0}}
/* The prototype's shrink reaches every `.btn` under `.heading-actions`, and a window (dialog.sd-dialog) opened from a
   heading button sits in the heading's markup (SettingsHistory, PdfButton), so its buttons shrank too: Settings' "Show
   more" to an empty 36 px square, the PDF window's "Download PDF" to a bare icon. A window's buttons keep their size
   and label: Tabler's padding and icon margins, the prototype's gap, their own width. */
@media (max-width:760px){.heading-actions .sd-dialog .btn{font-size:var(--tblr-btn-font-size);width:auto;padding:var(--tblr-btn-padding-y) var(--tblr-btn-padding-x);gap:7px}.heading-actions .sd-dialog .btn .icon{margin:0 calc(var(--tblr-btn-padding-x)/ 2) 0 calc(var(--tblr-btn-padding-x)/ -4)}}

/* Part 6b spec M3а: the Telegram link by mail - the card's lines. */
.people-telegram-mailed{color:var(--muted)}
/* the profile's addresses (part 6b spec M5): each with what it gets and «Присылать сюда»; one no letter reaches, grey */
.profile-addresses-hint{margin-top:4px}
.profile-address{overflow-wrap:anywhere}
.profile-address-switch{display:flex;align-items:center;gap:8px;flex-shrink:0}
.profile-address-switch>small{font-size:12px;color:var(--muted);white-space:nowrap}
/* on a phone «Присылать сюда» is said once in the hint above the list - each address gets the row's width (its review
   finding: addresses broken mid-word); the word stays for a screen reader */
@media (max-width:480px){.profile-address-switch>small{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}}
/* whether an address is on and who switched it on (the owner, 2026-09-29: opt-in) */
.profile-address-state{font-size:12px;color:var(--muted)}
.profile-address-state.is-on{color:var(--green)}
.profile-mail-optin{margin-top:0}
/* People's card: every address of the employee and whether it receives letters (part 6b spec M5), read-only */
.people-mail-addresses{list-style:none;margin:0 0 8px;padding:0}
.people-mail-addresses>li{display:flex;flex-direction:column;gap:2px;padding:6px 0;border-bottom:1px solid var(--line);min-width:0}
.people-mail-addresses>li:last-child{border-bottom:0}
.people-mail-addresses .people-email{overflow-wrap:anywhere}
.people-mail-addresses>li[data-receives="no"] .people-email{color:var(--muted)}
.people-mail-scope{font-size:12px}
/* an administrator's «Присылать сюда» at the right of each address (the owner, 2026-09-29) */
.people-mail-address-head{display:flex;align-items:center;justify-content:space-between;gap:8px;min-width:0}
.people-mail-address-head .people-email{min-width:0}
.people-mail-address-head .people-mail-switch{flex-shrink:0;font-size:12px;color:var(--muted)}

/* «Сводки» (spec 2026-09-29 G1, G6). The two tabs of Settings → Notifications are links (each a page): the prototype's
   `.page-tabs` drawn for `<a>` as it draws its buttons. */
.notify-page-tabs a{padding:0 2px 13px;border-bottom:2px solid transparent;color:var(--muted);text-decoration:none;display:flex;gap:8px;align-items:center}
.notify-page-tabs a.active{color:var(--accent);border-color:var(--accent)}
.notify-page-tabs a:focus-visible{outline-offset:-2px;border-radius:4px}
/* Six tabs since 2026-10-06 («Получатели» and «Журнал» apart). Where they do not fit one line - a phone, or a narrow
   window where the row stands beside the Settings menu (341 px of it at a 768 px screen) - the row wraps onto a second
   line, never scrolls sideways as the prototype's `.page-tabs` does on a phone: each tab is a page of its own, so a
   scrolling row came back at its left edge after every tab and hid the very tab just opened («Журнал» at 375 and
   768 px, «Получатели» at 768), with nothing on a phone to show that the row scrolls. Wrapped, every tab is in sight
   and the current one underlined; a label itself never breaks. */
.notify-page-tabs{flex-wrap:wrap;row-gap:10px;overflow:visible}
.notify-page-tabs a{white-space:nowrap}
@media (max-width:760px){.notify-page-tabs a{font-size:12px}}
.digests-card .card-heading,.mailing-card .card-heading,.mailing-check-card .card-heading{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;flex-wrap:wrap}
.mailing-back{display:inline-block;font-size:12px;color:var(--muted);margin-bottom:4px;text-decoration:none}
.mailing-back:hover{color:var(--accent)}
.digests-table td small{display:block;font-size:11px;color:var(--muted);margin-top:4px}
/* The list fits the card of a window from 1100 px (627 px inside it) with no sideways scroll: tight cells, and the three
   actions one under another in a narrow last column (a delete error under them, as wide as they are). Only on a phone
   (760 px and less) the tables keep a readable width and scroll inside their card instead of squeezing. */
.digests-table thead th,.digests-table td{padding:12px 10px}
.digests-table td:nth-child(2){width:32%}
.digests-table td:last-child{width:1%}
.mailing-actions{flex-direction:column;flex-wrap:nowrap;align-items:stretch;gap:6px}
.mailing-actions .btn{justify-content:center}
.mailing-actions .setting-error{display:block;max-width:120px;color:var(--red);font-size:12px;overflow-wrap:anywhere}
.mailing-journal thead th,.mailing-journal td{padding:10px}
@media (max-width:760px){
  .digests-table{min-width:640px}
  .mailing-recipients{min-width:520px}
  .mailing-journal{min-width:560px}
}
.alert.mailing-shared{display:block}
.mailing-shared>strong{display:block}
.mailing-shared ul{margin:6px 0 4px;padding-left:18px;overflow-wrap:anywhere}
.mailing-shared small{display:block;font-size:12px}
/* the editor: sections one under the other; a section's fields side by side while they fit, one under another on a phone */
.mailing-editor small.setting-error{display:block;color:var(--red);font-size:12px;margin-top:5px}
.mailing-editor .form-label{display:flex;flex-direction:column;gap:6px;font-size:13px;min-width:0}
.mailing-editor .form-label[hidden]{display:none}
.mailing-editor small.muted{font-size:12px;line-height:1.4}
.mailing-row{display:flex;flex-wrap:wrap;gap:16px 28px;align-items:flex-start;margin-bottom:8px}
.mailing-name{flex:1 1 280px}
.mailing-switch{display:flex;gap:10px;align-items:flex-start;flex:1 1 240px;margin-top:22px}
.mailing-switch small{display:block;margin-top:3px}
.mailing-section{border:0;border-top:1px solid var(--line);margin:18px 0 0;padding:16px 0 0;min-width:0}
.mailing-section>legend{float:none;width:auto;font-size:14px;font-weight:600;margin:0 0 10px;padding:0}
.mailing-statuses{display:flex;flex-direction:column;gap:6px;margin-bottom:14px}
.mailing-checks{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:4px 16px;margin-top:4px}
.mailing-checks .form-check{margin:0;min-width:0;overflow-wrap:anywhere}
.mailing-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:14px 18px;margin-bottom:10px}
.mailing-mode{margin-top:14px;max-width:520px}
/* the letters as they go: a white sheet in a frame (sandboxed - the letter's own HTML), its subject and addresses above */
.mailing-letter{margin:14px 0 0;min-width:0}
.mailing-letter h4{font-size:13px;margin:0 0 6px}
.mailing-letter-head{display:flex;flex-wrap:wrap;gap:4px 16px;font-size:12px;color:var(--muted);margin:6px 0;overflow-wrap:anywhere}
.mailing-letter-frame{display:block;width:100%;height:360px;border:1px solid var(--line);border-radius:6px;background:#fff}
details.mailing-letter{border:1px solid var(--line);border-radius:6px;padding:10px 12px}
details.mailing-letter>summary{cursor:pointer;font-size:13px;overflow-wrap:anywhere}
details.mailing-letter>summary small{display:block;font-size:12px;color:var(--muted);margin-top:3px}
/* the check */
.mailing-check h3{font-size:14px;margin:22px 0 10px}
.mailing-totals{display:flex;flex-wrap:wrap;gap:12px 36px;margin:0 0 6px}
.mailing-totals>div{display:flex;flex-direction:column}
.mailing-totals dt{font-size:12px;font-weight:400;color:var(--muted)}
.mailing-totals dd{font-size:26px;font-weight:500;margin:0}
.mailing-totals>div[data-gaps]:not([data-gaps="0"]) dd{color:var(--red)}
.mailing-by-kind{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap;gap:6px 22px;font-size:13px}
.mailing-recipients td{overflow-wrap:anywhere}
.mailing-gaps{list-style:none;padding:0;margin:0}
.mailing-gaps>li{padding:10px 0;border-bottom:1px solid var(--line);font-size:13px}
.mailing-gaps>li:last-child{border-bottom:0}
.mailing-gaps>li>small{display:block;font-size:12px;color:var(--muted);margin-top:4px;overflow-wrap:anywhere}
.mailing-gaps .number-badge{margin-left:8px}
.mailing-gap-tickets{margin:6px 0 0;padding-left:18px;font-size:12px}
.mailing-send{margin:22px 0 6px;padding:16px 0 0;border-top:1px solid var(--line)}
.mailing-send>small{display:block;font-size:12px;margin-top:8px}
.mailing-send-status{min-height:1.4em;margin:8px 0 0;font-size:13px}
.mailing-send-status.is-ok{color:var(--green)}
.mailing-send-status.is-error{color:var(--red)}
.mailing-letters{display:flex;flex-direction:column;gap:10px}
/* the journal: each letter a line with its delivery */
.mailing-journal td>small{display:block;font-size:11px;color:var(--muted);margin-top:4px}
.mailing-journal-letters{list-style:none;padding:0;margin:0}
.mailing-journal-letters>li{padding:4px 0;font-size:12px;overflow-wrap:anywhere}
.mailing-journal-letters>li>small{display:block;color:var(--muted)}
.mailing-journal-letters .neutral-badge{margin-top:3px}
.mailing-journal-letters .neutral-badge.is-ok,.mailing-journal td>.neutral-badge.is-ok{color:var(--green);border-color:var(--green)}
.mailing-journal-letters .neutral-badge.is-error,.mailing-journal td>.neutral-badge.is-error{color:var(--red);border-color:var(--red)}
.mailing-journal td>.neutral-badge{margin-bottom:4px}
.mailing-journal-planned{display:block;font-size:12px;color:var(--muted)}

/* Settings save in the background, no "Save" (the owner, 2026-09-30; src/lib/autosave.ts): the one status line beside a
   card's heading (src/components/settings/AutosaveStatus.tsx, SettingsCard.tsx) - quiet grey before a change, a small
   spinner while saving, green "Saved" with its note, red "Not saved: …". On a phone it drops under the heading. */
.settings-card-heading{align-items:flex-start;flex-wrap:wrap}
.autosave-status{margin:0;display:flex;flex-direction:column;align-items:flex-end;gap:2px;font-size:12px;line-height:1.4;color:var(--muted);max-width:min(100%,380px);text-align:right;min-height:20px}
.autosave-line{display:inline-flex;align-items:center;gap:6px}
.autosave-status .icon{width:16px;height:16px}
.autosave-status small{display:block;font-size:12px;color:var(--muted)}
.autosave-status small.is-warn{color:var(--orange)}
.autosave-status.is-saved .autosave-line{color:var(--green)}
.autosave-status.is-error .autosave-line{color:var(--red)}
.autosave-spinner{flex-shrink:0;width:12px;height:12px;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:autosave-spin .8s linear infinite}
@keyframes autosave-spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.autosave-spinner{animation:none}}
@media (max-width:600px){.autosave-status{align-items:flex-start;text-align:left;max-width:100%;flex-basis:100%}}
.sla-rule-dialog .sla-editor-status{margin-right:auto;display:flex;align-items:center}
/* A refusal in a long card (a form, a matrix, a year of holidays) stays in sight (review of 2026-09-30): while the
   card's heading is scrolled out of the window its line floats at the bottom, red on the page's surface; a click brings
   the heading back (SettingsCard.tsx). As wide as its words, up to the screen less 16 px a side: placed from the
   middle, it was given half the screen at most (its width fitted to the room right of `left:50%`), and a long refusal
   - «Не перемещено: …» of the KPI indicators' order - stood seven lines tall over a third of a phone's screen (review
   refusal-line-out-of-sight). */
.autosave-float{position:fixed;left:50%;bottom:16px;transform:translateX(-50%);z-index:100;display:inline-flex;align-items:center;gap:8px;width:max-content;max-width:calc(100vw - 32px);padding:10px 14px;border:1px solid var(--red);border-radius:8px;background:var(--surface);color:var(--red);font:inherit;font-size:13px;line-height:1.4;text-align:left;box-shadow:0 8px 35px #0002;cursor:pointer}
.autosave-float .icon{flex-shrink:0;width:16px;height:16px}
/* Settings → Notifications save in the background too (the owner, 2026-09-30, item 5): a digest's heading holds the way
   back and the name, the status line and «Проверить и отправить» - the line beside the button. */
.mailing-card .settings-card-heading>.autosave-status{margin-left:auto}
.sync-log-footer [aria-disabled="true"]{opacity:.55;cursor:default}
.tenant-alias .setting-error{display:block;color:var(--red);font-size:12px;margin-top:4px}
/* Settings → Forms: the form picker above the chosen form's card (the owner's item 12 of 2026-09-30;
   src/components/settings/FormPicker.tsx) - the caption and the list you can type into, as wide as a long form name. */
.forms-picker{margin:0 0 16px}
.forms-picker .search-select>label{display:block;font-size:12px;color:var(--muted);margin-bottom:5px}
.forms-picker-field{width:min(100%,460px)}
/* Settings → Forms: «Подключить форму» and a draft's card (service-forms spec 2026-10-07 §11.1-§11.2, slice S4;
   src/components/settings/ConnectFormCard.tsx, DraftCard.tsx). The picker and «Подключить форму» on one line (the button
   under the picker when there is no room); the connect card: the tenants as a segmented choice under `/all`,
   «Читаем из Pyrus…» with the autosave's spinner, the list of forms - number, name, steps, fields, the choice at the
   right; on a phone the steps and fields under the name -, «Номер формы» under it; the draft: the facts as
   `.split-line` rows, the register's numbers as small tiles, the steps and the folded fields as the class tables are. */
.forms-toolbar{display:flex;align-items:flex-end;gap:12px 16px;flex-wrap:wrap;margin:0 0 16px}
.forms-toolbar .forms-picker{margin:0;flex:0 1 460px;min-width:0}
.forms-toolbar .forms-picker-field{width:100%}
.forms-connect-button{white-space:nowrap}
.forms-connect-button .icon{width:15px;height:15px}
.form-connect-lead{font-size:12px;margin:0 0 18px;max-width:680px}
.form-connect-tenants{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin:0 0 18px;font-size:12px;color:var(--muted)}
.form-connect-tenants>span{margin-right:6px}
.form-connect-tenants a{padding:6px 12px;border:1px solid var(--line);border-radius:6px;color:var(--ink);text-decoration:none;font-size:13px;background:var(--surface)}
.form-connect-tenants a.active{color:var(--accent);border-color:var(--accent);background:var(--accent-soft);font-weight:600}
.pyrus-reading{display:flex;align-items:center;gap:8px;color:var(--muted);font-size:13px;margin:4px 0 16px}
.form-connect-problem{display:block;margin:0 0 16px}
.form-connect-problem p{margin:0}
.form-connect-problem p+.btn{margin-top:10px}
.form-connect-listed{display:flex;align-items:center;justify-content:space-between;gap:8px 16px;flex-wrap:wrap;margin:0 0 10px;font-size:12px}
.form-connect-table td{padding:12px 14px}
.form-connect-id{white-space:nowrap;color:var(--muted)}
.form-connect-count{text-align:right;white-space:nowrap;width:1%}
.form-connect-table td>small.form-connect-counts{display:none}
.form-connect-action{text-align:right;white-space:nowrap;width:1%}
.form-connect-action a{font-size:12px}
.form-connect-table tr.is-taken td{color:var(--muted)}
.form-connect-table tr.is-taken td>strong{color:var(--muted)}
.form-connect-hidden{font-size:12px;margin:8px 0 0}
.form-connect-number{margin-top:22px;max-width:420px}
.form-connect-number>label{display:block;font-size:12px;color:var(--muted);margin-bottom:5px}
.form-connect-number-row{display:flex;gap:8px}
.form-connect-number-row .form-control{max-width:200px}
.form-connect-number small{display:block;font-size:12px;margin-top:5px}
.form-connect-number small.setting-error{color:var(--red)}
.form-connect-fallback{font-size:13px;margin:0 0 10px}
@media(max-width:600px){
  .form-connect-table th.form-connect-count,.form-connect-table td.form-connect-count{display:none}
  .form-connect-table td>small.form-connect-counts{display:block;font-size:11px;color:var(--muted);margin-top:3px}
  .form-connect-table td{padding:10px 8px}
  .form-connect-number-row .form-control{max-width:none;flex:1}
}
.form-draft-note{margin:0 0 22px}
.form-draft-controls{margin:0 0 18px}
.form-draft-card h3{font-size:14px;font-weight:600;margin:0 0 8px}
.form-draft-facts,.form-draft-summary,.form-draft-steps{margin:0 0 24px}
.form-draft-numbers{display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:10px}
.form-draft-numbers>div{border:1px solid var(--line);border-radius:7px;padding:12px 14px;display:flex;flex-direction:column;gap:3px;min-width:0}
.form-draft-numbers strong{font-size:22px;font-weight:600;letter-spacing:-.3px;line-height:1.2}
.form-draft-numbers span{font-size:12px;color:var(--muted)}
.form-draft-step-table td{padding:10px 12px}
.form-draft-fields{margin-top:0}
.draft-editor+.form-draft-fields{margin-top:22px}
.form-draft-field.depth-1{padding-left:28px}
.form-draft-field.depth-2{padding-left:44px}
.form-draft-field.depth-3{padding-left:60px}
.form-draft-choices{font-size:12px;min-width:160px}
@media(max-width:600px){.form-draft-choices{min-width:0}.form-draft-card .form-field-table td{padding:8px 6px}.form-draft-card .form-field-table td.depth-1{padding-left:18px}.form-draft-card .form-field-table td.depth-2{padding-left:28px}.form-draft-card .form-field-table td.depth-3{padding-left:38px}}
/* Settings → KPI periods (src/app/[tenant]/settings/kpi/PeriodPicker.tsx). The indicators table scrolls sideways in its
   box wherever the card is narrower than it - a laptop's too (the owner's screenshot of 2026-10-07: the scrollbar lay
   over the line «Сумма весов активных…» under it). Where scrollbars overlay the content (macOS, phones) the bar is drawn
   over the box's bottom edge, where one takes room it was glued to that line: the box keeps room inside for the bar,
   under the last row, and a gap after it. The list of the year shows a choice at once (no "Show", the owner's
   2026-10-07); without JavaScript its button, in <noscript>, stands in the row beside the lists, not on a line of its
   own (never `display` here: with JavaScript the browser shows a <noscript>'s markup as text unless hidden). While the
   chosen year loads, the card under the lists dims. */
.kpi-settings-body>.table-responsive{padding-bottom:12px;margin-bottom:12px;container:kpi-indicators/inline-size}
.kpi-period-form>noscript{width:auto}
.kpi-settings-body[aria-busy="true"]>:not(.kpi-period-form){opacity:.55;pointer-events:none}
/* The order of the year's indicators (the owner, 2026-10-08; src/app/[tenant]/settings/kpi/IndicatorTable.tsx): the
   table's first cell is the row's place and its arrows, as the SLA matrix's rules have them (the up arrow is the down
   one turned); where an arrow is not there - «Выше» of the first row, «Ниже» of the last - its room is kept, so the
   arrows of every row stand in two columns. While a move runs - until the table is drawn again in its order - the
   arrows are busy, not disabled (the focus stays), and look it, as the SLA matrix's do. A refusal of a move is one red
   line above the table; empty, it takes no room - an empty block, not a hidden one: the live region is there before it
   speaks, and the float of its words (src/components/settings/AutosaveFloat.tsx) knows from the start whether the line
   is in the window, so it does not flash up for a frame while the line comes in. The arrow a move leaves the focus on
   is brought into sight (IndicatorTable.tsx) clear of that float at the window's bottom (`scroll-margin-bottom`, review
   refusal-line-out-of-sight): the longest refusal, «Не перемещено: …», floats 56 px tall with its gap on a laptop, 74 at
   768-1280 px, 129 at 375 px and some 165 at 320 px. */
.kpi-indicators-table td.kpi-order{width:1%;white-space:nowrap}
.kpi-order>span:first-child{display:inline-block;min-width:18px;text-align:right;margin-right:4px}
.kpi-order .icon-button,.kpi-order-gap{width:28px;height:28px;vertical-align:middle}
.kpi-order .icon-button{scroll-margin-bottom:112px}
@media (max-width:600px){.kpi-order .icon-button{scroll-margin-bottom:168px}}
.kpi-order-gap{display:inline-block}
.kpi-order .icon-button .icon{width:16px;height:16px}
.kpi-order-up .icon{transform:rotate(180deg)}
.kpi-order [aria-disabled="true"]{opacity:.55;cursor:progress}
.kpi-order-status{margin:0 0 8px;font-size:12px}
.kpi-order-status:empty{margin:0}
.kpi-order-status.is-error{color:var(--red)}
/* The order's cell (86 px) took the table of the owner's five indicators to 996 px in Russian, past its box on the
   owner's 1512 px laptop with the sidebar open (953-968 px): the table scrolled sideways and «Удалить» was cut, where
   without the cell (910 px) it fitted (review order-column-overflows-1512). In a box narrower than 1040 px «Изменить» and
   «Удалить» stand one under the other and so do the two arrows: 902 px in Russian, 895 in English - less than before
   the order was there; the rows there are already taller than both, the names wrapped. In a wider box, where the table
   fits with them side by side (996 px in Russian, 954 in English), they stay side by side: in a flex row that may wrap
   the table's own sizing would give the buttons less than their line long before the table runs out of room, and stack
   them on a wide screen too. The box is the size container (`.kpi-settings-body>.table-responsive` above). */
.kpi-order-arrows{display:inline-flex;vertical-align:middle}
@container kpi-indicators (max-width:1039px){.kpi-indicator-actions{flex-wrap:wrap}.kpi-order-arrows{flex-direction:column}}
/* The KPI of the "All tenants" mode (spec 2026-09-23 D6, src/components/kpi/KpiAllScreen.tsx): every tenant's report in a
   block of its own, one under the other, parted by a rule; its heading names the tenant (a tag) and ends with "Open this
   tenant". The style switch and the PDF sit together in the page heading. */
.kpi-tenant-block{border-top:1px solid var(--line);margin-top:30px;padding-top:4px}
.kpi-all .kpi-tenant-block:first-of-type{border-top:0;margin-top:0;padding-top:0}
.kpi-tenant-block .kpi-indicator-heading h2{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.kpi-tenant-block .kpi-indicator-heading .tenant-tag{font-size:12px;padding:2px 8px}
.kpi-tenant-open{flex-shrink:0;white-space:nowrap}
.kpi-all-heading-tools{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
/* The heading holds two controls here (the style switch and PDF): it wraps as Tasks' does (`.my-heading` above), the
   controls taking a row of their own below the title on a narrow screen. */
@media(max-width:900px){.kpi-all-heading{flex-wrap:wrap}}
@media(max-width:760px){.kpi-tenant-open{margin-left:auto}.kpi-all-heading .heading-actions{width:100%;justify-content:space-between}}
/* The KPI indicator cards (src/components/kpi/KpiCards.tsx; the owner, 2026-10-08: «ты можешь сделать, чтобы 5 кнопок
   помещалось на странице KPI, сейчас только 4 без прокрутки … у меня на ноутбуке разрешение 1512 на 982»). The
   prototype's row (`.kpi-indicator-row`, styles.css) kept every card in one line of cards at least 272 px wide and
   scrolled it sideways once they did not fit - from a fifth card on at that laptop's width. The cards take 220 px at
   least now, so five stand in one row in a 1512 px window with the sidebar open (≈1210 px for the page), and where they
   do not fit - a narrower window, more cards - they wrap onto the next row instead of scrolling: one card a row on a
   phone, the width of the screen. A card keeps its subgrid - its code, title and figure aligned with its neighbours' -
   with no gap between its own three rows, the rows of cards apart by the grid's gap. Under the old 272 px the three
   reference values of a card with their units («4,80 / 5,00  4,90 / 5,00  5,00 / 5,00») no longer fit side by side and
   ran into each other: there they drop the unit - the card's own figure above says it - and keep the number. The width
   is asked of the card's figure block (`.metric-display`), not of the card: a size container cannot be a subgrid. On a
   phone a title takes the room of its own lines (the prototype's own 760 px rule, which the row's three-line reserve
   outranked while the cards stood in one scrolling line - the grid's rows align the titles of a row by themselves).
   The dial of the Gauge view shrinks with its figure; its value at the centre did not (styles.css: 32 px, the unit
   15 px), so under the old card's 234 px of figure a marker lying flat at either end of the scale - 100 %, «145,50 мин»
   - ran into the value, and a long value over the arc (review K70-DIAL-1). There the value and its unit shrink with the
   figure, in the proportions they have in 234 px (32 / 234 ≈ 13.5 %, 15 / 234 ≈ 6.4 % of its width - `cqi` of the
   figure, the size container): 31.5 px at 233 px, 24.6 px in the narrowest card's 182 px. A fixed smaller size
   (26 px) still met the marker in cards of 220-225 px, the unit not shrinking with the dial. */
.kpi-quality-grid.kpi-indicator-row{grid-auto-flow:row;grid-template-columns:repeat(auto-fit,minmax(min(100%,220px),1fr));grid-template-rows:none;grid-auto-columns:auto;overflow:visible;overscroll-behavior-x:auto;padding-bottom:0;row-gap:14px}
.kpi-indicator-row>.card{row-gap:0}
.kpi-indicator-row .metric-display{container:kpi-figure/inline-size}
@container kpi-figure (max-width:233px){.metric-reference-values small{display:none}.kpi-quality-grid .metric-dial .gauge-value{font-size:13.5cqi}.kpi-quality-grid .metric-dial .gauge-value>small{font-size:6.4cqi}}
@media (max-width:760px){.kpi-indicator-row .metric-gauge .kpi-indicator-title{min-height:0}}
/* People → "Import e-mails" (the owner, 2026-10-01; src/components/people/EmailImport.tsx): the file step, the preview -
   the totals in a row of tiles, a row per person of the file with whom it is and what happens to each address - and the
   result. Colors are the tokens: green - will be added, orange - not found or a choice to make, red - a conflict. On a
   phone the table turns into cards (each cell under its own caption), so no address is cut and nothing scrolls sideways. */
.people-import-link{flex-shrink:0;white-space:nowrap}
.import-heading{flex-wrap:wrap}
.import-heading .btn{flex-shrink:0;white-space:nowrap}
.import-card{margin-bottom:22px;transition:opacity .15s}
.import-card[aria-busy="true"]{opacity:.55;pointer-events:none}
@media (prefers-reduced-motion:reduce){.import-card{transition:none}}
.import-how{margin:0 0 18px;font-size:13px;max-width:860px}
.import-source{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px 20px;margin-bottom:18px;align-items:start}
.import-source .form-label{font-size:13px;font-weight:500}
.import-source textarea{font-size:13px;min-height:132px}
.import-card .alert{font-size:13px;margin-bottom:14px}
.import-card .form-hint{font-size:12px;color:var(--muted);margin:12px 0 0}
.import-hint{font-size:12px;color:var(--muted)}
small.import-hint{display:block;margin-top:4px}
.import-totals{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:10px;margin:0;padding:4px 20px 16px}
.import-totals>div{border:1px solid var(--line);border-radius:8px;padding:10px 12px;min-width:0}
.import-totals dt{font-size:12px;font-weight:400;color:var(--muted);overflow-wrap:anywhere}
.import-totals dd{margin:2px 0 0;font-size:22px;font-weight:600;font-variant-numeric:tabular-nums;line-height:1.2}
.import-totals .is-add dd{color:var(--green)}
.import-totals .is-conflict dd{color:var(--red)}
.import-totals .is-missing dd{color:var(--orange)}
.import-skipped{margin:0;padding:0 20px 12px;font-size:12px;color:var(--muted)}
.import-table{margin:0}
.import-table td{vertical-align:top;padding:14px 20px}
.import-table .import-name{font-weight:500;overflow-wrap:anywhere;min-width:150px;width:18%}
.import-table .import-person{min-width:220px;width:32%}
.import-table .import-person>strong{font-weight:500;overflow-wrap:anywhere}
.import-missing{color:var(--orange);background:var(--orange-soft);border-color:transparent}
.import-choice{border:0;margin:0;padding:0;min-width:0;display:grid;gap:6px}
.import-choice legend{float:none;width:auto;margin:0 0 2px;padding:0;font-size:12px;font-weight:500;color:var(--orange)}
.import-option{display:flex;align-items:flex-start;gap:8px;margin:0;font-size:13px;cursor:pointer}
.import-option .form-check-input{float:none;flex-shrink:0;margin:2px 0 0}
.import-option>span{min-width:0;overflow-wrap:anywhere}
.import-addresses{list-style:none;margin:0;padding:0;display:grid;gap:6px}
.import-address{display:flex;flex-wrap:wrap;align-items:center;gap:3px 8px;font-size:13px}
.import-address .people-email{font-weight:500}
.import-note{font-size:12px;color:var(--muted);overflow-wrap:anywhere}
.import-add{color:var(--green);background:var(--green-soft);border-color:transparent;margin-left:0}
.import-address.is-present .people-email,.import-address.is-idle .people-email,.import-address.is-invalid .people-email{font-weight:400;color:var(--muted)}
.import-address.is-conflict .import-note,.import-address.is-repeated .import-note,.import-reason.is-conflict,.import-reason.is-repeated,.import-reason.is-failed{color:var(--red)}
.import-address.is-invalid .people-email{text-decoration:line-through}
.import-reason{font-size:12px;color:var(--muted)}
.import-reason.is-not-found,.import-reason.is-stale,.import-reason.is-skipped,.import-reason.is-unsent{color:var(--orange)}
.import-chosen{display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px;margin:8px 0 0}
.import-chosen .btn{flex:0 0 auto}
.import-footer{border-top:1px solid var(--line)}
.import-table tbody tr:last-child td{border-bottom:0}
.import-letters{margin:0 0 14px;font-size:12px;color:var(--muted);max-width:860px}
.import-subtitle{margin:18px 0 8px;font-size:14px;font-weight:600}
.import-done{list-style:none;margin:0;padding:0}
.import-done>li{display:flex;flex-wrap:wrap;align-items:center;gap:3px 10px;padding:9px 0;border-bottom:1px solid var(--line);font-size:13px}
.import-done>li>a{font-weight:500}
.import-done .neutral-badge{margin-left:0}
.import-skipped-table td{padding-left:0}
.import-skipped-table th:first-child{padding-left:0}
.import-result-actions{margin-top:20px}
@media(max-width:760px){
  .import-source{grid-template-columns:minmax(0,1fr)}
  .import-totals{grid-template-columns:repeat(2,minmax(0,1fr));padding:4px 15px 14px}
  .import-skipped{padding-left:15px;padding-right:15px}
  .import-table thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
  .import-table,.import-table tbody,.import-table tr,.import-table td{display:block;width:auto;min-width:0}
  .import-table tr{padding:12px 15px;border-bottom:1px solid var(--line)}
  .import-table tbody tr:last-child{border-bottom:0}
  .import-table td,.import-table .import-name,.import-table .import-person{padding:0 0 8px;border-bottom:0;min-width:0;width:auto}
  .import-table td:last-child{padding-bottom:0}
  .import-table td[data-label]::before{content:attr(data-label);display:block;font-size:11px;color:var(--muted);font-weight:400;margin-bottom:2px}
  .import-skipped-table tr{padding-left:0;padding-right:0}
  .import-card .button-row .btn{flex:1 1 auto}
}
@media (pointer:coarse){.import-source textarea,.import-source input{font-size:16px}}
/* Settings → Services (service-forms spec 2026-10-07 §12.4, slice S5): «Создать группу», each group - its name with
   «группа», its tickets, «Переименовать» / «Удалить группу», its notes, its members, «Добавить в группу» - and the services
   in no group. A member and a service in no group are one kind of row: the name, a line of what it is with its numbers,
   the warning and the notes; on a phone the same rows stack, nothing scrolls sideways. */
.services-since{margin:0 0 14px;font-size:12px}
.service-create{max-width:640px;margin:0 0 6px}
.service-create-row{display:flex;gap:8px;align-items:center}
.service-create-row .form-control{flex:1 1 auto;min-width:0}
.service-create-row .btn{flex:0 0 auto}
.service-status{margin:6px 0 0;font-size:12px;color:var(--muted)}
.service-status:empty{display:none}
.service-status.is-ok{color:var(--green)}
.service-status.is-error{color:var(--red)}
.services-subtitle{margin:22px 0 10px;font-size:14px;font-weight:600}
.services-hint{margin:-4px 0 10px;font-size:12px;max-width:860px}
.service-none{margin:0 0 12px;font-size:13px}
.service-group{border:1px solid var(--line);border-radius:8px;padding:14px 16px;margin:0 0 14px;background:var(--surface)}
.service-group-head{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:8px 16px}
.service-group-title{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px;min-width:0}
.service-group-title h3{margin:0;font-size:15px;font-weight:600;overflow-wrap:anywhere}
.service-group-title .number-badge{margin-left:0}
.service-group-actions{display:flex;flex-wrap:wrap;gap:6px}
.service-group-delete{color:var(--red)}
.service-group-rename{display:flex;flex-wrap:wrap;align-items:center;gap:6px;flex:1 1 320px;min-width:0}
.service-group-rename .form-control{flex:1 1 220px;min-width:0}
.service-rename-note{flex:1 0 100%;margin:2px 0 0;font-size:12px;color:var(--orange);display:flex;gap:6px;align-items:flex-start}
.service-rename-note .icon{width:16px;height:16px}
.service-group-members{margin:10px 0 4px;font-size:12px;font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.3px}
.service-list{list-style:none;margin:0 0 6px;padding:0}
.service-item{display:flex;align-items:flex-start;gap:10px;padding:9px 0;border-bottom:1px solid var(--line)}
.service-item:last-child{border-bottom:0}
.service-item-main{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1 1 auto}
.service-item-name{font-weight:500;overflow-wrap:anywhere}
.service-item-meta{font-size:12px;color:var(--muted)}
.service-item-warning{display:flex;gap:5px;align-items:center;font-size:12px;color:var(--orange)}
.service-item-warning .icon{width:15px;height:15px}
.service-item-quiet{font-size:12px;color:var(--muted)}
.service-item-remove{flex:0 0 auto}
.service-notes{list-style:none;margin:4px 0 0;padding:0;font-size:12px;color:var(--muted)}
.service-notes>li{display:flex;gap:6px;align-items:flex-start}
.service-notes .icon{width:15px;height:15px;margin-top:1px}
.service-group-notes{margin:2px 0 4px}
.service-group-add{display:flex;flex-wrap:wrap;align-items:flex-end;gap:8px;margin-top:8px}
.service-group-add-field{flex:1 1 280px;min-width:0;max-width:520px}
.service-group-add-go{flex:0 0 auto;min-height:36px}
.services-ungrouped{border:1px solid var(--line);border-radius:8px;padding:0 16px;background:var(--surface)}
.settings-tenant-picker{display:flex;align-items:center;gap:10px;margin:0 0 16px}
.settings-tenant-picker .form-label{margin:0}
.settings-tenant-picker .form-select{width:auto;min-width:180px}
@media(max-width:760px){
  .service-group{padding:12px}
  .service-create-row{flex-wrap:wrap}
  .service-create-row .btn{flex:1 1 auto}
  .services-ungrouped{padding:0 12px}
}

/* A draft's card of Settings → Forms, slice S6 (service-forms spec 2026-10-07 §11.2-§11.4; src/components/settings/
   DraftEditor.tsx, DraftPreview.tsx, FirstLoad.tsx): the three steps as a numbered line each; a section a block - its title,
   the line «где это видно» with the info icon, its table or switches; the marks beside a value («по подсказке» muted,
   «не узнано — проверьте» and «проверьте» orange, «новое в Pyrus» the accent, «нет в Pyrus» red); a closing status's row
   tinted; the robots as checkable rows; the preview's tiles as the register's; the buttons in a bar under the preview; the
   first load's progress as a thin bar. Tokens only, so both themes follow; at 375 px the tables scroll inside themselves
   and the bar's buttons wrap. */
.draft-howto{margin:0 0 22px;padding:12px 16px 12px 34px;background:var(--canvas);border-radius:7px;font-size:13px;line-height:1.55}
.draft-howto li+li{margin-top:4px}
.draft-editor{margin-top:6px}
.draft-section{margin:0 0 30px}
.form-draft-card .draft-section>h3,.form-card .draft-section>h3{font-size:15px;font-weight:600;margin:0 0 4px}
.draft-where{display:flex;gap:6px;align-items:flex-start;font-size:12px;color:var(--muted);margin:0 0 12px;max-width:760px}
.draft-where .icon{width:14px;height:14px;margin-top:2px}
.draft-mark{display:flex;gap:5px;align-items:flex-start;font-size:11.5px;margin-top:5px;color:var(--muted);line-height:1.4}
.draft-mark .icon{width:13px;height:13px;flex-shrink:0;margin-top:1px}
.draft-mark.is-unknown,.draft-mark.is-check{color:var(--orange)}
.draft-mark.is-new{color:var(--accent)}
.draft-mark.is-gone{color:var(--red)}
.draft-mark-why{color:var(--muted)}
.draft-problems{margin:8px 0 0}
.draft-problems small.setting-error{display:block;color:var(--red);font-size:12px;margin-top:4px}
.draft-field{display:block;max-width:520px;margin:0 0 12px}
.draft-field>span{display:block;font-size:12px;color:var(--muted);margin-bottom:5px}
.draft-field-facts{display:block;font-size:11.5px;color:var(--muted);margin-top:4px}
.draft-choice{border:0;padding:0;margin:0 0 12px;display:flex;flex-direction:column;gap:9px}
.draft-choice legend{font-size:12px;color:var(--muted);margin:0 0 2px;float:none;padding:0}
.draft-choice>label{display:flex;gap:9px;align-items:flex-start;font-size:13px;flex-wrap:wrap}
.draft-choice>label>input[type=radio]{margin-top:3px}
.draft-choice>label>span strong{display:block;font-weight:500}
.draft-choice>label>span small{display:block;font-size:12px}
.draft-inline-select,.draft-inline-input{flex:1 1 220px;max-width:340px;margin-top:-4px}
.draft-table td{padding:10px 12px;vertical-align:top}
.draft-table td>strong+small,.draft-fields-table td:first-child small{display:block;margin-top:3px;font-size:11.5px}
.draft-fields-table td:first-child{width:38%}
.draft-fields-table .form-select{min-width:220px;max-width:420px}
.draft-subject{display:flex;flex-direction:column;gap:8px}
.draft-subject>small{font-size:11.5px}
/* A field of a subject built of several (the owner, 2026-10-11): its choice with «выше», «ниже», «убрать» beside it. */
.draft-subject-pick{display:flex;gap:4px;align-items:center;max-width:620px}
.draft-subject-pick>.form-select{flex:1 1 auto;min-width:0}
.draft-subject-moves{display:flex;gap:2px;flex-shrink:0}
.draft-subject-moves .btn-icon{width:30px;min-height:30px;padding:0}
/* On a phone the field's choice takes the whole row and its buttons go under it (review of 2026-10-11). */
@media (max-width:575.98px){.draft-subject-pick{flex-wrap:wrap}.draft-subject-pick>.form-select{flex-basis:100%}}
.draft-numbers-line{font-size:12px;color:var(--muted);margin:2px 0 0;max-width:760px}
.draft-warning{display:flex;gap:6px;align-items:flex-start;font-size:12px;color:var(--orange);margin:10px 0 0;max-width:760px}
.draft-warning .icon{width:14px;height:14px;flex-shrink:0;margin-top:2px}
.draft-note{font-size:12px;color:var(--muted);margin:10px 0 0;max-width:760px}
.draft-always{display:flex;gap:6px;align-items:center;font-size:13px;margin:0 0 4px;color:var(--green)}
.draft-always .icon{width:15px;height:15px}
.draft-consequences{margin-top:12px;font-size:13px}
.draft-consequences>summary{cursor:pointer;color:var(--accent);font-weight:500;font-size:12.5px}
.draft-consequences table{margin-top:8px}
.draft-consequences td:first-child{width:30%;white-space:nowrap}
.form-class-table tr.is-closing>td{background:var(--green-soft)}
.form-class-table tr.is-gone>td{color:var(--muted)}
.draft-section .setting-toggle .draft-mark{margin-top:6px}
.draft-robots{display:flex;flex-direction:column;gap:10px;margin:0 0 6px}
.draft-robot{display:flex;gap:10px;align-items:flex-start;border:1px solid var(--line);border-radius:7px;padding:10px 12px;max-width:760px}
.draft-robot>.form-check-input{margin-top:3px;flex-shrink:0}
.draft-robot>span{display:flex;flex-direction:column;gap:2px;min-width:0}
.draft-robot strong{font-weight:500;font-size:13px}
.draft-robot small{font-size:12px}
.draft-sla-controls{margin:4px 0 6px}
.draft-date .form-control{max-width:200px}
.draft-preview{border-top:1px solid var(--line);padding-top:22px}
.draft-preview.is-pending .draft-note{font-size:13px}
.draft-preview-numbers{margin:0 0 12px}
.form-draft-numbers>div.is-warn{border-color:var(--orange);background:var(--orange-soft)}
.draft-examples{display:inline-flex;flex-wrap:wrap;gap:4px 8px;font-size:12px}
.draft-preview-steps{margin-top:14px}
.draft-preview h4,.first-load h4{font-size:13px;font-weight:600;margin:16px 0 6px}
.draft-sample ul,.draft-preview-warnings ul,.first-load-notes{margin:0;padding-left:18px;font-size:12.5px;line-height:1.6}
.draft-preview-warnings li{color:var(--ink)}
.draft-bar{border-top:1px solid var(--line);padding-top:16px;margin-top:8px}
.draft-bar .button-row{display:flex;gap:8px;flex-wrap:wrap}
.btn.btn-success{background:var(--green);border-color:var(--green);color:#fff}
.btn.btn-success:hover{filter:brightness(.95);background:var(--green);color:#fff}
.btn.btn-success:disabled{opacity:.45}
.draft-enable p{font-size:13px;margin:0 0 10px}
.first-load{margin:0 0 24px;padding:16px 18px;border:1px solid var(--line);border-radius:8px;background:var(--canvas)}
.first-load>h3{font-size:14px;font-weight:600;margin:0 0 4px}
.first-load .pyrus-reading{margin:6px 0 8px}
.first-load-bar{height:6px;border-radius:3px;background:var(--line);overflow:hidden;max-width:520px}
.first-load-bar>span{display:block;height:100%;background:var(--accent)}
.first-load-summary .table{background:var(--surface)}
.first-load-notes{margin-top:12px}
.first-load-retry{margin-top:6px}
/* review S6-R3: a failure's reason in words, the worker's own text folded under it; histories that did not load in the
   summary; a robot marked before that the latest sample no longer offers */
.first-load-detail{margin-top:6px;font-size:12px}
.first-load-detail>summary{cursor:pointer;color:var(--muted)}
.first-load-detail code{display:block;margin-top:4px;white-space:pre-wrap;overflow-wrap:anywhere;font-size:11.5px}
.first-load-summary .alert{margin:12px 0 0}
.draft-robot.is-gone{border-style:dashed}
/* On a phone the editor's tables stack: a role over its field; a step or a status with its count on one line, its class
   under them, the count named by its `data-label`; the summary's rows - the name and the two numbers, the examples under
   them. No table wider than the screen. */
@media(max-width:600px){
  .draft-fields-table .form-select{min-width:0;max-width:none;width:100%}
  .draft-table td{padding:8px}
  .draft-section table.draft-fields-table thead,.draft-section table.draft-table.form-class-table thead{display:none}
  .draft-section table.draft-fields-table tr,.draft-section table.draft-table.form-class-table tr{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px 12px;padding:10px 2px;border-bottom:1px solid var(--line)}
  .draft-section table.draft-fields-table td,.draft-section table.draft-table.form-class-table td{display:block;padding:0;border:0;background:transparent;width:auto}
  .draft-section table.draft-fields-table td{grid-column:1/-1}
  .draft-section table.draft-table.form-class-table td:nth-child(2){grid-column:1/-1;grid-row:2}
  .draft-section table.draft-table.form-class-table td.form-class-tickets{grid-column:2;grid-row:1}
  .draft-section table.draft-table.form-class-table td.form-class-tickets[data-label]::before{content:attr(data-label) ' ';color:var(--muted);font-size:11.5px}
  .draft-section table.draft-table.form-class-table .form-select{min-width:0;width:100%}
  .draft-section table.draft-table.form-class-table tr.is-closing{background:var(--green-soft)}
  .first-load-summary table.draft-table thead tr,.first-load-summary table.draft-table tbody tr{display:grid;grid-template-columns:minmax(0,1fr) 70px 70px;gap:4px 8px;padding:8px 6px;border-bottom:1px solid var(--line)}
  .first-load-summary table.draft-table th,.first-load-summary table.draft-table td{display:block;padding:0;border:0;background:transparent;width:auto}
  .first-load-summary table.draft-table td.form-class-tickets{text-align:right}
  .first-load-summary table.draft-table th{font-size:11px;white-space:normal;line-height:1.3;text-align:right}
  .first-load-summary table.draft-table th:last-child{display:none}
  .first-load-summary table.draft-table td:last-child{grid-column:1/-1}
  .first-load-summary table.draft-table td:last-child:empty{display:none}
  .draft-preview table.draft-preview-steps thead{display:none}
  .draft-preview table.draft-preview-steps tr{display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:4px 12px;padding:9px 2px;border-bottom:1px solid var(--line)}
  .draft-preview table.draft-preview-steps td{display:block;padding:0;border:0;background:transparent;width:auto}
  .draft-preview table.draft-preview-steps td:nth-child(2){grid-column:1/-1;grid-row:2;color:var(--muted);font-size:12px}
  .draft-preview table.draft-preview-steps td:nth-child(5){grid-column:1/-1;grid-row:3}
  .draft-preview table.draft-preview-steps td:nth-child(5):empty{display:none}
  .draft-preview table.draft-preview-steps td[data-label]::before{content:attr(data-label) ' ';color:var(--muted);font-size:11.5px}
  .draft-inline-select,.draft-inline-input{flex-basis:100%;max-width:none;margin-top:0}
  .draft-howto{padding-left:28px}
  .first-load{padding:14px}
}

/* A connected form's card, slice S7 (service-forms spec 2026-10-07 §11.5-§11.7; src/components/settings/FormCard.tsx,
   DraftEditor.tsx `edit`, EditPreview.tsx, FormActions.tsx): «Изменилась в Pyrus» as the warnings' block; «Отключается» with
   its spinner; «Обновить из Pyrus» and «Отключить форму» in a row under the form's facts; HelpDesk's read-only blocks with
   the shield; the service's group as a line; HelpDesk's other roles folded under its fields; «было → станет» - the numbers
   right-aligned, a row that moves tinted with the accent and its change bold; what the save will trigger as a short list
   above the buttons, «KPI изменится» in orange. At 600 px «было → станет» stacks: the number's name over its three
   values, each named by its `data-label`. */
.form-pyrus-changes,.form-warnings{display:block}
.form-pyrus-changes>strong,.form-warnings>strong{display:block}
.form-pyrus-changes ul{margin:6px 0;padding-left:18px}
.form-pyrus-changes small{display:block}
.form-pyrus-changes p{margin:6px 0 0}
.form-disabling{display:flex;gap:8px;align-items:center}
.form-actions{margin:4px 0 10px}
.form-actions .button-row{display:flex;gap:8px;flex-wrap:wrap}
.form-actions .btn .icon{width:15px;height:15px;margin-right:5px}
.form-helpdesk-note{display:flex;gap:6px;align-items:center;font-size:12px;margin:0 0 14px}
.form-helpdesk-note .icon{width:14px;height:14px;flex-shrink:0}
.draft-locked{display:flex;gap:6px;align-items:flex-start}
.draft-locked .icon{width:14px;height:14px;flex-shrink:0;margin-top:2px}
.draft-section>.draft-locked:first-of-type{margin-top:0}
.draft-group-line{max-width:520px;margin:4px 0 2px}
.draft-other-roles{margin-top:14px}
.edit-preview-table td.form-class-tickets,.edit-preview-table th.form-class-tickets{text-align:right;white-space:nowrap}
.edit-preview-table tr.is-changed>td{background:var(--accent-soft)}
.edit-preview-table tr.is-changed>td:last-child{font-weight:600}
.draft-will{margin:0 0 12px;font-size:12.5px;max-width:760px}
.draft-will ul{margin:4px 0 0;padding-left:18px;line-height:1.6}
.draft-will li.draft-warning-text{list-style:none;margin-left:-18px;display:flex;gap:6px;align-items:flex-start;color:var(--orange)}
.draft-will li.draft-warning-text .icon{width:14px;height:14px;flex-shrink:0;margin-top:3px}
@media(max-width:600px){
  .edit-preview table.edit-preview-table thead{display:none}
  .edit-preview table.edit-preview-table tr{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:4px 10px;padding:9px 2px;border-bottom:1px solid var(--line)}
  .edit-preview table.edit-preview-table td{display:block;padding:0;border:0;width:auto;text-align:left;background:transparent}
  .edit-preview table.edit-preview-table tr.is-changed{background:var(--accent-soft)}
  .edit-preview table.edit-preview-table td:first-child{grid-column:1/-1}
  .edit-preview table.edit-preview-table td.form-class-tickets{text-align:left}
  .edit-preview table.edit-preview-table td[data-label]::before{content:attr(data-label) ' ';color:var(--muted);font-size:11.5px}
  .form-actions .btn{flex:1 1 auto}
}
