/* Задачи: журнал, доска, фильтры, списки. */
.btn-sm {
    padding: 0.125rem var(--space-sm);
    font-size: var(--micro-size);
    min-height: 1.5rem;
    white-space: nowrap;
    letter-spacing: 0;
}
@media (max-width: 56.25em) {
    .btn-sm {
        min-height: 2.75rem;
        font-size: var(--fs-sm);
        padding: var(--space-sm);
    }
}
/* Чернетки після розбору (`/tasks?box=drafts`, sessionStorage fm_intake_done)
   в'їжджають одна за одною — той самий fm-arrive, без спалаху (flash тут
   зайвий на 10 картках підряд), delay ставить JS інлайном. Без ключа в
   sessionStorage клас не вішається зовсім — звичайний релоуд миттєвий. */
.tsk-draft-arrive { animation: fm-arrive var(--mx-reveal) var(--mx-ease) both; }
/* Відправка чернетки: рядок згортається grid-rows 1fr→0fr (техніка
   .mx-reveal-body з motion.css) замість зникнення на релоуд. 260ms —
   коротше за --mx-reveal навмисно: у масовій відправці рядки йдуть косяком
   і не мають тримати погляд довше за клік. */
.tsk-row-collapse {
    display: grid;
    grid-template-rows: 1fr;
    opacity: 1;
    transition: grid-template-rows 260ms var(--mx-ease),
                opacity 260ms var(--mx-ease);
}
.tsk-row-collapse > * { overflow: hidden; min-height: 0; }
.tsk-row-collapse.is-collapsed { grid-template-rows: 0fr; opacity: 0; }
@media (prefers-reduced-motion: reduce) {
    .tsk-row-collapse,
    .fm-ios-sheet { transition: none; }
}
.fp-container.edit-mode .fp-marker,
.tb-card[draggable="true"] { cursor: grab; }
/* ── Tasks filter / search — industrial control strip ────────────────────
   Один ряд контролов на общей базовой линии (--tsk-h), тонкие границы,
   mono-микро типографика, острые углы (blueprint). Поиск с иконкой-лупой,
   «выполненные» — chip-toggle, а не голый чекбокс. Всё гладко переносится
   на мобиле (flex-wrap). */
.tsk-filter { --tsk-h: 2.5rem; margin-bottom: var(--space-lg); }
.tsk-toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-sm); }
/* Box/direction segments — компактные inline, без full-width подчёркивания */
.tsk-tabs.seg-toggle { border: 0.0625rem solid var(--border); flex: none; display: flex; width: 100%; }
.tsk-tabs.seg-toggle label {
    height: var(--tsk-h); padding: 0 0.4rem;
    display: inline-flex; align-items: center; justify-content: center;
    flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis;
    font-size: var(--fs-xs); letter-spacing: 0;
}
@media (min-width: 40.0625em) {
    .tsk-tabs.seg-toggle { display: inline-flex; width: auto; }
    .tsk-tabs.seg-toggle label { flex: none; padding: 0 0.95rem; }
}
.tsk-controls { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-sm); flex: 1 1 auto; }
/* «Выполненные» → chip-toggle: гаснет muted, зажигается primary при активе */
.tsk-chip {
    display: inline-flex; align-items: center; gap: 0.45rem;
    height: var(--tsk-h); padding: 0 0.85rem;
    border: 0.0625rem solid var(--border); background: var(--bg-surface);
    color: var(--text-muted);
    font-family: var(--font-mono); font-size: var(--micro-size); letter-spacing: 0;
    cursor: pointer; white-space: nowrap; user-select: none;
    transition: color .12s var(--ease-out), border-color .12s var(--ease-out), background .12s var(--ease-out);
}
.tsk-chip input { position: absolute; opacity: 0; width: 0; height: 0; }
.tsk-chip::before {
    content: ""; width: 0.7rem; height: 0.7rem; flex: none;
    border: 0.0938rem solid currentColor;
}
.tsk-chip:has(input:checked) {
    color: var(--primary); border-color: var(--primary);
    background: color-mix(in srgb, var(--primary) 10%, transparent);
}
.tsk-chip:has(input:checked)::before {
    background: var(--primary); border-color: var(--primary);
    box-shadow: inset 0 0 0 0.125rem var(--bg-surface);
}
.tsk-chip:has(input:focus-visible) { box-shadow: 0 0 0 0.1875rem var(--focus-ring); }
/* Search: лупа внутри ряда, поле растёт, но с потолком, чтобы не зияло
   пустотой. Лупа и поле оба в потоке (fix: absolute-лупа перекрывала
   placeholder). */
.tsk-search { position: static; display: flex; align-items: center; gap: 0.4rem;
    padding: 0 0.65rem; flex: 1 1 12rem; min-width: 9rem; max-width: 22rem; }
.tsk-search-ic { width: 0.85rem; height: 0.85rem; color: var(--text-muted);
    pointer-events: none; flex: 0 0 auto; }
.tsk-search-input {
    width: 100%; height: var(--tsk-h); min-height: var(--tsk-h);
    padding: 0 0.75rem 0 2.1rem;
    border: 0.0625rem solid var(--border); background: var(--bg-surface);
    color: var(--text-primary); font-size: var(--fs-xs);
    transition: border-color .15s ease, box-shadow .15s ease;
}
@media (max-width: 40em) {
    /* Phone: рвём одноряд в стопку с предсказуемой шириной. Сегменты — на всю,
       равными третями; select'ы сжимаются и делят ряд по двое (не по 192 px, иначе
       на 360 px один валится и зияет пустотой); chip — рядом; поиск — свой полный
       ряд первым (главный контрол на телефоне). */
    .tsk-toolbar { flex-direction: column; align-items: stretch; gap: var(--space-sm); }
    .tsk-tabs.seg-toggle { display: flex; width: 100%; }
    .tsk-tabs.seg-toggle label {
        flex: 1 1 0; justify-content: center;
        padding: 0 0.4rem; letter-spacing: 0;
    }
    .tsk-controls { gap: var(--space-sm); }
    .tsk-chip { flex: 1 1 8rem; justify-content: center; }
    .tsk-search { flex: 1 1 100%; max-width: none; order: -1; }
}
.bar-fill { position: relative; overflow: hidden; }
.bar-prog {
    position: absolute; left: 0; top: 0; bottom: 0;
    background: rgba(255,255,255,0.32);
    border-right: 0.09375rem solid rgba(255,255,255,0.6);
}
.gantt2 { overflow-x: hidden; }
/* Filter bar — aligned technical inputs, one visual family. */
.lf-filter { margin: 0 0 var(--space-md); }
.lf-fold-sum {
    display: inline-flex; align-items: center; gap: 0.5rem;
    min-height: var(--tap-target); padding: 0 0.75rem 0 0.6rem;
    border: 0.0625rem solid var(--border); background: var(--bg-surface);
    color: var(--text-secondary); cursor: pointer; user-select: none;
    font-family: var(--font-mono); font-size: var(--micro-size); letter-spacing: 0;
}
.lf-fold-sum:hover { color: var(--text-primary); border-color: var(--primary); }
.lf-fold-ic { width: 1rem; height: 1rem; flex: none; }
/* Стрілка-афорданс праворуч: без неї summary читається як звичайна кнопка. */
.lf-fold-sum::after {
    content: "+"; margin-left: 0.15rem; font-size: var(--fs-xs); line-height: 1;
    color: var(--text-muted);
}
.lf-fold[open] > .lf-fold-sum::after { content: "\2212"; }
/* Лічильник активних фільтрів — головна страховка згортання: список уже
   звужений, і це має бути видно, коли контроли сховані. */
.lf-fold-n {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 1.1rem; height: 1.1rem; padding: 0 0.25rem;
    font-style: normal; font-size: var(--micro-size); font-weight: 700;
    color: var(--bg-base); background: var(--primary);
}
.lf-bar { display: flex; flex-wrap: wrap; gap: var(--space-sm); align-items: stretch; }
.lf-tabs { flex: 1 1 100%; overflow-x: auto; scrollbar-width: none; }
/* `flex:1 1 0` різав «відхилено»/«вирішено» до 69 px при потрібних 84-92:
   рівні сегменти на 390 px не вміщають довгі статуси. `1 0 auto` дає рости,
   коли місце є, і ніколи не стискає нижче тексту — контейнер уже скролиться
   по горизонталі (`.lf-tabs { overflow-x: auto }`). */
.lf-tabs.seg-toggle label {
    flex: 1 0 auto; min-width: max-content; text-align: center;
    padding-left: 0.6rem; padding-right: 0.6rem;
    white-space: nowrap;
}
/* Число на чипе — сам счётчик, а не подпись: тонкое, моно, tabular, чтобы
   ряд не дёргался при смене цифр. Ноль не печатается вовсе (см.
   reports_facets), поэтому пустых «0» в ряду нет. */
.lf-n {
    font-style: normal;
    font-family: var(--font-mono);
    font-size: var(--micro-size);
    font-variant-numeric: tabular-nums;
    margin-left: 0.35rem;
    opacity: 0.65;
}
.lf-select, .lf-search {
    height: 2.375rem; min-height: 2.375rem; box-sizing: border-box;
    border: 0.0625rem solid var(--border);
    background: var(--bg-surface); transition: border-color var(--dur-fast) var(--ease-out);
}
.lf-select {
    flex: 1 1 0; min-width: 0; max-width: none; width: auto;
    padding: 0 1.7rem 0 0.65rem;
    font-family: var(--font-mono); font-size: var(--fs-xs);
    letter-spacing: 0; color: var(--text-secondary);
    -webkit-appearance: none; appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%238a8580' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
    background-repeat: no-repeat; background-position: right 0.6rem center;
}
.lf-select:focus,
.tsk-controls .form-select:focus { border-color: var(--primary); color: var(--text-primary); outline: none; }
.lf-search { flex: 1.4 1 0; min-width: 0; display: flex; align-items: center; gap: 0.45rem; padding: 0 0.7rem; }
.lf-search-ic { width: 0.9rem; height: 0.9rem; color: var(--text-muted); flex: 0 0 auto; opacity: 0.7; }
.lf-search-input { border: none; background: transparent; color: var(--text-primary);
    font-family: var(--font-mono); font-size: var(--fs-xs); letter-spacing: 0;
    text-transform: none; width: 100%; outline: none;
    -webkit-appearance: none; appearance: none; }
.lf-search-input::placeholder {
    color: var(--text-muted); letter-spacing: 0; text-transform: none;
    /* mono placeholder без разрядки/капса — «Поиск», не «П О И С К» */
}
/* ═══ Reports LEDGER (журнал) — group-by-day · time-rail · machined tags ═══ */
.rl-tally { display:flex; margin:0 0 var(--space-md); border:0.0625rem solid var(--border); }
.rl-tally b { flex:1; display:flex; flex-direction:column; gap:0.25rem; padding:0.6rem 0.7rem; border-right:0.0625rem solid var(--border); }
.rl-tally .n { font-family:var(--font-mono); font-size:var(--fs-xl); font-weight:600; letter-spacing:-0.02em; line-height:1; font-variant-numeric:tabular-nums; }
.rl-day { display:flex; align-items:center; gap:0.6rem; margin:1.2rem 0 0.1rem; }
.rl-dow { color:var(--text-muted); }
/* (.rl-line слит в штриховое правило ниже, task-044.) */
.rl-cnt { font-family:var(--font-mono); font-size: var(--micro-size); color:var(--text-muted); font-variant-numeric:tabular-nums; }
/* Телефон: три колонки. Заголовок работ занимает первую строку ЦЕЛИКОМ,
   тег статуса уходит вниз к подстроке. Раньше тег стоял справа и держал
   свои 77 px на обеих строках через grid-row:1/3 — заголовку оставалось
   181 px из 350, и «Укладка камня, санузлы 1.10-1.13» обрывалось на слове
   «сану…». Теперь на заголовок работает 287 px. */
/* Разделитель строк — точки, а не сплошная линия: пятнадцать сплошных линий
   превращают список в пятнадцать коробок, точки держат ритм и отступают на
   второй план. Рисует фон, а не border: у background-image управляемый шаг,
   а `border: dotted` ставит точки по своему усмотрению и по-разному в
   разных браузерах. */
.rl-row { display:grid; grid-template-columns:3.1rem minmax(0,1fr) auto; align-items:center; gap:0.12rem 0.8rem;
    padding:0.6rem 0.15rem; text-decoration:none; color:inherit; position:relative;
    background-image:var(--rule-dots); background-size:var(--rule-dots-size);
    background-repeat:repeat-x; background-position:bottom left; }
/* Наведение подсвечивает саму строку, а не рисует полосу слева: акцентная
   линия в левом гуттере уводила глаз с данных и ломала ритм колонок.
   Заливка ложится ВТОРЫМ слоем фона, чтобы пунктир остался поверх. */
.rl-row:hover {
    background-image:var(--rule-dots), linear-gradient(var(--bg-surface), var(--bg-surface));
    background-size:var(--rule-dots-size), 100% 100%;
    background-repeat:repeat-x, no-repeat;
    background-position:bottom left, 0 0;
}
.rl-row:active {
    background-image:var(--rule-dots), linear-gradient(var(--bg-elevated), var(--bg-elevated));
    background-size:var(--rule-dots-size), 100% 100%;
    background-repeat:repeat-x, no-repeat;
    background-position:bottom left, 0 0;
}
.rl-rail { grid-row:1/3; align-self:stretch; display:flex; flex-direction:column; align-items:flex-end; justify-content:center;
    gap:0.15rem; padding-right:0.8rem; border-right:0.0625rem solid var(--border); font-family:var(--font-mono); }
.rl-t { font-size:var(--fs-xs); letter-spacing:-0.02em; color:var(--text-primary); font-variant-numeric:tabular-nums; }
.rl-ty { width:0.85rem; height:0.85rem; color:var(--text-muted); }
/* Розкладка на 390 px. Тег статусу стоїть у рядку 1 поруч із заголовком, а не
   над мета-рядком: інакше він з'їдав 52-107 px з `.rl-sub`, і назва об'єкта
   лишалася 28-50 px замість потрібних 70. Заголовок натомість не ріжеться
   в один рядок, а переноситься на два — тексту втрачається менше, а рядок
   росте лише там, де заголовок реально довгий. */
.rl-who { grid-column:2; grid-row:1; font-family:var(--font-sans); font-weight:600; font-size:var(--fs-sm); letter-spacing:-0.006em;
    color:var(--text-primary); min-width:0; overflow:hidden;
    display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; line-height:1.25; }
.rl-sub { grid-column:2/4; grid-row:2; display:flex; align-items:center; gap:0.5rem; min-width:0;
    flex-wrap:nowrap; overflow:hidden;
    font-family:var(--font-mono); font-size: var(--micro-size); letter-spacing: 0; color:var(--text-muted); }
/* Назва об'єкта повторюється в кожному рядку і зрозуміла з контексту сайту,
   тому вона стискається першою; автор/причина отримують решту ширини. */
.rl-obj { flex:0 1 auto; min-width:0; max-width:9rem; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.rl-media { flex:0 0 auto; display:inline-flex; align-items:center; gap:0.2rem; }
.rl-media svg { width:0.7rem; height:0.7rem; }
.rl-tag { grid-column:3; grid-row:1; justify-self:end; align-self:center; font-family:var(--font-mono); font-size:var(--micro-size); font-weight:600;
    letter-spacing: 0; padding:0.26rem 0.5rem 0.26rem 0.42rem; white-space:nowrap;
    display:inline-flex; align-items:center; gap:0.3rem;
    clip-path:polygon(0 0, calc(100% - 0.34rem) 0, 100% 0.34rem, 100% 100%, 0 100%); }
.rl-tag::before { content:""; width:0.3rem; height:0.3rem; background:currentColor; }
.rl-tag--approved { color:var(--success);   background:color-mix(in srgb,var(--success) 15%,transparent); }
.rl-tag--rework { color:var(--primary);   background:color-mix(in srgb,var(--primary) 15%,transparent); }
.rl-tag--rejected { color:var(--secondary); background:color-mix(in srgb,var(--secondary) 15%,transparent); }
.rl-tag--submitted { color:var(--primary);   background:color-mix(in srgb,var(--primary) 15%,transparent); }
.rl-tag--draft { color:var(--text-muted);background:var(--bg-elevated); }
@media (min-width: 30em) {
    /* Широкий экран: объект встаёт РЯДОМ с автором, а не под ним. Двухрядная
       раскладка нужна только телефону — там места правее автора нет. На планшете
       и десктопе правая половина строки пустовала, а объект уезжал во второй ряд
       (клиент: «почему тут лукас во втором ряду, когда справа свободно»).
       minmax(0,…) обеим текстовым колонкам, иначе длинное имя не даёт сжаться и
       тег статуса выдавливается за край. */
    /* Заголовок работ важнее подписи «автор · объект», поэтому забирает
           большую долю: при 1.2fr он обрывался на третьем слове. */
    .rl-row { grid-template-columns: 3.4rem minmax(0, 1.8fr) minmax(0, 1fr) auto; }
    /* Рельса в одну строку: на телефоне время и глиф стоят столбиком, и в
           однорядной раскладке этот столбик центрируется как блок — время
           уезжает выше строки имени. В ряд они садятся на одну ось. */
    .rl-rail {
        grid-row: 1;
        flex-direction: row;
        align-items: center;
        justify-content: flex-end;
        gap: 0.4rem;
    }
    .rl-t { line-height: 1; }
    .rl-who { grid-column: 2; grid-row: 1; display: block; white-space: nowrap; text-overflow: ellipsis; }
    .rl-sub { grid-column: 3; grid-row: 1; }
    .rl-tag { grid-column: 4; grid-row: 1; justify-self: start; }
    .rl-obj { max-width: none; }
}
/* Complaint status tags (ledger) */
.rl-tag--c-new { color:var(--secondary); background:color-mix(in srgb,var(--secondary) 15%,transparent); }
.rl-tag--c-in_progress { color:var(--primary);   background:color-mix(in srgb,var(--primary) 15%,transparent); }
.rl-tag--c-resolved { color:var(--success);   background:color-mix(in srgb,var(--success) 15%,transparent); }
.rl-tag--c-closed { color:var(--text-muted); background:var(--bg-elevated); }
/* (.rl-by слит с правилом из task-ledger блока ниже, task-044.) */
/* Fine violation-type tags (ledger). Safety = hi-vis (тревога), остальное — тон primary/muted. */
.rl-tag--f-safety { color:var(--secondary); background:color-mix(in srgb,var(--secondary) 15%,transparent); }
.rl-tag--f-cleanliness { color:var(--primary);   background:color-mix(in srgb,var(--primary) 15%,transparent); }
.rl-tag--f-tardiness { color:var(--primary);   background:color-mix(in srgb,var(--primary) 15%,transparent); }
.rl-tag--f-other { color:var(--text-muted);background:var(--bg-elevated); }
/* «Показати ще» — росте вікно ledger'а на +20, перерендер регіону. */
.rl-more { display:block; width:100%; margin:0.9rem 0 0; padding:0.75rem 1rem;
    font-family:var(--font-mono); font-size: var(--fs-xs); font-weight:600; letter-spacing: 0;
    color:var(--text-secondary); background:var(--bg-surface); border:0.0625rem solid var(--border);
    cursor:pointer; transition:border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out); }
.rl-amt { font-family:var(--font-mono); font-weight:700; color:var(--text-primary); font-variant-numeric:tabular-nums; }
.rl-paid { color:var(--success); font-size: var(--micro-size); letter-spacing: 0; }
.rl-active { color:var(--secondary); font-size: var(--micro-size); letter-spacing: 0; }
/* Force-strip the inner box of the search input (глобальный input-бордер бил
   .lf-search-input по специфичности → двойной бокс). */
.lf-search input.lf-search-input {
    border: 0; background: transparent; box-shadow: none;
    padding: 0; margin: 0; height: auto; border-radius: 0;
}
.tsk-search input.tsk-search-input {
    border: 0; background: transparent; box-shadow: none; padding: 0; margin: 0; height: auto;
    font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--text-primary); outline: none; width: 100%;
}
/* Task ledger: priority dot in rail · deadline chip · task status tags */
/* Пріоритет словом, не крапкою зі світінням (каталог ШІ-патернів п.2, п.6; 29.09). Звичайний — не пишемо. */
.rl-prio { flex: 0 0 auto; font-family: var(--font-mono); font-size: var(--micro-size); letter-spacing: 0.04em; text-transform: uppercase; font-weight: 700; color: var(--text-secondary); }
.rl-prio--critical { color: var(--late, var(--secondary)); }
.rl-prio--high,
.fm-voice:hover,
.inspector-action .btn,
.gantt-label[data-status="completed"],
.wk-task[data-status="completed"],
.estimate-stage-qtag.fb-tag--in_progress,
.ntf-tgl.is-on,
.sch-grip:hover,
.sch-grip:focus-visible,
.dt-cal:hover,
.pp-grp-nav a b { color: var(--text-primary); }
.rl-due { display: inline-flex; align-items: center; gap: 0.2rem; flex:0 0 auto; white-space:nowrap; }
.rl-due svg { width: 0.72rem; height: 0.72rem; opacity: 0.7; flex:0 0 auto; }
.rl-by { flex:1 1 auto; min-width:0; color:var(--text-muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.rl-tag--t-open { color: var(--text-secondary); background: var(--bg-elevated); }
/* «В работе» — принятая задача: живое состояние, тот же язык, что submitted,
   но своим цветом, чтобы ПМ с одного взгляда видел, что увидели и взяли. */
.rl-tag--t-in_progress { color: var(--accent, var(--primary)); background: color-mix(in srgb,var(--accent, var(--primary)) 15%,transparent); }
.rl-tag--t-submitted { color: var(--primary);   background: color-mix(in srgb,var(--primary) 15%,transparent); }
.rl-tag--t-accepted { color: var(--success);   background: color-mix(in srgb,var(--success) 15%,transparent); }
.rl-tag--t-rework { color: var(--secondary); background: color-mix(in srgb,var(--secondary) 15%,transparent); }
.rl-tag--t-cancelled { color: var(--text-muted); background: var(--bg-elevated); }
/* Автор в подстроке журнала — рядом с объектом, тем же служебным шрифтом.
   Появляется только когда крупную строку занял заголовок отчёта. */
.rl-au { flex:0 0 auto; color:var(--text-secondary); }
.rl-au::after { content:"·"; margin:0 0.35rem; color:var(--text-muted); }
/* ── Панель дій /tasks: «+ Додати» / «Список задач» / «Надиктувати» ──────
   Три рівні кнопки в одному рядку (клієнт: «+ ДОБАВИТЬ» ламався на два
   рядки на телефоні, «Список задач» узагалі не було видно поруч).
   nowrap+min-height з .btn лишаються — тут тільки сітка й непереносність
   лейблів; якщо десь не влізе — коротшати переклад, не шрифт. */
.tsk-bar {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-sm);
    margin-bottom: var(--space-md);
}
/* Голосова кнопка ховається, якщо браузер не вміє MediaRecorder (app.js) —
   тоді ряд стає з двох колонок, не з дірою на місці третьої. */
/* ── Ряд 2 /tasks: «СНАБЖЕНИЕ» + «ФИЛЬТРЫ» на тій самій сітці ─────────────
   Раніше два окремих <details> без спільної сітки — кожен своєї (довільної)
   ширини, третій зайвий рядок над списком задач (~200 px висоти до першої
   задачі). Модифікатор на базі .tsk-bar: 2 колонки замість 3, той самий gap
   і margin-bottom, ті самі ліва/права межа, що й у ряду з кнопками. */
.tsk-bar:has(#tsk-voice[hidden]),
.tsk-bar--2col { grid-template-columns: repeat(2, 1fr); }
/* Клієнт: «Список задач» / «Надиктувати» — голий текст без рамки, «незрозуміло,
   що це кнопка». Даємо їм ту саму рамку, що вже носять чипи «СНАБЖЕНИЕ» /
   «ФИЛЬТРЫ» рядком нижче (.lf-fold-sum) — той самий border/bg, без radius. */
.tsk-bar .btn-secondary {
    border: 0.0625rem solid var(--border);
    background: var(--bg-surface);
    justify-content: center;
}
/* Чіп займає всю комірку і висоту .btn (2.75rem = 44 px) — інакше ряди
   різняться висотою всупереч спільній сітці. */
.tsk-bar--2col .lf-fold-sum {
    width: 100%;
    box-sizing: border-box;
    min-height: 2.75rem;
    justify-content: center;
    white-space: nowrap;
}
.ik-scan {
    position: relative;
    width: 100%;
    height: 0.1875rem;
    overflow: hidden;
    background: var(--border);
}
.ik-scan-seg {
    position: absolute;
    inset: 0 auto 0 0;
    width: 28%;
    background: var(--primary);
    animation: ik-scan-move 1.1s var(--mx-ease) infinite;
}
@keyframes ik-scan-move {
    from { transform: translateX(-100%); }
    to { transform: translateX(460%); }
}
.ik-wait-line {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-sm);
    margin: var(--space-xs) 0 0;
    font-family: var(--font-mono);
    font-size: var(--micro-size);
    color: var(--text-muted);
}
.ik-wait-time {
    font-variant-numeric: tabular-nums;
    letter-spacing: 0;
    color: var(--text-secondary);
    flex-shrink: 0;
}
.ik-wait-files {
    margin: 0.25rem 0 0;
    font-family: var(--font-mono);
    font-size: var(--micro-size);
    letter-spacing: 0;
    color: var(--text-muted);
}
@media (prefers-reduced-motion: reduce) {
    /* Не «коротша петля» — вимкнена: сегмент завмирає на старті. */
    .ik-scan-seg { animation: none; transform: none; }
}
/* ── Голос → задачи ───────────────────────────────────────────────────────
   Состояние записи — сигнальный цвет и пульс рамки: на стройке кнопку
   видно с вытянутой руки. */
#tsk-voice { display: inline-flex; align-items: center; gap: 0.4rem; }
.tsk-voice--rec {
    color: var(--secondary) !important;
    border-color: var(--secondary) !important;
}
.pf-rr-status { font-size: var(--fs-sm); line-height: 1.5; margin-bottom: var(--space-sm); }
.pf-rr-meta,
.chat-msg--pending .chat-msg-status,
.rl-tally .k,
.sch-field-lbl {
    font-family: var(--font-mono); font-size: var(--micro-size);
    letter-spacing: 0; color: var(--text-muted);
}
/* Разделитель дня в журнале — крупнее по смыслу, поэтому штриховой.
   flex:1 слит из верхнего дубля (task-044). */
.rl-line {
    flex: 1;
    height: 0.0625rem;
    background: var(--rule-dash);
    background-size: var(--rule-dash-size);
    background-repeat: repeat-x;
}
/* ── Заявка снабжению (= задача, слито 11.08) ─────────────────────────────
   Свёрнутая форма под тулбаром задач: объект + «что нужно». Исполнителей
   собирает сервер по ролям — прораб не думает, кто в снабжении. */
.tsk-supply { margin-bottom: var(--space-md); }
/* У ряду 2 (.tsk-bar--2col) нижній відступ дає сам грід — тут інша комірка. */
.tsk-bar--2col > .tsk-supply { margin-bottom: 0; }
.tsk-supply-form { display: flex; gap: var(--space-sm); flex-wrap: wrap; margin-top: var(--space-sm); }
/* Скоуплено под schedule (task-044): без скоупа правило перебивало .wk-label
   weekly-отчёта (pages.css «Form» кластер) — там своя типографика. */
.wk-nav .wk-label {
    font-family: var(--font-mono); font-size: var(--micro-size);
    color: var(--text-secondary); letter-spacing: 0;
}
.wk-daylink:hover,
.wk-daylink:focus-visible,
.reply-cancel:hover,
.reply-cancel:focus-visible { color: var(--primary); outline: none; }
.wk-note:focus-visible, .wk-workers:focus-visible { outline: none; border-color: var(--primary); }
.wk-save:hover, .wk-save:focus-visible { border-color: var(--primary); color: var(--primary); outline: none; }
.wk-del:hover, .wk-del:focus-visible { border-color: var(--secondary); color: var(--secondary); outline: none; }
/* ── Режим выбора задач ──────────────────────────────────────────────────
   Чекбоксы появляются только в режиме «Выбрать» (кнопка над списком);
   в обычном виде список остаётся журналом без служебных элементов. */
.tsk-bulk { display: flex; gap: var(--space-sm); margin-bottom: var(--space-sm); }
.fm-guide-open { font-family: var(--font-mono); font-size: var(--fs-xs); letter-spacing: 0; }
.fm-acc-sep { padding: var(--space-xs) var(--space-sm); font-family: var(--font-mono); font-size: var(--micro-size, 0.625rem); letter-spacing: 0; color: var(--text-secondary); }
.fm-board-col-pick { font-size: var(--fs-xs); min-height: 2rem; padding: 0.1rem 0.35rem; }
@media (min-width: 68.8125em) {
    /* ── Шапка на десктопе: без дублей, «назад» слева (22.09.2026) ────────────
       1. Пузырь сообщений справа вёл на тот же /messages, что и пункт меню
          «Сообщения», — после того как пункт получил правильный значок `chat`,
          дубль стало видно глазом. На телефоне пузырь уже прятался (там есть
          вкладка «Чат»), теперь и на десктопе; счётчик непрочитанных переехал
          на сам пункт меню (base.html, опрос раз в 30 с).
       2. Кнопка «назад» стояла в правом краю, за колокольчиком: у правой группы
          порядок 20, а у кнопки его не было задано, и она шла следом. Назад — это
          движение влево, её место первым в строке, до логотипа — как на телефоне. */
    #fm-dm-bell { display: none; }
}
/* ── Дошка задач об'єкта (/tasks/board): колонки за статусом ───────────── */
.tb-cols { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-sm); align-items: start; }
.tb-col { border: 0.0625rem solid var(--border); background: var(--bg-surface); min-height: 12rem; display: flex; flex-direction: column; }
.tb-col-head { display: flex; justify-content: space-between; align-items: center; padding: 0.5rem var(--space-sm); border-bottom: 0.0625rem solid var(--border); font-family: var(--font-mono); font-size: var(--micro-size); letter-spacing: 0; }
.tb-col-n { color: var(--text-secondary); }
.tb-col-body { padding: var(--space-xs); display: flex; flex-direction: column; gap: var(--space-xs); flex: 1; }
.tb-col.can-drop { outline: 0.0625rem dashed var(--primary); }
.tb-card { --accent-color: var(--border); border: 0.0625rem solid var(--border); background: var(--bg-base); padding: 0.55rem 0.6rem; }
.tb-card.assignment-high { --accent-color: var(--primary); }
.tb-card-title { display: block; color: inherit; text-decoration: none; font-size: var(--fs-sm); line-height: 1.3; margin-bottom: 0.3rem; }
.tb-card-meta { display: flex; flex-wrap: wrap; gap: 0.3rem 0.6rem; font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--text-secondary); }
.tb-moves { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.45rem; }
.tb-move { background: transparent; border: 0.0625rem solid var(--border); color: var(--text-secondary); font-family: var(--font-mono); font-size: var(--micro-size); letter-spacing: 0; padding: 0.25rem 0.45rem; cursor: pointer; }
.tb-empty { color: var(--text-muted); text-align: center; padding: var(--space-md) 0; }
@media (max-width: 64em) {
    .tb-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 48em) {
    /* Телефон: колонки стрічкою зі snap, одна колонка на екран з хвостом наступної. */
    .tb-cols { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; gap: var(--space-sm); -webkit-overflow-scrolling: touch; padding-bottom: var(--space-xs); }
    .tb-col { flex: 0 0 84%; scroll-snap-align: start; }
    .tb-card[draggable="true"] { cursor: default; }
}
/* ═══════════════════════════════════════════════════════════════════════════
   ЛИСТ (23.09.2026, Артём: «брутализм и микроразметка по делу, но пахнет
   ИИ»). Шар поверх усього: знімає шаблонні прийоми (моно-капс з розрядкою на
   кожній підписі, крапки-роздільники, кремова земля, помаранч на всіх
   кнопках) і дає стройці її власну лексику: щитова гарнітура Fira Sans
   Condensed, бетонна земля, чорна дія, помаранч лише як сигнал, рамка
   аркуша 3 px, стрічка небезпеки на простроченому, штамп аркуша внизу.
   Файл шрифтів: assets-src/fonts-full (Fira Sans, OFL), сабсет latin+cyr.
   ═══════════════════════════════════════════════════════════════════════════ */
@font-face { font-family: 'Fira Sans'; font-style: normal; font-weight: 400; font-display: swap; src: url('/fonts/FiraSans-Regular.woff2?v=1') format('woff2'); }
@font-face { font-family: 'Fira Sans'; font-style: normal; font-weight: 500; font-display: swap; src: url('/fonts/FiraSans-Medium.woff2?v=1') format('woff2'); }
@font-face { font-family: 'Fira Sans'; font-style: normal; font-weight: 600; font-display: swap; src: url('/fonts/FiraSans-SemiBold.woff2?v=1') format('woff2'); }
@font-face { font-family: 'Fira Sans'; font-style: normal; font-weight: 700; font-display: swap; src: url('/fonts/FiraSans-Bold.woff2?v=1') format('woff2'); }
@font-face { font-family: 'Fira Sans Condensed'; font-style: normal; font-weight: 600; font-display: swap; src: url('/fonts/FiraSansCondensed-SemiBold.woff2?v=1') format('woff2'); }
@font-face { font-family: 'Fira Sans Condensed'; font-style: normal; font-weight: 700; font-display: swap; src: url('/fonts/FiraSansCondensed-Bold.woff2?v=1') format('woff2'); }
/* ── Аудит ui-ux-pro-max (23.09.2026): контраст, третій колір, фокус, тап-цілі ── */
/* Ролі кольору: помаранч = сигнал; посилання й інформація = «креслярський синій»
   (каталог Construction/Architecture: grey + safety orange + blueprint blue).
   Текстові варіанти сигнальних кольорів дотягнуті до 4.5:1 у своїй темі. */
/* Поля вводу: один фокус, не два (Артём 23.09: «подвійна рамка виглядає убого»).
   Рамка поля стає синьою, кільце-outline без відступу, помаранчевого світіння нема. */
:root {
    --font-sans: 'Fira Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
    --font-display: 'Fira Sans Condensed', 'Fira Sans', system-ui, sans-serif;
    /* Підпис читається в рукавиці на сонці: не менше 13 px. */
    --micro-size: 0.8125rem;
    --sheet-rule: 0.1875rem;
    --link: #7fb2e5;
    --hazard-text: #ff5a1f;
    --success-text: #6fb583;
    --focus-ring: transparent;
}
:root[data-theme="light"] { --bg-base: #e5e5e2; --bg-elevated: #d9d9d5; --border: #c8c8c3; --text-secondary: #4a4a46; --text-muted: #5e5e59; --link: #1f4e79; --hazard-text: #b53a0f; --success-text: #3f6f4f; --primary: #c2410c; --success: #356140; --focus-ring: rgba(194, 65, 12, 0.3); --secondary: #b53a0f; --late: #b3261e; --plan: #8f8f89; }
/* Хром — чистий чорний, не «майже». */
.header,
.fm-bottombar,
.header::after { background: var(--black); }
/* ── Тип: гарнітура з дорожніх знаків, у строчному регістрі, без розрядки ── */
body { font-family: var(--font-sans); font-variant-numeric: tabular-nums; }
/* ── Дія чорна (на темній темі біла), помаранч лишається сигналом ── */
.btn { font-size: var(--fs-sm); font-weight: 600; padding: 0.6rem var(--space-md); min-height: 2.75rem; }
.btn-sm { min-height: var(--tap-target); padding: 0.35rem 0.75rem; }
@media (min-width: 48em) {
    .btn-sm { min-height: 2.25rem; }
}
.btn-primary:hover { background: var(--text-primary); opacity: 0.88; }
.tb-card.assignment-normal { --accent-color: var(--border); }
.tb-move:hover { background: var(--text-primary); color: var(--bg-base); border-color: var(--text-primary); }
.tb-col.can-drop { outline-color: var(--text-primary); }
.rl-tag { border-color: var(--border); color: var(--text-secondary); }
/* Налаштування → Каталоги: список усіх адмін-сіток. */
.cat-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr)); gap: 0.5rem; }
/* «На мені за графіком» у «Задачах» (28.09). */
.tsk-mine { margin-bottom: var(--space-lg); }
.tsk-mine-row a { color: var(--text-primary); font-weight: 600; overflow-wrap: anywhere; }
.tb-src a[aria-current="page"] { border-color: var(--text-primary); color: var(--text-primary); font-weight: 600; }
@media (min-width: 64em) {
    .tb-filters .tb-q { grid-column: auto; }
}
.dl-tbl th, .dl-tbl td { padding: 0.375rem 0.5rem; border-bottom: 0.0625rem solid var(--border); text-align: left; vertical-align: middle; }
.dl-tbl thead th { color: var(--text-secondary); font-weight: 600; white-space: nowrap; }
.dl-tbl tbody th { font-weight: 600; white-space: nowrap; position: sticky; left: 0; background: var(--bg-surface); }
.sch-save[data-state="failed"] { color: var(--invalid); border-color: var(--invalid); font-weight: 600; }
