/* Отчёты: разбор, ИИ-вердикт, дневной отчёт, жалобы. */
/* Q3 — KPI as a dense industrial ledger strip (Brockmann/micrographic): 4
   metrics in one row, split by hairline rules (1 px gap over a --border ground),
   mono tabular numerals, micro labels. No padded cards, no decorative corners.
   Zeros recede (muted); the red accent only lights when its value > 0. */
.kpi-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0.0625rem;
    background: var(--border);
    border: 0.0625rem solid var(--border);
    margin-bottom: var(--space-lg);
}
.kpi-link {
    text-decoration: none;
    color: inherit;
    display: block;
    background: var(--bg-surface);
    transition: background var(--dur-fast) var(--ease-out);
}
.kpi-card {
    padding: var(--space-md) var(--space-xs);
    text-align: center;
    transition: color var(--dur-fast) var(--ease-out);
}
.kpi-value {
    font-family: var(--font-mono);
    font-size: clamp(1.25rem, 5vw, 1.625rem);
    font-weight: 700;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--text-primary);
}
.kpi-label {
    font-family: var(--font-mono);
    font-size: var(--micro-size);
    color: var(--micro-color);
    letter-spacing: 0;
    line-height: 1.25;
    margin-top: var(--space-sm);
}
.report-detail,
.daily-report {
    max-width: 56.25rem;
}
.detail-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
    gap: var(--space-md);
    margin-bottom: var(--space-xl);
}
.detail-label {
    display: block;
    font-family: var(--font-mono);
    font-size: var(--micro-size);
    letter-spacing: 0;
    color: var(--text-secondary);
    margin-bottom: var(--space-xs);
}
.detail-value {
    font-family: var(--font-mono);
    font-size: var(--fs-md);
    font-weight: 600;
}
.detail-block {
    margin-bottom: var(--space-xl);
}
.detail-block-title {
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    font-weight: 700;
    letter-spacing: 0;
    color: var(--text-secondary);
    border-bottom: 0.0625rem solid var(--border);
    padding-bottom: var(--space-xs);
    margin-bottom: var(--space-md);
}
.ai-verdict-block {
    /* Оранжевая линия сверху висела ровно между планом и разбором и читалась
       как случайная черта. Разделяет теперь та же тонкая граница, что у
       остальных блоков; акцент несёт бейдж вердикта. */
    border-top: 0.0625rem solid var(--border);
    padding-top: var(--space-md);
    padding-left: 0;
}
.ai-row {
    display: flex;
    align-items: baseline;
    gap: var(--space-sm);
    margin-bottom: var(--space-sm);
    font-size: var(--fs-sm);
}
.ai-icon {
    font-family: var(--font-mono);
    font-size: var(--micro-size);
    font-weight: 700;
    padding: 0.125rem 0.375rem;
    flex-shrink: 0;
}
.ai-icon--ok { background: var(--success)   !important; color: var(--white); }
.ai-icon--fail { background: var(--secondary) !important; color: var(--white); }
.ai-verdict-head {
    display: inline-block;
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    letter-spacing: 0;
    padding: 0.25rem 0.625rem;
    margin-bottom: var(--space-sm);
    /* Пилюля (radius 624rem) выпадала из дома: остальные панели и метки
       квадратные со срезом. Рамку рисует слой, потому что clip-path режет
       border вместе с фоном и на диагонали остаётся разрыв. */
    position: relative;
    isolation: isolate;
    background: currentColor;
    border: 0;
    border-radius: 0;
    clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--cut-sm)),
                       calc(100% - var(--cut-sm)) 100%, 0 100%);
}
.ai-verdict-head::before {
    content: "";
    position: absolute;
    inset: 0.0625rem;
    z-index: -1;
    background: var(--bg-surface);
    clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--cut-sm)),
                       calc(100% - var(--cut-sm)) 100%, 0 100%);
}
.ai-verdict--approved { color: var(--success); }
.ai-verdict--rework { color: var(--accent); }
.ai-verdict--rejected { color: var(--secondary); }
.ai-label {
    font-family: var(--font-mono);
    font-size: var(--micro-size);
    letter-spacing: 0;
    color: var(--text-secondary);
    flex-shrink: 0;
    min-width: 3.75rem;
}
.ai-text { color: var(--text-primary); }
.ai-frames {
    margin-top: var(--space-md);
    padding-top: var(--space-md);
    border-top: 0.0625rem solid var(--border);
}
.ai-frames-title {
    font-family: var(--font-mono);
    font-size: var(--micro-size);
    letter-spacing: 0;
    color: var(--text-secondary);
    margin-bottom: var(--space-sm);
}
.ai-frame {
    font-size: var(--fs-xs);
    padding: var(--space-xs) 0;
    border-bottom: 0.0625rem solid var(--border);
}
.ai-frame-num {
    font-family: var(--font-mono);
    font-weight: 700;
    color: var(--primary);
}
.daily-header {
    margin-bottom: var(--space-2xl);
    border-bottom: 0.0625rem solid var(--border);
    padding-bottom: var(--space-md);
}
.daily-date {
    font-family: var(--font-mono);
    font-size: clamp(1.5rem, 3vw, 2rem);
    font-weight: 700;
}
.daily-site {
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    color: var(--text-secondary);
    letter-spacing: 0;
}
.daily-timeline {
    position: relative;
    /* №218 */
    padding-left: 1.5rem;
}
@media (min-width: 48em) {
    .daily-timeline { padding-left: 2.5rem; }
}
.daily-timeline::before {
    content: '';
    position: absolute;
    /* №219 */
    left: 0.4375rem;
    top: 0;
    bottom: 0;
    width: 0.125rem;
    background: var(--border);
}
@media (min-width: 48em) {
    .daily-timeline::before { left: 0.9375rem; }
}
.timeline-text,
.detail-text {
    font-size: var(--fs-sm);
    line-height: 1.6;
    white-space: pre-wrap;
}
.complaint-card-mini {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-sm) 0;
    border-bottom: 0.0625rem solid var(--border);
    font-size: var(--fs-sm);
}
.complaint-card-mini a {
    color: var(--text-primary);
    text-decoration: none;
    flex: 1;
}
.complaint-deadline {
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    color: var(--text-muted);
}
.kpi-mini-grid {
    display: flex;
    /* №223 */
    gap: var(--space-md);
    flex-wrap: wrap;
}
@media (min-width: 48em) {
    .kpi-mini-grid { gap: var(--space-lg); }
}
.kpi-mini-val {
    display: block;
    font-family: var(--font-mono);
    /* №224 */
    font-size: var(--fs-md);
    font-weight: 700;
}
@media (min-width: 48em) {
    .kpi-mini-val { font-size: var(--fs-xl); }
}
.fm-period-pills { display: inline-flex; gap: 0.25rem; flex-wrap: wrap; }
.fm-period-pills .btn.is-active {
    background: var(--primary);
    color: var(--bg-surface);
    border-color: var(--primary);
}
.fm-bell { position: relative; display: inline-flex; align-items: center; order: 20; margin-inline-start: auto; }
.fm-bell-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--tap-target);
    height: var(--tap-target);
    background: transparent;
    border: 0.0625rem solid transparent;
    color: var(--text-secondary);
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}
/* Непрочитане — ЧИСЛОМ, не червоною крапкою (каталог ШІ-патернів п.2; 29.09).
   Моно-цифри на чорній табличці без округлення, поруч з дзвіночком. */
.fm-bell-count {
    position: absolute;
    top: 0.125rem;
    right: 0;
    min-width: 1.1rem;
    padding: 0.05rem 0.2rem;
    font-family: var(--font-mono);
    font-size: 0.625rem;
    font-weight: 700;
    line-height: 1.1;
    text-align: center;
    color: var(--white);
    background: var(--chrome);
    border: 0.0625rem solid var(--text-muted);
    border-radius: 0;
    pointer-events: none;
}
.inspector-panel {
    /* In normal flow — scrolls with the report. Was `position: sticky; bottom:0`
       which pinned the inspector-review block to the bottom of the viewport so
       it never scrolled away (client: «поле проверки подвешено, не скролится»). */
    position: static;
    background: var(--bg-surface);
    border-top: 0.0625rem solid var(--border);
    padding: var(--space-md) var(--space-lg);
    margin-top: var(--space-lg);
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm);
    align-items: flex-start;
}
/* ── Telegram-style report delivery overlay ─────────────────────────
   The foreman watches the report travel: sending → sent (✓) → delivered
   (✓✓), then lands in «Отправленные». Materializes as a real surface. */
.fm-send {
    position: fixed; inset: 0; z-index: 1000;
    display: flex; align-items: center; justify-content: center;
    background: var(--chrome);
    animation: fm-send-in var(--dur-normal) var(--ease-out);
}
.fm-send-card {
    display: flex; flex-direction: column; align-items: center; gap: 1.1rem;
    padding: 2rem 2.5rem; min-width: 14rem;
    background: var(--bg-surface); border: 0.0625rem solid var(--border);
    animation: fm-send-pop var(--dur-normal) cubic-bezier(0.22, 1, 0.36, 1);
}
@keyframes fm-send-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes fm-send-pop { from { opacity: 0; transform: translateY(0.6rem) scale(0.95); } to { opacity: 1; transform: none; } }
.fm-send-visual { position: relative; width: 3.25rem; height: 3.25rem; }
.fm-send-spin {
    position: absolute; inset: 0;
    border: 0.1875rem solid var(--border); border-top-color: var(--primary);
    border-radius: 50%; animation: fm-spin 0.8s linear infinite;
}
@keyframes fm-spin { to { transform: rotate(360deg); } }
.fm-send-check { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; }
.fm-send-check-ring { fill: none; stroke: var(--success); stroke-width: 2; opacity: 0.3; }
.fm-send-check-a, .fm-send-check-b {
    fill: none; stroke: var(--success); stroke-width: 4;
    stroke-linecap: round; stroke-linejoin: round;
    stroke-dasharray: 46; stroke-dashoffset: 46;
    transition: transform var(--dur-normal) cubic-bezier(0.22, 1, 0.36, 1);
}
.fm-send.is-sent .fm-send-check-a { animation: fm-check-draw 0.42s var(--ease-out) forwards; }
.fm-send.is-delivered .fm-send-check-a { stroke-dashoffset: 0; transform: translateX(-0.28rem); }
.fm-send.is-delivered .fm-send-check-b {
    opacity: 1; transform: translateX(0.28rem);
    animation: fm-check-draw 0.4s var(--ease-out) forwards;
}
@keyframes fm-check-draw { to { stroke-dashoffset: 0; } }
.fm-send-label {
    font-family: var(--font-mono); font-size: var(--fs-sm); letter-spacing: 0;
    color: var(--text-primary); text-align: center;
}
@media (prefers-reduced-motion: reduce) {
    .fm-send, .fm-send-card { animation: none; }
    .fm-send-spin { animation-duration: 1.6s; }
    .fm-send-check-a, .fm-send-check-b { animation: none !important; stroke-dashoffset: 0; transition: none; }
}
@keyframes fm-arrive { from { opacity: 0; transform: translateY(-0.75rem); } to { opacity: 1; transform: none; } }
@keyframes fm-arrive-flash { from { opacity: 1; } to { opacity: 0; } }
.inspector-action summary {
    min-height: 2.25rem;
}
.btn-inspector {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    cursor: pointer;
}
.btn-fine { border-color: var(--secondary); color: var(--secondary); }
.btn-approve:hover { background: color-mix(in srgb, var(--success)   14%, transparent); }
.btn-rework:hover { background: color-mix(in srgb, var(--accent)    14%, transparent); }
.btn-fine:hover { background: color-mix(in srgb, var(--secondary) 14%, transparent); }
@media (max-width: 47.99em) {
    /* Detail block → tight 2-col ledger, hairline gaps, small padding.
           30.07: те саме роздування знайшлось на звітах (report_detail) — шість
           повноекранних панелей: дата рядок, обʼєкт рядок… Тому компактний
           ledger тепер ЗАГАЛЬНЕ правило для .detail-grid на телефоні, а не
           приватне для .zone-detail. Панель = десктопний ритм; телефон = таблиця. */
    .detail-grid { grid-template-columns: 1fr 1fr; gap: 0.0625rem; margin-bottom: var(--space-sm); }
    .detail-item { padding: 0.35rem 0.5rem; border-width: 0.0625rem; }
    .detail-label { font-size: var(--micro-size); margin-bottom: 0.05rem; }
    .detail-value { font-size: var(--fs-xs); font-weight: 600; }
    .detail-block { margin-bottom: var(--space-sm); }
    .detail-block-title { margin-bottom: var(--space-xs); padding-bottom: 0.15rem; }
    .detail-text { font-size: var(--fs-xs); line-height: 1.4; }
}
/* The group owns the outline; segments carry no border of their own, and the
   semantic colour survives in the icon only. */
.rev-actions .action-item .btn,
.rev-actions .inspector-action > summary {
    border: 0;
    background: transparent;
    color: var(--text-primary);
    /* `summary` computed to display:list-item despite `.btn`'s inline-flex, so
       its label sat at the top of the segment while the approve button's label
       was centred — the row looked misaligned. Force the flex box here. */
    display: flex;
    align-items: center;
    /* Three labels across a 390 px phone. The global 0.12em tracking wrapped
       "НА ДОРАБОТКУ" onto a second line, so that button grew taller than its
       neighbours and the row read as broken. One line each, type shrinks with
       the viewport instead of the box growing. */
    width: 100%; height: 100%;
    justify-content: center;
    white-space: nowrap;
    font-size: clamp(0.5rem, 2.4vw, 0.6875rem);
    letter-spacing: 0;
    gap: 0.3rem;
    padding-inline: 0.4rem;
}
/* Primary action = solid block. It is the one thing the inspector does most,
   and a fill needs no outline to be findable. */
.rev-actions .action-item .btn-approve {
    background: var(--success);
    color: var(--bg-base);
}
.rev-actions .action-item .btn-approve:active { background: color-mix(in srgb, var(--success) 82%, black); }
.rev-actions .action-item .btn:active,
.rev-actions .inspector-action > summary:active,
.rev-actions .inspector-action[open] > summary {
    background: color-mix(in srgb, var(--text-primary) 10%, transparent);
}
.rev-actions .btn-inspector .icon { width: 0.8125rem; height: 0.8125rem; }
/* Внутри хоста плашка перестаёт быть плавающей: она и есть нижняя панель. */
.fm-actionbar .chip-island {
    position: static;
    transform: none;
    max-width: none;
    margin: 0;
    padding: 0;
    background: transparent;
    border: 0;
    box-shadow: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    justify-content: center;
    /* Нулевой радиус — правило дома; скругление осталось от плавающей
       «пилюли», в панели оно резало активную кнопку по левому краю. */
    border-radius: 0;
}
.fm-actionbar .chip-island-btn { flex: 1 1 0; justify-content: center; }
.kpi-link--static:hover { background: inherit; }
/* Заголовок отчёта (пишет AI, правит человек) + служебная строка под ним. */
.rep-title { margin-bottom: 0.15rem; }
.rep-title-edit > summary {
    list-style: none; cursor: pointer; color: var(--text-secondary);
    border-bottom: 0.0625rem solid var(--border);
}
.rep-title-edit[open] > summary { color: var(--primary); border-bottom-color: var(--primary); }
.rep-title-edit form { display: flex; gap: var(--space-sm); margin-top: var(--space-sm); width: 100%; }
/* Бейджи внутри строки меты — служебные метки, а не кнопки: тот же мелкий
   кегль, иначе строка распухает на третий ряд. */
.rep-meta .badge {
    text-transform: none; font-size: var(--micro-size);
    padding: 0.1rem 0.35rem; min-height: 0;
}
/* ── Доска для рисования ──────────────────────────────────────────────────
   Полноэкранный оверлей: светлый холст-«бумага» во весь экран, тёмная
   панель инструментов снизу (хром всегда тёмный, DESIGN.md §1).

   Панель ВНИЗУ, а не вверху: телефон держат одной рукой, и «Отправить»
   должна лежать под большим пальцем. До 24.08.2026 панель была верхней и
   строкой без переноса — на 390 CSS-пикселях девять текстовых кнопок в неё
   не влезали, «Отправить» уезжала за правый край, и отправить рисунок было
   нечем (Дмитрий, скрин в группе).

   Подписи заменены иконками из общего спрайта: слово занимает 5-6 целей
   нажатия, иконка — одну. Текст остался у отправки, и только с 30rem, где
   он помещается, не сжимая инструменты. Смысл кнопки для скринридера и для
   долгого тапа несут aria-label и title, они переведены. */
#fm-board {
    /* Выше passkey-плашки (9998): она fixed bottom и перекрывала кнопки. */
    position: fixed; inset: 0; z-index: 10000;
    display: flex; flex-direction: column;
    background: var(--bg-base);
    /* Выезжает снизу по общему токону (--mx-quick/--mx-ease из motion.css),
       как шторка отчёта (layout.css .fm-sheet-panel). Класс вешает board.js
       через кадр. */
    transform: translateY(100%);
    transition: transform var(--mx-quick) var(--mx-ease);
}
@media (prefers-reduced-motion: reduce) {
    #fm-board { transform: none; opacity: 0; transition: opacity 0.15s linear; }
    #fm-board.is-open { opacity: 1; }
}
.rep-pair-i.is-on {
    background: var(--bg-elevated);
    color: var(--text-primary);
    font-weight: 700;
}
/* Отклик на само касание, а не на отпускание (DESIGN.md §0: перчатка). */
.rep-pair-i:active,
.fm-bell-item.is-state,
.wk-item:active,
.site-tile--folder .site-tile-img,
.dreg-folder:hover,
.dreg-folder:focus-visible { background: var(--bg-surface); }
.rep-shot img,
.rep-shot video {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    background: var(--bg-elevated);
}
/* Разбор AI по пунктам свёрнут: блок занимал 891 px, больше экрана целиком.
   Вердикт и пересказ видны всегда, детали раскрывают, когда спорят. */
.ai-more > summary {
    list-style: none; cursor: pointer;
    font-family: var(--font-mono); font-size: var(--micro-size);
    letter-spacing: 0;
    color: var(--text-secondary);
    padding: var(--space-xs) 0;
    min-height: var(--tap-target);
    display: flex; align-items: center;
}
.ai-more > summary::after { content: "+"; margin-left: 0.5rem; }
.ai-more[open] > summary::after { content: "−"; }
.ai-more[open] > summary { color: var(--primary); }
.ai-checks .ai-row {
    display: grid;
    grid-template-columns: 2.9rem 4.5rem 1fr;
    align-items: start;
    gap: 0 var(--space-sm);
    margin: 0;
    padding: 0.55rem 0;
    border-top: 0.0625rem solid var(--border);
    font-size: var(--fs-xs);
    line-height: 1.45;
}
.ai-checks .ai-icon {
    justify-self: start;
    text-align: center;
    min-width: 2.9rem;
    padding: 0.1rem 0;
}
.ai-checks .ai-label { padding-top: 0.1rem; }
@media (max-width: 26em) {
    /* Узкий экран: метка уходит под маркер, текст занимает всю ширину. */
    .ai-checks .ai-row { grid-template-columns: 2.9rem 1fr; }
    .ai-checks .ai-text { grid-column: 1 / -1; padding-top: 0.3rem; }
}
/* ── Точечные разделители перечней ────────────────────────────────────────
   Пункты плана и критерии разбора разделяет чертёжный пунктир, а не
   сплошная линия: сплошная читается как край карточки. Правило для строк
   журнала живёт в самом определении `.rl-row` выше — второй слой правил на
   тот же компонент запрещён (DESIGN.md, раздел 8, пункт 4). */
.ai-checks .ai-row {
    border-top: 0;
    background-image: var(--rule-dots);
    background-size: var(--rule-dots-size);
    background-repeat: repeat-x;
    background-position: top left;
}
.btn-primary,
.gph[open] .gph-bub,
.fv-mode.is-on,
.sch2-add:hover { background: var(--text-primary); color: var(--bg-base); }
.site-tile--empty .site-tile-count { background: var(--bg-elevated); color: var(--text-secondary); }
/* Редактор графіка: колонка дій за вмістом (кнопки після уніфікації стали
   ширшими за 9.5rem і ряд вилазив за таблицю — смуга прокрутки на 1670 px). */
/* Лише десктоп: на телефоні рядок стає сіткою 1fr 1fr (правила вище), а це
   правило стояло пізніше в каскаді і перебивало її — поля вилазили за край
   (25.09.2026). */
.sph[open] .gph-bub { background: var(--text-primary); color: var(--bg-base); }
.hc-input::-webkit-outer-spin-button, .hc-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.hc-total b { font-family: var(--font-mono); color: var(--text-primary); font-size: var(--fs-md, 1rem); }
.sch-child-act > .chip { flex: 0 0 auto; height: var(--tap-target); min-height: var(--tap-target); box-sizing: border-box; }
.sch2 .sch2-menu .sch2-steps .chip, .sch2-m-acts .chip { min-height: var(--tap-target); }
