:root {
    --ink: #0f0f10;
    --muted: #5f6166;
    --faint: #8a8d93;
    --line: #e2e3e6;
    --bg: #ffffff;
    --soft: #f5f6f7;
    --ok: #0f6b33;
    --ok-bg: #e3f3e9;
    --warn: #7a5200;
    --warn-bg: #fff2d4;
    --bad: #a81f1a;
    --bad-bg: #fde7e5;
    --radius: 14px;
    --mono: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font: 16px/1.6 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
}

a { color: var(--ink); text-underline-offset: 2px; }

code {
    font-family: var(--mono);
    font-size: .88em;
    background: var(--soft);
    padding: 1px 5px;
    border-radius: 5px;
}

/* --- Шапка --- */

.topbar {
    position: sticky;
    top: 0;
    z-index: 10;
    background: rgba(255, 255, 255, .94);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--line);
}

.topbar-inner {
    max-width: 1100px;
    margin: 0 auto;
    padding: 12px 20px;
    display: flex;
    align-items: center;
    gap: 24px;
    flex-wrap: wrap;
}

.brand {
    display: flex;
    align-items: center;
    gap: 12px;
    text-decoration: none;
    margin-right: auto;
}

.brand img {
    height: 38px;
    width: auto;
    display: block;
    flex: none;
}

.brand-text {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.brand-name {
    display: block;
    font-size: 20px;
    font-weight: 800;
    letter-spacing: .1em;
    line-height: 1;
}

.brand-sub {
    display: block;
    font-size: 10.5px;
    letter-spacing: .3em;
    color: var(--faint);
    text-transform: uppercase;
    line-height: 1;
}

nav { display: flex; gap: 4px; flex-wrap: wrap; }

nav a {
    text-decoration: none;
    padding: 9px 16px;
    border-radius: 999px;
    font-size: 15px;
    font-weight: 500;
    color: var(--muted);
    white-space: nowrap;
}

nav a:hover { background: var(--soft); color: var(--ink); }
nav a.active { background: var(--ink); color: #fff; font-weight: 600; }

/* --- Контент --- */

main { max-width: 1100px; margin: 0 auto; padding: 34px 20px 80px; }

h1 {
    font-size: 30px;
    font-weight: 800;
    letter-spacing: -.022em;
    margin: 0 0 8px;
    line-height: 1.2;
}

h2 {
    font-size: 15px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--muted);
    margin: 38px 0 14px;
}

.lede { color: var(--muted); margin: 0 0 28px; max-width: 72ch; }

.card {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 24px;
    margin-bottom: 18px;
    background: #fff;
}

.card > h2:first-child { margin-top: 0; }
.card.scroll { padding: 0; }

/* --- Плитки показателей --- */

.grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); }

.stat {
    background: var(--soft);
    border-radius: var(--radius);
    padding: 18px 20px;
    border: 1px solid transparent;
}

.stat .k {
    font-size: 11.5px;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--muted);
    font-weight: 600;
}

.stat .v {
    font-size: 30px;
    font-weight: 800;
    letter-spacing: -.025em;
    margin-top: 6px;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.stat .n { font-size: 13px; color: var(--muted); margin-top: 5px; line-height: 1.4; }
.stat .v.mono { font-family: var(--mono); font-size: 23px; letter-spacing: 0; }

.stat.ok   { background: var(--ok-bg);   border-color: #c6e4d2; }
.stat.ok   .v, .stat.ok   .k { color: var(--ok); }
.stat.warn { background: var(--warn-bg); border-color: #f0dca8; }
.stat.warn .v, .stat.warn .k { color: var(--warn); }
.stat.bad  { background: var(--bad-bg);  border-color: #f3c9c6; }
.stat.bad  .v, .stat.bad  .k { color: var(--bad); }
.stat.ok .n, .stat.warn .n, .stat.bad .n { color: inherit; opacity: .78; }

/* --- Формы --- */

label.field, .field { display: block; margin-bottom: 20px; }
label.field > span, .field > span { display: block; font-weight: 650; margin-bottom: 5px; font-size: 15.5px; }
label.field > small, .field > small {
    display: block;
    color: var(--muted);
    font-size: 13.5px;
    line-height: 1.5;
    margin-bottom: 9px;
}

input[type=file], input[type=text], input[type=password] {
    width: 100%;
    padding: 12px 14px;
    border: 1px solid var(--line);
    border-radius: 10px;
    font: inherit;
    background: #fff;
    color: var(--ink);
}

input[type=text]:focus, input[type=password]:focus, input[type=file]:focus {
    outline: 2px solid var(--ink);
    outline-offset: -1px;
    border-color: var(--ink);
}

input[type=file] { padding: 9px 12px; }

input[type=file]::file-selector-button {
    border: 0;
    background: var(--ink);
    color: #fff;
    padding: 9px 16px;
    border-radius: 999px;
    margin-right: 13px;
    font: inherit;
    font-weight: 500;
    cursor: pointer;
}

.btn {
    display: inline-block;
    background: var(--ink);
    color: #fff;
    border: 1px solid var(--ink);
    padding: 12px 28px;
    border-radius: 999px;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
    line-height: 1.3;
}

.btn:hover { background: #000; }
.btn[disabled] { opacity: .4; cursor: not-allowed; }
.btn.ghost { background: #fff; color: var(--ink); border-color: var(--line); }
.btn.ghost:hover { background: var(--soft); border-color: var(--ink); }
.btn-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.btn-row form { margin: 0; display: contents; }

/* Удаление необратимо — отделяем его цветом от обычных действий. */
.btn.ghost.danger { color: var(--bad); border-color: #f0c5c2; }
.btn.ghost.danger:hover { background: var(--bad-bg); border-color: var(--bad); }

/* Кнопка, выглядящая ссылкой: нужна, чтобы удаление шло через POST-форму. */
.linkbtn {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 2px;
    color: var(--ink);
}

.linkbtn.danger { color: var(--bad); }

td.actions { white-space: nowrap; }
td.actions form { display: inline; margin: 0; }
td.actions > * + * { margin-left: 12px; }

/* --- Таблицы --- */

.scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

table { border-collapse: collapse; width: 100%; font-size: 14.5px; }

th, td { text-align: left; padding: 11px 14px; border-bottom: 1px solid var(--line); vertical-align: top; }
tr:last-child td { border-bottom: 0; }

thead th, table tr:first-child th {
    font-size: 11.5px;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--muted);
    font-weight: 700;
    white-space: nowrap;
    background: var(--soft);
}

td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
td.sku { font-family: var(--mono); font-size: 13px; white-space: nowrap; }

/* Номер полки — то, ради чего всё затевалось. */
td.loc {
    font-family: var(--mono);
    font-weight: 700;
    font-size: 15px;
}

/* Фиксированная раскладка: иначе длинные значения Sublocation(s) съедают
   колонку с названием, и оно ломается на четыре строки. */
table.pages { table-layout: fixed; }

/* Вторая и следующие позиции одной этикетки — без верхней границы,
   чтобы они читались как продолжение строки, а не как новая страница. */
tr.row-cont td { border-top: 0; }
tr.row-cont td.page-no { color: transparent; }

td.order { font-weight: 600; }

/* Получатель: имя читается, адрес — подсказка под ним. Длинные улицы
   переносим, а не растягиваем колонку: раскладка фиксированная. */
td.who { font-size: 13px; line-height: 1.35; overflow-wrap: anywhere; }
td.who b { font-weight: 700; }

tr.row-warn { background: var(--warn-bg); }
tr.row-bad  { background: var(--bad-bg); }

.tag {
    display: inline-block;
    font-size: 12px;
    font-weight: 650;
    padding: 3px 10px;
    border-radius: 999px;
    background: var(--soft);
    color: var(--muted);
    white-space: nowrap;
}

.tag.ok   { background: var(--ok-bg);   color: var(--ok); }
.tag.warn { background: #fde8bc;        color: var(--warn); }
.tag.bad  { background: #fad5d2;        color: var(--bad); }

/* --- Сообщения --- */

.msg {
    padding: 14px 18px;
    border-radius: 10px;
    margin-bottom: 20px;
    font-size: 15px;
    border: 1px solid transparent;
}

.msg.ok   { background: var(--ok-bg);   color: var(--ok);   border-color: #c6e4d2; }
.msg.warn { background: var(--warn-bg); color: var(--warn); border-color: #f0dca8; }
.msg.bad  { background: var(--bad-bg);  color: var(--bad);  border-color: #f3c9c6; }
.msg a { color: inherit; }

.muted { color: var(--muted); }
.small { font-size: 13px; line-height: 1.45; }

footer {
    border-top: 1px solid var(--line);
    padding: 26px 20px;
    text-align: center;
    color: var(--faint);
    font-size: 13px;
}

/* Длинные имена файлов не должны распирать страницу. */
.lede, td, .stat .n { overflow-wrap: anywhere; }

/* --- Телефон --- */

@media (max-width: 680px) {
    body { font-size: 15.5px; }
    .topbar-inner { padding: 11px 14px; gap: 10px; }
    .brand { margin-right: 0; }
    nav { width: 100%; gap: 2px; }
    nav a { padding: 8px 13px; font-size: 14.5px; }
    main { padding: 24px 14px 60px; }
    h1 { font-size: 25px; }
    h2 { margin-top: 30px; }
    .card { padding: 18px; }
    .stat .v { font-size: 26px; }
    .btn { width: 100%; text-align: center; }
    .btn-row { flex-direction: column; align-items: stretch; }

    /* Второстепенные таблицы просто прокручиваются вбок, а не сплющиваются. */
    .scroll table:not(.pages) { min-width: 620px; }
    .scroll table:not(.pages) th,
    .scroll table:not(.pages) td { padding: 10px 11px; }

    /* Две колонки вместо четырёх строк — сводка умещается в один экран. */
    .grid { grid-template-columns: 1fr 1fr; gap: 10px; }
    .stat { padding: 14px 15px; }

    /* Разбор по страницам — карточками: место хранения читается сразу,
       без горизонтальной прокрутки. Порядок внутри карточки меняем через
       order, чтобы разметка таблицы осталась нормальной для десктопа. */
    .pages, .pages tbody, .pages td { display: block; width: auto; }
    .pages colgroup, .pages thead { display: none; }

    .pages tr {
        display: flex;
        flex-direction: column;
        border-bottom: 1px solid var(--line);
        padding: 15px 17px;
        position: relative;
    }
    .pages tr:last-child { border-bottom: 0; }

    .pages td { border: 0; padding: 0; }

    /* Полка — сразу под номером страницы, до названия. */
    .pages td.page-no { order: 1; }
    .pages td.loc     { order: 2; }
    .pages td.desc    { order: 3; }
    .pages td.sku     { order: 4; }
    .pages td.who     { order: 5; }

    .pages td.page-no {
        text-align: left;
        font-size: 11.5px;
        font-weight: 700;
        letter-spacing: .08em;
        text-transform: uppercase;
        color: var(--muted);
    }
    .pages td.page-no::before { content: "Страница "; }

    .pages td.loc {
        font-size: 21px;
        line-height: 1.25;
        margin: 5px 0 6px;
        white-space: normal;
    }

    .pages td.desc { font-size: 14.5px; color: var(--muted); line-height: 1.45; }

    .pages td.sku { font-size: 12.5px; color: var(--faint); margin-top: 6px; }

    /* В карточке получателя не хватает подписи: на широком экране её
       даёт шапка таблицы, а здесь шапки нет. */
    .pages td.who { font-size: 13px; margin-top: 6px; }
    .pages td.who::before {
        content: attr(data-label) ": ";
        color: var(--faint);
    }

    /* Статус — ярлыком в правом верхнем углу карточки. */
    .pages td.status { position: absolute; top: 13px; right: 15px; text-align: right; }
    .pages td.status .small { margin-top: 4px; max-width: 150px; }
}

/* --- Шапка: язык и выход --- */

/* Тема, язык и выход — в правом верхнем углу, в одной строке с логотипом.
   Меню из девяти пунктов в 1100 пикселей рядом с ними всё равно не влезает,
   поэтому оно честно занимает свою строку целиком, а не отжимает блок вниз
   третьей строкой, как было. */
.brand { order: 1; }
.topbar-end { order: 2; margin-left: auto; }
nav { order: 3; flex-basis: 100%; }

.topbar-end { display: flex; align-items: center; gap: 14px; }

.lang { display: inline-flex; border: 1px solid var(--line); border-radius: 999px; overflow: hidden; }

.lang a {
    text-decoration: none;
    padding: 6px 12px;
    font-size: 12.5px;
    font-weight: 700;
    letter-spacing: .04em;
    color: var(--muted);
}

.lang a:hover { background: var(--soft); color: var(--ink); }
.lang a.active { background: var(--ink); color: #fff; }

/* «Админ» и «Выйти» — такие же овалы, как переключатель языка: три разные
   по виду ссылки в одном углу выглядели случайным набором. Размеры взяты
   у .lang a, чтобы высота совпадала до пикселя. */
.signout {
    text-decoration: none;
    padding: 6px 12px;
    font-size: 12.5px;
    font-weight: 700;
    letter-spacing: .04em;
    color: var(--muted);
    border: 1px solid var(--line);
    border-radius: 999px;
    white-space: nowrap;
}

.signout:hover { background: var(--soft); color: var(--ink); }

/* --- Страница входа --- */

body.signin { background: var(--soft); }

.signin-main {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 28px 18px;
    max-width: none;
}

.signin-card {
    width: 100%;
    max-width: 430px;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 22px;
    padding: 40px 38px 32px;
    text-align: center;
    box-shadow: 0 18px 50px rgba(15, 15, 16, .07);
}

.signin-mark { width: 150px; height: auto; display: block; margin: 0 auto 18px; }

.signin-brand { line-height: 1; margin-bottom: 10px; }

.signin-name {
    display: block;
    font-size: 30px;
    font-weight: 800;
    letter-spacing: .12em;
}

.signin-sub {
    display: block;
    margin-top: 6px;
    font-size: 12px;
    letter-spacing: .34em;
    text-transform: uppercase;
    color: var(--faint);
}

.signin-lede { color: var(--muted); font-size: 14.5px; margin: 0 0 26px; }

.signin-card .field { text-align: left; }
.signin-card .msg { text-align: left; }
.signin-btn { width: 100%; margin-top: 4px; }

.signin-lang {
    margin-top: 24px;
    display: flex;
    justify-content: center;
    gap: 6px;
}

.signin-lang a {
    text-decoration: none;
    font-size: 12.5px;
    font-weight: 700;
    letter-spacing: .04em;
    color: var(--faint);
    padding: 5px 11px;
    border-radius: 999px;
}

.signin-lang a.active { background: var(--ink); color: #fff; }

/* Переключатель темы на входе — такая же пилюля, как языки. */
.signin-lang a:first-child {
    border: 1px solid var(--line);
    font-size: 14px;
    line-height: 1;
    padding: 6px 10px;
}

/* --- Обложки товаров в таблице задания --- */

td.cover { width: 56px; padding-right: 0; }

.cover-thumb {
    display: block;
    width: 44px;
    height: 44px;
    object-fit: cover;
    border-radius: 7px;
    border: 1px solid var(--line);
    background: var(--soft);
}

/* Обложка нашлась не для всякого товара — пустую рамку лучше спрятать. */
.cover-thumb:not([src]), .cover-thumb[src=""] { display: none; }

/* Увеличение по наведению, без клика — как в складской программе.
   Всплывашка живёт в <body>, а не рядом с картинкой: таблица прокручивается
   внутри .card.scroll, и любой вложенный элемент обрезался бы по её краю. */
#cover-zoom {
    position: fixed;
    z-index: 60;
    padding: 6px;
    border-radius: 12px;
    background: var(--card, #fff);
    border: 1px solid var(--line);
    box-shadow: 0 14px 40px rgba(0, 0, 0, .28);
    pointer-events: none;
    opacity: 0;
    transition: opacity .12s ease;
}

#cover-zoom.on { opacity: 1; }

#cover-zoom img {
    display: block;
    width: 260px;
    height: 260px;
    object-fit: contain;
    border-radius: 7px;
    background: var(--soft);
}

/* На тач-экранах наведения нет, а место всплывашка займёт. */
@media (hover: none) {
    #cover-zoom { display: none; }
}

@media (max-width: 680px) {
    /* Блок стоит в строке с логотипом и прижат к правому краю. Раньше он
       занимал всю ширину отдельной строкой — тогда он и висел под меню. */
    .topbar-end { width: auto; justify-content: flex-end; }
    .signin-card { padding: 32px 22px 26px; border-radius: 18px; }
    .signin-mark { width: 118px; }
    .signin-name { font-size: 26px; }
    .pages td.cover { padding: 0 0 8px; }
    .pages .cover-thumb { width: 54px; height: 54px; }
}

/* --- Тёмная тема ---
   Весь интерфейс построен на переменных, поэтому тема — это их подмена.
   Тему ставит сервер атрибутом data-theme на <html>, чтобы при загрузке
   страницы не мигало светлым. */

:root[data-theme="dark"] {
    --ink: #e9eaec;
    --muted: #a0a4ab;
    --faint: #767b84;
    --line: #2e3238;
    --bg: #15171a;
    --soft: #1e2126;
    --ok: #6ddc9a;
    --ok-bg: #16301f;
    --warn: #f0c36b;
    --warn-bg: #342a14;
    --bad: #f28b84;
    --bad-bg: #3a1e1c;
}

:root[data-theme="dark"] .topbar { background: rgba(21, 23, 26, .94); }
:root[data-theme="dark"] .card,
:root[data-theme="dark"] input[type=file],
:root[data-theme="dark"] input[type=text],
:root[data-theme="dark"] input[type=password] { background: #1a1d21; }

/* Чёрная кнопка на тёмном фоне не читается — делаем её светлой. */
:root[data-theme="dark"] .btn { background: var(--ink); color: #15171a; border-color: var(--ink); }
:root[data-theme="dark"] .btn:hover { background: #fff; }
:root[data-theme="dark"] .btn.ghost { background: transparent; color: var(--ink); border-color: var(--line); }
:root[data-theme="dark"] .btn.ghost:hover { background: var(--soft); }
:root[data-theme="dark"] .btn.ghost.danger { color: var(--bad); border-color: #5a2f2c; }
:root[data-theme="dark"] input[type=file]::file-selector-button { background: var(--ink); color: #15171a; }
:root[data-theme="dark"] .signout { border-color: var(--line); }
:root[data-theme="dark"] .signout:hover { background: var(--soft); color: var(--ink); }
:root[data-theme="dark"] nav a.active,
:root[data-theme="dark"] .lang a.active,
:root[data-theme="dark"] .signin-lang a.active { background: var(--ink); color: #15171a; }

:root[data-theme="dark"] body.signin { background: #101214; }
:root[data-theme="dark"] .signin-card { background: #1a1d21; box-shadow: 0 18px 50px rgba(0, 0, 0, .45); }
:root[data-theme="dark"] .cover-thumb { background: var(--soft); }

/* Переключатель темы — та же пилюля, что у языка. */
.theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;  /* как у овалов рядом: иначе ряд выглядит неровным */
    border: 1px solid var(--line);
    border-radius: 999px;
    text-decoration: none;
    font-size: 15px;
    line-height: 1;
    color: var(--muted);
}

.theme-toggle:hover { background: var(--soft); color: var(--ink); }

/* --- Прогресс задания --- */

.progress-card { padding: 22px 24px; }

.progress-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    margin-bottom: 12px;
    font-weight: 650;
}

.progress-count { font-variant-numeric: tabular-nums; color: var(--muted); font-weight: 600; }

.progress-track {
    height: 10px;
    border-radius: 999px;
    background: var(--soft);
    overflow: hidden;
}

.progress-fill {
    height: 100%;
    width: 2%;
    border-radius: 999px;
    background: var(--ink);
    transition: width .4s ease;
}

/* Пока идёт чтение файла, доля неизвестна — показываем бегущую полоску,
   иначе непонятно, работает программа или застряла. */
.progress-fill.indeterminate {
    width: 32%;
    animation: progress-wait 1.3s ease-in-out infinite alternate;
}

@keyframes progress-wait {
    from { margin-left: 0; }
    to   { margin-left: 68%; }
}

/* --- Своё поле выбора файла ---
   Родная подпись у <input type="file"> идёт от языка браузера, а не
   страницы, поэтому поле спрятано, а кнопку и имя файла рисуем сами. */

.filefield {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 9px 12px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: #fff;
    cursor: pointer;
}

.filefield:focus-within { outline: 2px solid var(--ink); outline-offset: -1px; }
.filefield input[type=file] { position: absolute; width: 1px; height: 1px; opacity: 0; }

.filefield-btn {
    flex: none;
    background: var(--ink);
    color: #fff;
    padding: 9px 16px;
    border-radius: 999px;
    font-weight: 500;
    font-size: 15px;
    white-space: nowrap;
}

.filefield-name { color: var(--muted); overflow-wrap: anywhere; }

/* Крестик прижат к правому краю поля — там его и ищут. */
.filefield-clear {
    flex: none;
    margin-left: auto;
    border: 0;
    background: transparent;
    color: var(--muted);
    font-size: 21px;
    line-height: 1;
    padding: 1px 7px 3px;
    border-radius: 999px;
    cursor: pointer;
}

.filefield-clear:hover { color: var(--ink); background: var(--soft); }

/* Полоса хода отправки. Появляется только на время работы: постоянная
   пустая шкала на форме выглядит так, будто что-то сломалось. */
.progress {
    height: 4px;
    margin-top: 12px;
    border-radius: 999px;
    background: var(--soft);
    overflow: hidden;
}

.progress-fill {
    height: 100%;
    width: 0;
    border-radius: 999px;
    background: var(--ink);
    transition: width .2s ease;
}

/* --- Напоминания по распорядку --- */

/* Карточки в правом нижнем углу: там они не закрывают ни таблицу, ни
   кнопки формы. На телефоне занимают ширину экрана — иначе текст дела
   сжимается в столбик по два слова. */
.reminders {
    position: fixed;
    right: 18px;
    bottom: 18px;
    z-index: 50;
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-width: 340px;
}

.remind {
    background: var(--card, #fff);
    border: 1px solid var(--line);
    border-left: 4px solid var(--ink);
    border-radius: 12px;
    padding: 12px 14px;
    box-shadow: 0 10px 28px rgba(0, 0, 0, .14);
}

.remind-head {
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--muted);
}

.remind-title { font-size: 15px; font-weight: 700; margin-top: 3px; }
.remind-what { font-size: 13px; color: var(--muted); margin-top: 4px; line-height: 1.4; }

.remind-row { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
/* На узком экране .btn растягивается на всю ширину — для карточки
   напоминания это лишнее: три кнопки встают столбиком и она занимает
   треть экрана. Здесь они делят строку. */
.remind-row .btn {
    padding: 6px 12px;
    font-size: 13px;
    text-decoration: none;
    width: auto;
    flex: 1 1 auto;
}

/* Короткая кнопка в узкой колонке таблицы не должна переноситься
   по слогам: «Отметит/ь» читается как опечатка. */
.btn.small { padding: 6px 12px; font-size: 13px; white-space: nowrap; }

.remind-more {
    align-self: flex-end;
    font-size: 12.5px;
    color: var(--muted);
    background: var(--card, #fff);
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: 5px 12px;
    text-decoration: none;
}

@media (max-width: 560px) {
    .reminders { left: 12px; right: 12px; bottom: 12px; max-width: none; }

    /* Надпись «STMEDIA Group» занимает полторы сотни пикселей, и из-за неё
       тема, язык и выход не помещались рядом с логотипом — уезжали своей
       строкой. На телефоне оставляем знак: он и так узнаётся. */
    .brand-text { display: none; }

    /* Овалы с подписями шире прежних ссылок, и в 340 пикселей весь блок
       опять не влезал. Ужимаем отступы, а не прячем подписи: «Выйти»
       и «Админ» должны оставаться читаемыми. */
    .topbar-end { gap: 7px; }
    .signout, .lang a { padding: 5px 9px; font-size: 12px; }
    .theme-toggle { width: 30px; height: 30px; }
    .signout, .lang { height: 30px; display: inline-flex; align-items: center; }
}

@media print { .reminders { display: none; } }

/* --- Распорядок и учёт часов --- */

table.routine tr.done td { color: var(--muted); }
table.routine input[type=time],
table.plain input[type=number],
table.plain input[type=text] {
    font: inherit;
    padding: 4px 7px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: transparent;
    color: inherit;
    max-width: 150px;
}

ol.steps { margin: 8px 0 0; padding-left: 20px; line-height: 1.55; }
ol.steps li, ul.steps li { margin-bottom: 6px; }
ul.steps { margin: 0; padding-left: 20px; line-height: 1.55; }

.faint { color: var(--faint); }

/* Строка добавления расхода: поля в ряд, на телефоне — в столбик. */
.row-fields { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.row-fields input, .row-fields select {
    font: inherit;
    padding: 8px 11px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: transparent;
    color: inherit;
    min-width: 120px;
}
.row-fields input[type=text]:first-child { min-width: 200px; flex: 1; }

/* --- Глазок у поля пароля --- */

.pw-wrap { display: flex; align-items: center; gap: 8px; }
.pw-wrap input { flex: 1; min-width: 0; }

.pw-eye {
    flex: none;
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--card);
    color: var(--muted);
    cursor: pointer;
}

.pw-eye:hover { color: var(--ink); }
.pw-eye.on { color: var(--ink); border-color: var(--ink); }

/* Перечёркнутый глаз — когда пароль скрыт, то есть по умолчанию. */
.pw-eye .slash { opacity: 1; }
.pw-eye.on .slash { opacity: 0; }

/* Распорядок на телефоне: три колонки в 390 пикселей не помещаются, и
   название дела ломается по два слова. Разворачиваем строку в карточку —
   тем же приёмом, что список страниц задания. */
@media (max-width: 560px) {
    table.routine, table.routine tbody, table.routine tr, table.routine td {
        display: block;
        width: auto;
    }

    table.routine thead { display: none; }

    table.routine tr {
        border-bottom: 1px solid var(--line);
        padding: 14px 2px;
    }

    table.routine tr:last-child { border-bottom: 0; }
    table.routine td { border: 0; padding: 0; }

    /* Время — строкой над делом, мелко: его читают реже, чем само дело. */
    table.routine td:first-child { margin-bottom: 8px; }
    table.routine td:first-child input[type=time] { max-width: 110px; }

    table.routine td:last-child { margin-top: 10px; }
}
table.plain select {
    font: inherit;
    padding: 4px 7px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: transparent;
    color: inherit;
}

:root[data-theme="dark"] .filefield { background: #1a1d21; }
:root[data-theme="dark"] .filefield-btn { background: var(--ink); color: #15171a; }

/* --- Схема склада --- */

.map-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    align-items: center;
    justify-content: space-between;
}

.map-wrap { padding: 14px; }

/* Лист в условных единицах: aspect-ratio задаётся из шаблона, ширина тянется
   под экран. Сетка нужна, чтобы блоки было к чему выравнивать на глаз. */
.map-sheet {
    position: relative;
    width: 100%;
    border: 2px solid var(--ink, #111);
    border-radius: 10px;
    background-color: var(--card, #fff);
    background-image:
        linear-gradient(to right, var(--line) 1px, transparent 1px),
        linear-gradient(to bottom, var(--line) 1px, transparent 1px);
    background-size: 5% 6.25%;
    overflow: hidden;
    touch-action: none;
    user-select: none;
}

.map-zone {
    position: absolute;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 3px;
    border: 2px solid var(--ink, #111);
    border-radius: 5px;
    background: var(--soft);
    cursor: grab;
    overflow: hidden;
}

.map-zone:active { cursor: grabbing; }
.map-zone.selected { outline: 3px solid #2f6fed; outline-offset: 2px; }
.map-zone.found { background: #fde68a; border-color: #b45309; }

.map-zone-title {
    font-weight: 700;
    font-size: 13px;
    line-height: 1.15;
    text-align: center;
    word-break: break-word;
}

/* Часть стеллажей на эскизе подписана вдоль, а не поперёк. */
.map-zone.rotated .map-zone-title { writing-mode: vertical-rl; }

.map-zone-count {
    position: absolute;
    top: 2px;
    right: 5px;
    font-size: 11px;
    opacity: .65;
}

.map-zone.kind-pallet { background: #e7f0ff; border-style: dashed; }
.map-zone.kind-area { background: transparent; border-style: dotted; }
.map-zone.kind-wall { background: var(--ink, #111); border-radius: 2px; }
.map-zone.kind-wall .map-zone-title { color: #fff; font-size: 11px; }

.map-handle {
    position: absolute;
    right: 0;
    bottom: 0;
    width: 15px;
    height: 15px;
    cursor: nwse-resize;
    background: linear-gradient(135deg, transparent 50%, var(--ink, #111) 50%);
}

.map-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; }

.map-panel-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.map-panel-head h2 { margin: 0; }
#map-panel-body { max-height: 340px; overflow: auto; }
#map-panel-body table { width: 100%; }

:root[data-theme="dark"] .map-sheet { border-color: var(--line); }
:root[data-theme="dark"] .map-zone { border-color: var(--line); }
:root[data-theme="dark"] .map-zone.kind-pallet { background: #1e2a44; }
:root[data-theme="dark"] .map-zone.found { background: #7c5e12; border-color: #fbbf24; }
:root[data-theme="dark"] .map-handle { background: linear-gradient(135deg, transparent 50%, var(--line) 50%); }

/* --- Остаток, объединённые заказы и Lasgo в таблице задания --- */

/* Остаток — свойство товара: минус значит, что его уже разобрали и на полке
   может не оказаться. Поэтому цифра, а не слово «ОК»: её видно сразу. */
.tag.stock {
    font-family: var(--mono);
    font-weight: 700;
    min-width: 34px;
    text-align: center;
}

.tag.qty {
    background: #fde68a;
    color: #7a5200;
    font-weight: 700;
}

.tag.lasgo {
    background: #e9d5ff;
    color: #5b21b6;
    font-weight: 700;
}

/* Цвет строки — про заказ, а не про товар, поэтому он мягче ячейки. */
.pages tr.row-combined > td { background: #fffaeb; }
.pages tr.row-lasgo > td { box-shadow: inset 3px 0 0 #a855f7; }
.pages tr.row-combined.row-lasgo > td { background: #fdf4ff; }

.legend {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 16px;
    align-items: center;
    font-size: 13px;
    color: var(--muted);
    margin: 10px 2px 0;
}

.legend .swatch {
    display: inline-block;
    width: 22px;
    height: 14px;
    border-radius: 4px;
    border: 1px solid var(--line);
    vertical-align: -2px;
}

.legend .swatch.row-combined { background: #fffaeb; }
.legend .swatch.row-lasgo { background: #fff; box-shadow: inset 3px 0 0 #a855f7; }

:root[data-theme="dark"] .pages tr.row-combined > td { background: #3a3218; }
:root[data-theme="dark"] .pages tr.row-combined.row-lasgo > td { background: #2f2340; }
:root[data-theme="dark"] .tag.qty { background: #6b5618; color: #fde68a; }
:root[data-theme="dark"] .tag.lasgo { background: #4c2a73; color: #e9d5ff; }
:root[data-theme="dark"] .legend .swatch.row-combined { background: #3a3218; }
:root[data-theme="dark"] .legend .swatch.row-lasgo { background: var(--card); }

/* Б/у товар лежит отдельно от нового — свой цвет, как у Lasgo. */
.tag.used { background: #cffafe; color: #155e75; font-weight: 700; }
.pages tr.row-used > td { box-shadow: inset 3px 0 0 #06b6d4; }
.legend .swatch.row-used { background: #fff; box-shadow: inset 3px 0 0 #06b6d4; }
:root[data-theme="dark"] .tag.used { background: #164e5c; color: #cffafe; }
:root[data-theme="dark"] .legend .swatch.row-used { background: var(--card); }

/* Pause-сток: придержанный товар, лежит отдельно. */
.tag.pause { background: #ffe4e6; color: #9f1239; font-weight: 700; }
.pages tr.row-pause > td { box-shadow: inset 3px 0 0 #f43f5e; }
.legend .swatch.row-pause { background: #fff; box-shadow: inset 3px 0 0 #f43f5e; }
:root[data-theme="dark"] .tag.pause { background: #6b1f33; color: #ffe4e6; }
:root[data-theme="dark"] .legend .swatch.row-pause { background: var(--card); }

/* --- Крупные обложки, панель печати, категории --- */

/* Картинку должно быть видно, не наводя мышь, и на распечатке тоже.
   Колонка задана в colgroup таблицы задания (152px) — ширина здесь её
   повторяет. Она чуть шире самой картинки: отступ справа держит SKU на
   расстоянии от обложки, и без запаса картинка сжималась бы. */
td.cover { width: 152px; padding-right: 12px; }

.cover-thumb { width: 120px; height: 120px; border-radius: 10px; }

/* Картинка не должна вылезать за колонку, какой бы та ни оказалась. */
.cover-thumb { max-width: 100%; }

/* --- Штрихкод в колонке SKU --------------------------------------------- */

/* По списку задания ходят со сканером, поэтому код рисуется в натуральную
   величину: EAN-13 рассчитан на 37.3 мм по ширине. Уже — и сканер начинает
   промахиваться, особенно с экрана. */
.ean-box {
    display: block;
    width: 160px;
    max-width: 100%;
    margin: 5px 0 2px;
    padding: 2px 0;
    background: #fff;        /* код читается только на белом */
    border-radius: 3px;
}

.ean { display: block; width: 100%; height: 34px; }

/* В тёмной теме подложка остаётся белой — иначе код не прочитать. */
:root[data-theme="dark"] .ean-box { background: #fff; }

.toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0 0 10px;
}

/* Ярлык поставщика в списке заданий. */
.tag.supplier { background: var(--soft); color: var(--muted); font-weight: 600; }

/* Подсказка, свёрнутая до заголовка: нужна редко, место занимать не должна. */
.card.hint { padding: 14px 20px; }
.card.hint summary { cursor: pointer; font-weight: 650; }
.card.hint[open] summary { margin-bottom: 4px; }

/* --- Учёт Lasgo --------------------------------------------------------- */

/* Поля формы в строку: штрихкод набирают часто, и три поля в столбик
   растянули бы форму на весь экран телефона. */
.row {
    display: flex;
    flex-wrap: wrap;
    gap: 0 18px;
    align-items: flex-start;
}

.row > .field { flex: 1 1 260px; }
.row > .field.narrow { flex: 0 0 150px; }

.field select,
.field input[type="date"],
.field input[type="number"] {
    width: 100%;
    padding: 11px 13px;
    border: 1px solid var(--line);
    border-radius: 10px;
    font: inherit;
    font-size: 16px;  /* ниже 16px Safari на телефоне увеличивает страницу */
    background: var(--card);
    color: var(--ink);
}

/* Дату и количество правят прямо в таблице, поэтому поля не должны
   выглядеть формой — только то, что по ним можно щёлкнуть. */
.inline-date, .inline-num { margin: 0; }

.inline-num input[type="number"] {
    width: 4.5em;
    text-align: right;
    border: 1px solid transparent;
    background: transparent;
    padding: 3px 4px;
    font: inherit;
    font-size: 15px;
    border-radius: 7px;
    color: inherit;
}

.inline-num input[type="number"]:hover,
.inline-num input[type="number"]:focus { border-color: var(--line); background: var(--card); }

.inline-date input[type="date"] {
    border: 1px solid transparent;
    background: transparent;
    padding: 3px 4px;
    font-size: 14px;
    border-radius: 7px;
    color: inherit;
}

.inline-date input[type="date"]:hover,
.inline-date input[type="date"]:focus { border-color: var(--line); background: var(--card); }

/* Распечатка — отдельный носитель: поле ввода на бумаге бесполезно,
   а дату видеть нужно. */
.print-only { display: none; }

/* Разрыв между порядком сортировки и фильтром по носителю. */
.toolbar-gap { flex: 0 0 18px; }

.toolbar-label {
    font-size: 11.5px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--muted);
    font-weight: 700;
    margin-right: 2px;
}

.chip {
    display: inline-block;
    padding: 6px 14px;
    border: 1px solid var(--line);
    border-radius: 999px;
    font-size: 14px;
    text-decoration: none;
    color: var(--muted);
}

.chip:hover { border-color: var(--ink); color: var(--ink); }
.chip.on { background: var(--ink); border-color: var(--ink); color: #fff; font-weight: 600; }

.toolbar .btn { margin-left: auto; padding: 9px 20px; }

/* Тип носителя: подсказка, в какой зоне склада искать. */
.cat {
    display: inline-block;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    padding: 1px 7px;
    border-radius: 4px;
    margin-right: 6px;
    vertical-align: 1px;
    white-space: nowrap;
}

.cat-vinyl  { background: #ede9fe; color: #5b21b6; }
.cat-cd     { background: #dbeafe; color: #1e40af; }
.cat-dvd    { background: #fee2e2; color: #991b1b; }
.cat-bluray { background: #cffafe; color: #155e75; }

:root[data-theme="dark"] .cat-vinyl  { background: #3b2d63; color: #ddd6fe; }
:root[data-theme="dark"] .cat-cd     { background: #1e3a5f; color: #bfdbfe; }
:root[data-theme="dark"] .cat-dvd    { background: #5c1f1f; color: #fecaca; }
:root[data-theme="dark"] .cat-bluray { background: #164e5c; color: #cffafe; }

/* --- Печать: на бумаге остаётся только список --- */

@media print {
    .topbar, footer, .no-print, .btn-row, .card.progress-card, .legend { display: none !important; }

    body { background: #fff; color: #000; font-size: 10pt; }
    main { max-width: none; padding: 0; }
    h1 { font-size: 15pt; }
    h2 { margin: 10pt 0 5pt; }

    .card { border: 0; padding: 0; margin: 0 0 6pt; }
    .card.scroll { overflow: visible; }

    /* Строку заказа нельзя разрывать между страницами: на складе по ней идут
       как по единице работы. */
    .pages tr { break-inside: avoid; }
    .lasgo tr { break-inside: avoid; }
    thead { display: table-header-group; }

    /* Поля ввода на бумаге бесполезны — печатаем сами значения. */
    .inline-date, .inline-num { display: none; }
    .print-only { display: inline; }

    table { font-size: 9.5pt; }
    th, td { padding: 4pt 6pt 4pt 0; }

    .cover-thumb { width: 96px; height: 96px; }

    /* На бумаге код должен быть не меньше натуральной величины, иначе
       сканер его не возьмёт. Печатать такой лист нужно без «вписать
       в страницу»: масштабирование убивает штрихкод. */
    .ean-box { width: 40mm; padding: 0; }
    .ean { height: 12mm; -webkit-print-color-adjust: exact; print-color-adjust: exact; }

    /* Заливку строк принтер обязан напечатать — по ней отличают заказы. */
    .pages tr.row-combined > td,
    .tag { -webkit-print-color-adjust: exact; print-color-adjust: exact; }

    .grid { display: none; }
}

/* --- Крестик очистки в поле поиска --- */

.clearable { position: relative; display: block; }

/* Место под крестик, чтобы длинный код не уезжал под него. */
.clearable input[type=text] { padding-right: 44px; }

.clear {
    position: absolute;
    top: 50%;
    right: 6px;
    transform: translateY(-50%);
    width: 32px;
    height: 32px;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--muted);
    font-size: 23px;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}

.clear:hover { background: var(--soft); color: var(--ink); }
.clear:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
