:root {
    --bg: #0f1115;
    --card: #181b22;
    --line: #2a2f3a;
    --text: #e6e8ec;
    --muted: #9aa3b2;
    --accent: #f5a623;
    --danger: #e5484d;
    --ok: #30a46c;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
    background: var(--bg);
    color: var(--text);
}

.topbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 24px;
    background: #12141a;
    border-bottom: 1px solid var(--line);
}

.brand { font-weight: 600; }
.user { color: var(--muted); font-size: 14px; }
.logout { color: var(--accent); margin-left: 12px; text-decoration: none; }

.container { max-width: 1280px; margin: 20px auto; padding: 0 16px; }

.auth-off {
    padding: 8px 24px; font-size: 13px;
    background: rgba(229,72,77,.15); border-bottom: 1px solid var(--danger);
    color: var(--danger);
}
.auth-off code { color: var(--text); }

.card {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 16px 20px;
    margin-bottom: 20px;
}

/* --- two-column layout: sidebar + main ------------------------------------ */
.layout { display: flex; gap: 20px; align-items: flex-start; }

.sidebar {
    flex: 0 0 380px; width: 380px;
    background: var(--card); border: 1px solid var(--line);
    border-radius: 10px; padding: 16px 18px;
    position: sticky; top: 20px;
    max-height: calc(100vh - 40px); overflow: auto;
}
.sidebar-head { display: flex; align-items: center; justify-content: space-between; }
.sidebar-head h2 { margin: 0; font-size: 16px; }
.layout.collapsed .sidebar { display: none; }

.main { flex: 1 1 auto; min-width: 0; }

.toolbar { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.toolbar .spacer { flex: 1 1 auto; }
.toolbar .breadcrumbs { margin-bottom: 0; }
form.inline { display: inline; margin: 0; }

.btn.small { padding: 4px 9px; font-size: 13px; line-height: 1; }
.mkdir-form { display: inline-flex; gap: 6px; align-items: center; }
.mkdir-input { width: 150px; margin: 0; padding: 6px 9px; }

/* the whole file listing is a drop target */
.filearea {
    border: 2px dashed transparent; border-radius: 10px;
    background: var(--card);
    padding: 6px 14px 12px;
    transition: border-color .15s, background .15s;
}
.filearea.drag { border-color: var(--accent); background: rgba(245,166,35,.06); }
.drop-hint { text-align: center; color: var(--muted); font-size: 13px; padding: 12px 0 6px; }
.filearea.drag .drop-hint { color: var(--accent); }

.hidden { display: none !important; }
.cbcol { width: 28px; text-align: center; }
.cbcol input { cursor: pointer; }
.scanning progress { width: 100%; height: 10px; }
.bulk-bar {
    display: flex; align-items: center; gap: 12px;
    padding: 8px 10px; margin-bottom: 8px;
    background: rgba(229,72,77,.08); border: 1px solid var(--danger);
    border-radius: 8px; font-size: 14px;
}

.card h2 { margin-top: 0; font-size: 16px; }

label { display: block; margin: 10px 0; font-size: 14px; color: var(--muted); }
/* Правило ниже задаёт input'ам display: block, а это перебивает атрибут
   hidden — из-за чего скрытое поле выбора файла всё равно рисовалось рядом с
   кнопкой «Выбрать файлы». Возвращаем атрибуту силу. */
[hidden] { display: none !important; }

input[type=text], input[type=password], input[type=file], textarea {
    display: block;
    width: 100%;
    margin-top: 4px;
    padding: 8px 10px;
    background: #0f1115;
    border: 1px solid var(--line);
    border-radius: 6px;
    color: var(--text);
}

.btn {
    padding: 8px 14px;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: #222733;
    color: var(--text);
    cursor: pointer;
    font-size: 14px;
}
.htmx-indicator { opacity: 0; transition: opacity .15s; }
.htmx-request .htmx-indicator, .htmx-request.htmx-indicator { opacity: 1; }

.btn.primary { background: var(--accent); color: #1a1200; border-color: var(--accent); }
.btn.danger { background: transparent; color: var(--danger); border-color: var(--danger); }
.btn.warn { background: transparent; color: var(--accent); border-color: var(--accent); }
.btn:disabled { opacity: .5; cursor: progress; }
a.btn { display: inline-block; text-decoration: none; }
.btn.copied { color: var(--ok); border-color: var(--ok); }

table.objects td.actions { display: flex; gap: 8px; align-items: center; }
table.objects td.actions form { margin: 0; }

table.objects { width: 100%; border-collapse: collapse; font-size: 14px; }
table.objects th, table.objects td {
    text-align: left;
    padding: 8px 6px;
    border-bottom: 1px solid var(--line);
}
table.objects .key { font-family: ui-monospace, monospace; }
table.objects .empty { color: var(--muted); text-align: center; }
table.objects .folder-row .key a { color: var(--accent); text-decoration: none; font-weight: 600; }
table.objects .folder-row .key a:hover { text-decoration: underline; }

.breadcrumbs { font-size: 14px; margin-bottom: 12px; }
.breadcrumbs a { color: var(--accent); text-decoration: none; }
.breadcrumbs a:hover { text-decoration: underline; }
.breadcrumbs .sep { color: var(--muted); margin: 0 6px; }
.breadcrumbs .current { color: var(--text); font-weight: 600; }

.flash { padding: 10px 14px; border-radius: 8px; margin-bottom: 16px; font-size: 14px; }
.flash.ok { background: rgba(48,163,108,.15); border: 1px solid var(--ok); }
.flash.err { background: rgba(229,72,77,.15); border: 1px solid var(--danger); }

.login-box { max-width: 380px; margin: 80px auto; text-align: center; }
.login-box .btn { display: inline-block; text-decoration: none; margin-top: 16px; }
.login-box form { margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--line); text-align: left; }
.login-box .error { color: var(--danger); }

/* Purge queue status */
.muted { color: var(--muted); }
.small { font-size: 12px; }
.queue-now ul.pending { margin: 6px 0 0; padding-left: 18px; font-family: ui-monospace, monospace; font-size: 13px; }
h3 { font-size: 14px; margin: 18px 0 8px; }

.badge {
    display: inline-block; padding: 2px 8px; border-radius: 999px;
    font-size: 12px; text-transform: uppercase; letter-spacing: .03em;
}
.badge.running { background: rgba(245,166,35,.15); color: var(--accent); border: 1px solid var(--accent); }
.badge.success { background: rgba(48,163,108,.15); color: var(--ok); border: 1px solid var(--ok); }
.badge.partial { background: rgba(245,166,35,.15); color: var(--accent); border: 1px solid var(--accent); }
.badge.failed  { background: rgba(229,72,77,.15); color: var(--danger); border: 1px solid var(--danger); }

table.jobs .job-detail td { padding-top: 0; border-bottom: 1px solid var(--line); }
table.jobs .job-detail .paths { font-family: ui-monospace, monospace; font-size: 12px; color: var(--muted); }
table.jobs .job-detail .detail { font-size: 12px; color: var(--muted); margin-top: 4px; }
table.jobs .job-detail .logs { margin-top: 6px; font-family: ui-monospace, monospace; font-size: 12px; color: var(--text); opacity: .85; }

/* --- name search ---------------------------------------------------------- */
.search-box { display: inline-flex; align-items: center; gap: 8px; }
.search-input {
    width: 220px; margin: 0; padding: 6px 10px;
    background: #0f1115; border: 1px solid var(--line);
    border-radius: 6px; color: var(--text); font-size: 14px;
}
.search-input:focus { outline: none; border-color: var(--accent); }

/* "ищу…" next to the box, and the results dim while the request is in flight,
   so a slow search never looks like a finished empty one. */
.search-spinner { color: var(--accent); font-size: 13px; white-space: nowrap; }
.filearea.htmx-request { opacity: .45; transition: opacity .1s; }

.search-banner {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 10px; margin: 8px 0;
    background: rgba(245,166,35,.08); border: 1px solid var(--accent);
    border-radius: 8px; font-size: 14px;
}
.search-banner.empty { background: rgba(154,163,178,.08); border-color: var(--line); }
.search-banner .btn { margin-left: auto; }
.search-banner .trunc { color: var(--danger); }

/* Folder part of a search hit — click it to open the containing folder. */
.path-dir { color: var(--accent); text-decoration: none; }
.path-dir:hover { text-decoration: underline; }
table.objects tr.row-heavy .path-dir { color: var(--accent); }

/* --- weight analysis in the file list -------------------------------------- */
table.objects tr.row-heavy { background: rgba(229,72,77,.10); }
table.objects tr.row-heavy td { border-bottom-color: rgba(229,72,77,.35); }
table.objects tr.row-heavy .key { color: var(--danger); }
.analysis-note { margin: 8px 2px 0; }
.analysis-note a { color: var(--accent); }
.row-msg { margin-left: 4px; }
.row-msg.err { color: var(--danger); }

/* --- compression results ---------------------------------------------------- */
.was { text-decoration: line-through; color: var(--muted); }
.saved { color: var(--ok); font-weight: 600; }
.compress-log { margin-bottom: 14px; }
.compress-list {
    margin: 8px 0 0; padding-left: 18px;
    font-family: ui-monospace, monospace; font-size: 13px;
}
.compress-list .key { color: var(--text); }
tr.htmx-request { opacity: .55; }

/* Метка «расширение не совпадает с содержимым». Ключ при этом не трогается. */
.tag-mismatch {
    display: inline-block;
    margin-left: 4px;
    padding: 0 5px;
    border-radius: 3px;
    background: #fde2e6;
    color: #a02033;
    font-weight: 700;
    cursor: help;
}

/* Страница массового сжатия */
.squeeze-form {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 10px;
    margin: 12px 0;
}

.squeeze-form label {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 13px;
    color: #55606b;
}

.flash.warn-flash {
    background: #fff5e0;
    border: 1px solid #e8c37a;
    color: #6b4a10;
}

.squeeze-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 12px 0;
}


/* --- Оверлей загрузки -------------------------------------------------- */
/* Пока идёт загрузка, экран перекрыт: уйти со страницы посреди пачки — это
   потерять часть файлов, а докрутить прогресс уже не получится. */
body.up-locked { overflow: hidden; }

.up-overlay {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: rgba(15, 17, 21, .84);
}

.up-box {
    width: min(760px, 100%);
    max-height: 82vh;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 20px 22px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--card);
    box-shadow: 0 24px 60px rgba(0, 0, 0, .55);
}

.up-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.up-title { font-size: 15px; font-weight: 600; overflow-wrap: anywhere; }
.up-stat { font-size: 13px; color: var(--muted); }

.up-track {
    position: relative;
    height: 6px;
    border-radius: 999px;
    background: #222733;
    overflow: hidden;
}
.up-total { height: 8px; }

.up-fill {
    display: block;
    height: 100%;
    width: 0;
    border-radius: 999px;
    background: var(--accent);
    transition: width .12s linear;
}

/* Байты доставлены, дальше жмёт сервер — сколько это займёт, браузеру знать
   неоткуда. Полоса бежит вместо того, чтобы показывать выдуманный процент. */
.up-indeterminate .up-fill {
    width: 40% !important;
    animation: up-slide 1.1s ease-in-out infinite;
}
@keyframes up-slide {
    from { transform: translateX(-110%); }
    to { transform: translateX(260%); }
}

.up-list {
    margin-top: 4px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.up-row {
    display: grid;
    grid-template-columns: 40px minmax(0, 1fr) 88px minmax(0, 210px);
    align-items: center;
    gap: 12px;
    padding: 6px 8px;
    border-radius: 6px;
    font-size: 13px;
}
.up-row.up-active { background: rgba(245, 166, 35, .09); }
.up-row.up-ok .up-state { color: var(--ok); }
.up-row.up-failed { background: rgba(229, 72, 77, .12); }
.up-row.up-failed .up-state { color: var(--danger); }
.up-row.up-skipped { opacity: .5; }

.up-thumb {
    width: 40px;
    height: 40px;
    border: 1px solid var(--line);
    border-radius: 4px;
    background: #11131a;
    overflow: hidden;
}
.up-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

.up-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.up-state {
    text-align: right;
    font-size: 12px;
    color: var(--muted);
    overflow-wrap: anywhere;
}

@media (max-width: 620px) {
    .up-row { grid-template-columns: 32px minmax(0, 1fr) minmax(0, 140px); }
    .up-row .up-track { display: none; }
    .up-thumb { width: 32px; height: 32px; }
}

@media (prefers-reduced-motion: reduce) {
    .up-fill { transition: none; }
    .up-indeterminate .up-fill { animation: none; width: 100% !important; }
}

/* Страница настроек */
.settings-form { display: flex; flex-direction: column; gap: 18px; max-width: 520px; }
.settings-form > label { display: flex; flex-direction: column; gap: 4px; font-size: 14px; }
label.check { display: flex; flex-direction: row; align-items: center; gap: 8px; font-size: 14px; }
label.check input { width: auto; margin: 0; }
.settings-form .hint { font-size: 12px; color: var(--muted); line-height: 1.45; }
.settings-form .field-err { font-size: 12px; color: var(--danger); }
.settings-form .row { display: flex; gap: 10px; }
