/* Dotační monitor — design system
   Plain CSS, no build step, no framework. */

:root {
    --color-bg: #f4f6f8;
    --color-surface: #ffffff;
    --color-border: #e1e4e9;
    --color-border-strong: #cbd1d9;
    --color-text: #1c2230;
    --color-muted: #667085;
    --color-muted-light: #98a2b3;

    --color-primary: #2454a3;
    --color-primary-dark: #1b3f80;
    --color-primary-bg: #eaf1fb;

    --color-success: #1a7f4e;
    --color-success-bg: #e6f6ee;
    --color-success-border: #b7e4cd;

    --color-warning: #9a6400;
    --color-warning-bg: #fef3e0;
    --color-warning-border: #f3d791;

    --color-danger: #b3261e;
    --color-danger-bg: #fbe9e7;
    --color-danger-border: #f2c1bc;

    --color-info: #2f6fa8;
    --color-info-bg: #eaf3fb;
    --color-info-border: #bcdaf2;

    --color-neutral: #4b5563;
    --color-neutral-bg: #eef1f4;
    --color-neutral-border: #dbe0e6;

    /* Source matrix mode badges only (AUTO/SEMI-AUTO/MANUAL/WATCHLIST reuse
       success/info/neutral/warning above) — AGGREGATOR and OUT need their
       own color since neither existing status meaning fits. */
    --color-aggregator: #6b3fa0;
    --color-aggregator-bg: #f1ebf8;
    --color-aggregator-border: #ddccee;

    --color-out: #3f3f46;
    --color-out-bg: #e4e4e7;
    --color-out-border: #52525b;

    --radius-sm: 5px;
    --radius-md: 8px;
    --shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.06);
    --shadow-md: 0 2px 8px rgba(16, 24, 40, 0.08);

    --space-1: 0.25rem;
    --space-2: 0.5rem;
    --space-3: 0.75rem;
    --space-4: 1rem;
    --space-5: 1.5rem;
    --space-6: 2rem;

    --content-max-width: 1600px;
    --content-max-width-narrow: 760px;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    background: var(--color-bg);
    color: var(--color-text);
    font-size: 15px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { line-height: 1.25; font-weight: 600; }
h1 { font-size: 1.5rem; margin: 0 0 var(--space-5); }
h2 { font-size: 1.05rem; margin: 0 0 var(--space-3); }
a { color: var(--color-primary); }

/* ---------- Header / navigation ---------- */

.site-header {
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    position: sticky;
    top: 0;
    z-index: 10;
}

.site-header .header-inner {
    max-width: var(--content-max-width);
    margin: 0 auto;
    padding: 0 var(--space-5);
    display: flex;
    align-items: center;
    gap: var(--space-5);
    min-height: 58px;
}

.brand {
    font-weight: 700;
    font-size: 1.05rem;
    color: var(--color-text);
    text-decoration: none;
    white-space: nowrap;
}

.main-nav {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    flex: 1;
    flex-wrap: wrap;
}

.nav-link {
    color: var(--color-muted);
    text-decoration: none;
    font-size: 0.9rem;
    font-weight: 500;
    padding: 0.4rem 0.7rem;
    border-radius: var(--radius-sm);
    white-space: nowrap;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.nav-link:hover { background: var(--color-neutral-bg); color: var(--color-text); }

.nav-link.active {
    background: var(--color-primary-bg);
    color: var(--color-primary-dark);
}

.header-user {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    white-space: nowrap;
}

.header-user .user-chip {
    font-size: 0.85rem;
    color: var(--color-muted);
}

.header-user form { margin: 0; }

.header-user .btn-link {
    background: none;
    border: none;
    color: var(--color-muted);
    font-size: 0.85rem;
    cursor: pointer;
    padding: 0.35rem 0.5rem;
    border-radius: var(--radius-sm);
}

.header-user .btn-link:hover { background: var(--color-neutral-bg); color: var(--color-text); }

/* ---------- Desktop/laptop navigation compaction ----------
   Manual Source Check Compact Layout Hotfix: at common laptop widths
   the *default* header sizing (1.5rem header-inner gap/padding, 0.9rem
   nav-link text + 0.4rem/0.7rem padding) doesn't leave enough room for
   every nav link on one line, so `.main-nav`'s `flex-wrap: wrap` (see
   base rule above) drops the last link ("Administrace") alone onto its
   own second row — a header sized tall enough for one orphaned link is
   wasted height. Never hides or shrinks any link away — every link
   keeps its full text, only sizing/spacing shrinks.

   Deliberately has no upper `max-width` bound (applies from 901px up to
   any wider desktop/monitor width) — an earlier version capped this at
   1350px, reverting to the original wide spacing above it. That reopened
   the exact same "Administrace alone on row 2" bug at common desktop
   widths (1351-1500px live-measured) whenever the signed-in user's
   `user.username` + ` · ` + `user.role_label` text ran long enough (e.g.
   a longer real name + "Specialista", the longest role label) — found
   during this etapa's own audit with `alzbeta-novakova · Specialista`.
   Since the compact sizing here is only marginally smaller than the
   original and a wide screen already has ample room regardless, there is
   no such thing as "too wide to need it" — compacting is always safe,
   never applying it above some width is what was unsafe. */
@media (min-width: 901px) {
    .site-header .header-inner { gap: var(--space-3); padding: 0 var(--space-4); }
    .brand { font-size: 0.95rem; }
    .main-nav { gap: 0.1rem; flex-wrap: nowrap; }
    .nav-link { font-size: 0.82rem; padding: 0.35rem 0.5rem; }
    .header-user { gap: var(--space-2); }
    /* Safety net, not a nav-item truncation: usernames are operator-
       created (no public signup, CLAUDE.md) so this rarely engages, but
       an unusually long one must never be what reopens the page-level
       horizontal overflow this hotfix removes — verified live with a
       24-character synthetic username during this etapa's QA. */
    .header-user .user-chip {
        font-size: 0.78rem;
        max-width: 160px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .header-user .btn-link { padding: 0.3rem 0.4rem; font-size: 0.78rem; }
}

/* Narrower laptops where even the compacted single-line nav above still
   doesn't fit next to brand + user block: give the nav its own full-
   width row instead of forcing `nowrap` into an overflow, or letting
   one link strand itself. This range is nested inside the one above —
   declared after it, so it wins the cascade here — and keeps the same
   compacted nav-link/brand/user sizing, only adding the row
   restructuring. If the whole nav still doesn't fit even alone on its
   own row, its own `flex-wrap: wrap` (inherited from the base rule)
   lets it fold across a controlled, evenly-shared second line rather
   than overflowing or isolating a single item. */
@media (min-width: 901px) and (max-width: 1200px) {
    .site-header .header-inner { flex-wrap: wrap; row-gap: 0.3rem; min-height: auto; }
    .main-nav { flex-basis: 100%; order: 3; flex-wrap: wrap; }
}

/* ---------- Layout ---------- */

main {
    max-width: var(--content-max-width);
    margin: var(--space-6) auto;
    padding: 0 var(--space-5);
    /* Opacity-only entrance — no transform, so no layout shift. */
    animation: main-fade-in 0.18s ease-out;
}

@keyframes main-fade-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

main.narrow { max-width: var(--content-max-width-narrow); }

/* ---------- Cards / sections ---------- */

.card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    padding: var(--space-5);
}

.section { margin-bottom: var(--space-5); }
.section h2 {
    font-size: 1rem;
    padding-bottom: var(--space-2);
    border-bottom: 1px solid var(--color-border);
    margin-bottom: var(--space-4);
}

.muted { color: var(--color-muted); }

.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    flex-wrap: wrap;
    margin-bottom: var(--space-5);
}
.page-header h1 { margin: 0; }
.page-header .page-lead { color: var(--color-muted); font-size: 0.9rem; margin-top: 0.2rem; }

/* ---------- Alerts / messages ---------- */

.messages { list-style: none; padding: 0; margin: 0 0 var(--space-5); display: flex; flex-direction: column; gap: var(--space-2); }
.alert {
    padding: 0.65rem 0.9rem;
    border-radius: var(--radius-sm);
    background: var(--color-warning-bg);
    border: 1px solid var(--color-warning-border);
    color: var(--color-text);
    font-size: 0.9rem;
}

/* ---------- Forms ---------- */

label { display: block; margin-bottom: 0.3rem; font-weight: 500; font-size: 0.9rem; }

input[type="text"], input[type="password"], input[type="date"], input[type="number"],
input[type="url"], input[type="email"], select, textarea {
    width: 100%;
    padding: 0.5rem 0.7rem;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    margin-bottom: var(--space-4);
    font-size: 0.92rem;
    font-family: inherit;
    background: var(--color-surface);
    color: var(--color-text);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-primary-bg);
}

textarea { min-height: 6rem; resize: vertical; }

.errorlist { color: var(--color-danger); padding-left: 1.1rem; margin: 0 0 0.6rem; font-size: 0.85rem; }

form.card > div { margin-bottom: var(--space-1); }

.checkbox-row label {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-weight: 400;
    margin-right: var(--space-4);
}
.checkbox-row input[type="checkbox"] { width: auto; margin: 0; }

/* ---------- Buttons ---------- */

button, .btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    background: var(--color-primary);
    color: #fff;
    border: 1px solid var(--color-primary);
    padding: 0.5rem 1rem;
    border-radius: var(--radius-sm);
    font-size: 0.9rem;
    font-weight: 500;
    cursor: pointer;
    text-decoration: none;
    line-height: 1.3;
    transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}

button:hover, .btn:hover { background: var(--color-primary-dark); border-color: var(--color-primary-dark); }

.btn-secondary {
    background: var(--color-surface);
    color: var(--color-primary);
    border: 1px solid var(--color-border-strong);
}
.btn-secondary:hover { background: var(--color-neutral-bg); border-color: var(--color-muted-light); }

.btn-danger { background: var(--color-danger); border-color: var(--color-danger); }
.btn-danger:hover { background: #8f1e17; border-color: #8f1e17; }

/* Review resolution actions (Relevantní/Nerelevantní) — outline, not solid:
   solid red is reserved for the genuinely irreversible soft-delete action
   (.btn-danger above), so Nerelevantní reads as "flagged/cautionary" rather
   than as loudly as an actual delete button, while still being clearly
   distinct from the positive Relevantní action next to it. */
.btn-success-outline {
    background: var(--color-success-bg);
    color: var(--color-success);
    border: 1px solid var(--color-success-border);
}
.btn-success-outline:hover { background: var(--color-success); color: #fff; border-color: var(--color-success); }

.btn-danger-outline {
    background: var(--color-danger-bg);
    color: var(--color-danger);
    border: 1px solid var(--color-danger-border);
}
.btn-danger-outline:hover { background: var(--color-danger); color: #fff; border-color: var(--color-danger); }

.btn-sm { padding: 0.3rem 0.7rem; font-size: 0.82rem; }

/* ---------- Badges ---------- */

.badge {
    display: inline-block;
    padding: 0.18rem 0.55rem;
    border-radius: 999px;
    font-size: 0.76rem;
    font-weight: 600;
    white-space: nowrap;
    background: var(--color-neutral-bg);
    color: var(--color-neutral);
    border: 1px solid var(--color-neutral-border);
}
.badge-success { background: var(--color-success-bg); color: var(--color-success); border-color: var(--color-success-border); }
.badge-warning { background: var(--color-warning-bg); color: var(--color-warning); border-color: var(--color-warning-border); }
.badge-danger { background: var(--color-danger-bg); color: var(--color-danger); border-color: var(--color-danger-border); }
.badge-info { background: var(--color-info-bg); color: var(--color-info); border-color: var(--color-info-border); }
.badge-neutral { background: var(--color-neutral-bg); color: var(--color-neutral); border-color: var(--color-neutral-border); }
.badge-aggregator { background: var(--color-aggregator-bg); color: var(--color-aggregator); border-color: var(--color-aggregator-border); }
.badge-out { background: var(--color-out); color: #fff; border-color: var(--color-out-border); }

/* Relevance badges use the outline variant so a status badge and a
   relevance badge with the same text (both "Ke kontrole" are two
   different, unrelated fields — see GrantCall.Status/Relevance) stay
   visually distinguishable even without reading the column/label next to
   them, not just by their (identical) text and color. */
.badge-outline.badge-success,
.badge-outline.badge-warning,
.badge-outline.badge-danger,
.badge-outline.badge-info,
.badge-outline.badge-neutral {
    background: transparent;
    font-weight: 500;
}

.badge-group { display: inline-flex; align-items: center; gap: 0.3rem; }
.badge-group .badge-label { font-size: 0.72rem; color: var(--color-muted); text-transform: uppercase; letter-spacing: 0.02em; }

.meta-row { display: flex; flex-wrap: wrap; gap: var(--space-4) var(--space-5); margin-bottom: var(--space-2); }
.meta-item { display: flex; flex-direction: column; gap: 0.2rem; }
.meta-item .meta-label { font-size: 0.72rem; color: var(--color-muted); text-transform: uppercase; letter-spacing: 0.03em; }
.flag-row { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: var(--space-2); }

.review-action-bar { border-top: 3px solid var(--color-primary); }
.review-action-bar-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
}
.review-action-bar-header h2 { margin: 0; padding-bottom: 0; border-bottom: none; }
.review-action-bar-status { display: flex; flex-wrap: wrap; gap: var(--space-4); }
.review-action-bar .actions { margin-top: 0; }

/* ---------- Tables ---------- */

.table-responsive { width: 100%; overflow-x: auto; }

table.data { width: 100%; border-collapse: collapse; }
table.data th, table.data td {
    text-align: left;
    padding: 0.6rem 0.7rem;
    border-bottom: 1px solid var(--color-border);
    font-size: 0.88rem;
    vertical-align: top;
}
table.data th {
    background: #f8f9fb;
    font-weight: 600;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: var(--color-muted);
    white-space: nowrap;
}
table.data tbody tr { transition: background-color 0.12s ease; }
table.data tbody tr:hover { background: #f7f9fc; }
table.data td.nowrap, table.data th.nowrap { white-space: nowrap; }

.truncate {
    display: inline-block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
}

/* Two-line clamp for long provider/programme names in tables: the full
   name is almost always readable in place, the title tooltip stays as a
   complement (never the only way to read it). */
.clamp-2 {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.col-title { width: 32%; min-width: 240px; }
.col-provider { width: 22%; min-width: 220px; }
.col-narrow { width: 10%; min-width: 90px; }
.col-call-select { width: 4%; min-width: 32px; }

/* Review Queue Compact Layout hotfix — table-layout: fixed makes the table
   respect the colgroup percentages below no matter what a cell contains, so
   a long value can never grow the table past its container (the "část
   tabulky je mimo obraz" complaint) the way plain table-layout: auto did.
   Column widths intentionally sum to 100%. */
.review-table { table-layout: fixed; }
.review-table .col-review-select { width: 4%; min-width: 32px; }
.review-table .col-review-title { width: 28%; }
.review-table .col-review-provider { width: 16%; }
.review-table .col-review-status { width: 13%; }
.review-table .col-review-relevance { width: 13%; }
.review-table .col-review-deadline { width: 11%; }
.review-table .col-review-actions { width: 15%; }

.review-call-title { font-weight: 500; }

/* Review Queue Bulk Resolution — a compact toolbar above the table, same
   `.actions` flex row the rest of the app already uses for button groups,
   just with the "Vybrat vše" label folded into the same line so the panel
   never adds real vertical height. Checkboxes themselves reuse
   .checkbox-row's `input[type="checkbox"] { width: auto; margin: 0; }`
   rule, so no new checkbox styling is needed either. */
.bulk-panel { flex-wrap: wrap; }
.bulk-select-all { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.85rem; color: var(--color-muted); }
.bulk-select-all input[type="checkbox"] { width: auto; margin: 0; }

/* Secondary detail lines under a review queue call's title (former
   "Žadatelé / oblast"/"Financování" columns) — capped to roughly 3 lines
   total via max-height regardless of how many of the conditional rows are
   present, and each row is forced to a single truncated line, so this
   block can never be what makes a table row tall again. Full values are
   never put in a `title` attribute here — that would just re-introduce the
   same "huge HTML per row" problem in a different attribute; the complete
   text stays reachable only on the call's own detail page. */
.review-call-meta {
    margin-top: 0.25rem;
    max-height: 3.6rem;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}
.review-call-meta-row {
    font-size: 0.78rem;
    color: var(--color-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ---------- Empty states ---------- */

.empty-state {
    text-align: center;
    padding: var(--space-6) var(--space-4);
    color: var(--color-muted);
}
.empty-state p { margin: 0; font-size: 0.9rem; }

/* ---------- Filters ---------- */

.filters {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: var(--space-3) var(--space-4);
    align-items: end;
}
.filters .field { display: flex; flex-direction: column; min-width: 0; }
.filters .field label { font-size: 0.78rem; margin-bottom: 0.25rem; }
.filters .field select, .filters .field input[type="text"] { margin-bottom: 0; text-overflow: ellipsis; }
.filters .field-actions { display: flex; align-items: center; gap: var(--space-2); }
.filters .field-checkboxes { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); }
/* Options like "Konec příjmu (nejpozději)" need more than one 180px track
   to stay readable in the closed select box. */
.filters .field-wide { grid-column: span 2; }
@media (max-width: 480px) {
    .filters .field-wide { grid-column: span 1; }
}

/* Call List Active Filters & Result Summary — kept to a compact single
   wrapping row so it never adds much vertical space above the table. */
.filter-result-count {
    margin: var(--space-3) 0 var(--space-2);
    font-size: 0.85rem;
    color: var(--color-muted);
}
.filter-summary {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: var(--space-3);
}
.filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.18rem 0.55rem;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 500;
    background: var(--color-primary-bg);
    color: var(--color-primary);
    border: 1px solid var(--color-primary);
    text-decoration: none;
    white-space: nowrap;
}
.filter-chip:hover { text-decoration: none; opacity: 0.85; }
.filter-chip-remove { font-weight: 700; }
.filter-clear-all { font-size: 0.82rem; margin-left: 0.2rem; }
.filter-chip:focus-visible,
.filter-clear-all:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--color-primary-bg);
    border-radius: 4px;
}

/* ---------- Actions bar ---------- */

.actions { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: var(--space-5); align-items: center; }
.actions form { display: inline; margin: 0; }
/* Destructive action stands apart from the routine buttons: pushed to the
   far edge so it can't be hit by muscle memory next to "Upravit". */
.actions > .btn-danger, .actions > form:last-child:has(.btn-danger) { margin-left: auto; }

/* Compact horizontal action list inside a table cell (Review Queue Cockpit)
   — keeps Detail/Upravit/Zdroj/Schválit on one wrapping line instead of
   stacking with <br>, so a row's height is driven by its text content, not
   by how many actions it has. */
.row-actions { display: flex; flex-wrap: wrap; gap: 0.25rem 0.6rem; align-items: center; }
.row-actions form { display: inline; margin: 0; }

/* ---------- Pagination ---------- */

.pagination {
    margin-top: var(--space-5);
    display: flex;
    gap: var(--space-3);
    align-items: center;
    justify-content: center;
}
.pagination a, .pagination .page-current {
    display: inline-flex;
    align-items: center;
    padding: 0.4rem 0.9rem;
    border-radius: var(--radius-sm);
    border: 1px solid var(--color-border-strong);
    text-decoration: none;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--color-text);
    background: var(--color-surface);
}
.pagination a { transition: background-color 0.15s ease, border-color 0.15s ease; }
.pagination a:hover { background: var(--color-neutral-bg); }
.pagination .page-current { border-color: transparent; color: var(--color-muted); background: none; }

/* ---------- Dashboard stat grid ---------- */

.stat-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-4);
    margin-bottom: var(--space-6);
}
@media (max-width: 1100px) {
    .stat-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 520px) {
    .stat-grid { grid-template-columns: 1fr; }
}
.stat-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-top: 3px solid var(--color-border-strong);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    padding: var(--space-4) var(--space-5);
    transition: box-shadow 0.15s ease, transform 0.15s ease;
}
.stat-card:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
.stat-card .value { font-size: 1.9rem; font-weight: 700; line-height: 1.15; }
.stat-card .label { color: var(--color-muted); font-size: 0.82rem; margin-top: 0.3rem; }
.stat-card.accent { border-top-color: var(--color-primary); }
.stat-card.accent .value { color: var(--color-primary); }
.stat-card.warn { border-top-color: var(--color-warning); }
.stat-card.warn .value { color: var(--color-warning); }
.stat-card.danger { border-top-color: var(--color-danger); }
.stat-card.danger .value { color: var(--color-danger); }

/* ---------- Detail grid ---------- */

dl.detail-grid { display: grid; grid-template-columns: max-content 1fr; gap: 0.5rem 1.25rem; margin: 0; }
dl.detail-grid dt { color: var(--color-muted); font-size: 0.8rem; padding-top: 0.15rem; }
dl.detail-grid dd { margin: 0; }
dl.detail-grid dd p { margin: 0 0 0.4rem; }
dl.detail-grid dd p:last-child { margin-bottom: 0; }

.note {
    padding: 0.7rem 0.9rem;
    border-radius: var(--radius-sm);
    font-size: 0.86rem;
    margin: 0;
}
.note-monitoring {
    background: var(--color-neutral-bg);
    border: 1px dashed var(--color-border-strong);
    color: var(--color-muted);
}

.field-row { display: flex; gap: var(--space-4); flex-wrap: wrap; }
.field-row > div { flex: 1; min-width: 200px; }

/* ---------- Manual Source Check Queue — card list ----------
   Replaces the former 11-column table (Manual Source Check Queue UI
   Polish) with a compact card per tracked source. Every rule here is
   scoped under `.source-check-*` — never a bare `details`/`summary`/
   `textarea`/`form` selector — so this can't leak into any other page's
   forms or disclosure widgets.

   Manual Source Check Compact Layout Hotfix: `.source-check-record`
   (the "Zapsat kontrolu" disclosure) moved from its own bordered block
   below the actions row into `.source-check-actions` itself, as the
   last flex item alongside "Otevřít zdroj"/"Ručně přidat výzvu"/
   "Založit zdroj" — a closed `<details>` needs no `display` override to
   act as a normal auto-width flex item (any block-level child of a
   `display:flex` container becomes one automatically); only the *open*
   state forces it onto its own full-width row via `flex: 1 1 100%`, so
   the form below the summary still lays out normally instead of being
   squeezed into a narrow leftover gap next to the other buttons. */

.source-check-filters { margin-bottom: var(--space-4); }

.source-check-list {
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
    min-width: 0;
}

.source-check-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-left: 4px solid var(--color-border-strong);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    padding: 0.9rem 1.2rem;
    min-width: 0;
    max-width: 100%;
}

/* Left border colour mirrors the same `state_badge_css` value already
   used for the status badge text below — one state->colour mapping on
   the backend, never duplicated here as a second copy that could drift
   out of sync. Colour is always a secondary cue: the state is also
   always spelled out as text in `.source-check-card-status`. */
.source-check-card-badge-warning { border-left-color: var(--color-warning); }
.source-check-card-badge-danger { border-left-color: var(--color-danger); }
.source-check-card-badge-neutral { border-left-color: var(--color-neutral); }

.source-check-card-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: var(--space-3);
    flex-wrap: wrap;
}
.source-check-card-title-group { min-width: 0; flex: 1 1 auto; }
.source-check-card-title { margin: 0 0 0.25rem; font-size: 1rem; overflow-wrap: anywhere; }
.source-check-card-badges { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; }
.source-check-card-fact { font-size: 0.8rem; color: var(--color-muted); white-space: nowrap; }
.source-check-card-status { font-size: 0.8rem; white-space: nowrap; flex-shrink: 0; }

.source-check-meta {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.35rem 0.75rem;
    margin-top: 0.6rem;
}
.source-check-meta-item { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.source-check-meta-label { font-size: 0.72rem; color: var(--color-muted); text-transform: uppercase; letter-spacing: 0.03em; }
.source-check-meta-value { font-size: 0.92rem; font-weight: 500; overflow-wrap: anywhere; }

/* Full note text stays in the DOM (Django auto-escapes it) so the
   `title` tooltip can show it in full — the visible block itself is
   capped to ~3 lines via line-clamp so a long note can never stretch
   the card. `overflow-wrap: anywhere` covers a long unbroken token
   (e.g. a pasted URL) that `-webkit-line-clamp` alone wouldn't wrap. */
.source-check-note {
    margin-top: 0.6rem;
    padding: 0.5rem 0.7rem;
    background: var(--color-neutral-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font-size: 0.85rem;
    color: var(--color-text);
    overflow-wrap: anywhere;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    max-height: 4.2rem;
}

.source-check-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.6rem;
}

/* Closed: just another auto-width flex item, no border/padding/margin
   of its own — `.source-check-actions`'s own `gap` already spaces it
   from its siblings, same as every other action button. Open: claims
   the full row (wraps below the other buttons via flex-wrap on the
   parent) so the form has real width to lay out in. */
.source-check-record {
    min-width: 0;
    max-width: 100%;
}
.source-check-record[open] {
    flex: 1 1 100%;
}
.source-check-record[open] .source-check-record-summary {
    margin-bottom: var(--space-2);
}

/* Sized to match `.btn-sm` (same padding/font-size) so it sits flush
   with the other compact action buttons in the same row — styled to
   read as a button, not a plain disclosure triangle. The native marker
   is hidden in both engines since the button-like background/border
   already communicates "expandable"; this is a `<summary>`, never a
   `<button>`, so it can't accidentally submit the form it discloses. */
.source-check-record-summary {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    cursor: pointer;
    list-style: none;
    background: var(--color-primary-bg);
    color: var(--color-primary-dark);
    border: 1px solid var(--color-primary);
    padding: 0.3rem 0.7rem;
    border-radius: var(--radius-sm);
    font-size: 0.82rem;
    font-weight: 500;
    -webkit-user-select: none;
    user-select: none;
}
.source-check-record-summary::-webkit-details-marker { display: none; }
.source-check-record-summary:hover { background: var(--color-primary); color: #fff; }
.source-check-record-summary:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--color-primary-bg);
}

.source-check-record-form {
    display: grid;
    grid-template-columns: minmax(220px, 280px) 1fr auto;
    gap: var(--space-3);
    align-items: end;
    min-width: 0;
}
.source-check-record-field { display: flex; flex-direction: column; min-width: 0; }
.source-check-record-field label { font-size: 0.8rem; margin-bottom: 0.25rem; }
/* Overrides only inside this scoped form — the page's global `select,
   textarea { margin-bottom; }` rule and the global `textarea { min-height:
   6rem; }` would otherwise make this compact per-card form as tall as a
   full-page form. */
.source-check-record-form select,
.source-check-record-form textarea {
    margin-bottom: 0;
}
.source-check-record-form textarea {
    min-height: 2.6rem;
    resize: vertical;
}
.source-check-record-field-submit { align-self: end; }

.source-check-record-hint {
    margin: var(--space-2) 0 0;
    font-size: 0.78rem;
    color: var(--color-muted);
}

@media (max-width: 900px) {
    .source-check-meta { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 700px) {
    .source-check-record-form { grid-template-columns: 1fr; }
    .source-check-record-field-submit { align-self: stretch; }
}
@media (max-width: 480px) {
    .source-check-card { padding: 0.75rem 0.9rem; }
    .source-check-meta { grid-template-columns: 1fr; }
    .source-check-card-header { flex-direction: column; align-items: flex-start; }
}

/* ---------- Responsive ---------- */

@media (max-width: 900px) {
    main { padding: 0 var(--space-4); margin: var(--space-4) auto; }
    .site-header .header-inner { padding: 0 var(--space-4); flex-wrap: wrap; min-height: auto; padding-top: var(--space-2); padding-bottom: var(--space-2); }
    .main-nav { order: 3; width: 100%; gap: 0.2rem; }
    .header-user { margin-left: auto; }
    dl.detail-grid { grid-template-columns: 1fr; }
    dl.detail-grid dt { padding-top: 0.6rem; }
    .card { padding: var(--space-4); }
}

/* ---------- Motion preferences ----------
   All animation here is decorative; anyone who asked their OS to reduce
   motion gets an effectively static UI. */

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
    .stat-card:hover { transform: none; }
}
