/* Ash OCR — visual grammar.
 *
 * Palette and spacing intentionally close to peform so the two products
 * look like siblings. Adjust as peform's theme evolves.
 */

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

:root {
    --bg: #f5f5f5;
    --surface: #ffffff;
    --ink: #333333;
    --muted: #666666;
    --line: #e0e0e0;
    --primary: #1a237e;
    --primary-dark: #283593;
    --accent: #2196f3;
    --success-bg: #e8f5e9;
    --success-ink: #2e7d32;
    --warning-bg: #fff3e0;
    --warning-ink: #e65100;
    --error-bg: #fce4ec;
    --error-ink: #c62828;
    --radius: 8px;
    --radius-sm: 6px;
    --shadow-sm: 0 1px 3px rgba(0,0,0,0.08);
    --shadow-md: 0 4px 12px rgba(0,0,0,0.1);
}

html, body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
                 'Helvetica Neue', Arial, sans-serif;
    background: var(--bg);
    color: var(--ink);
    font-size: 14px;
    line-height: 1.5;
}

a { color: var(--primary); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Top bar */
.topbar {
    background: var(--primary);
    color: #fff;
    padding: 12px 24px;
    display: flex;
    align-items: center;
    gap: 24px;
}
.topbar .brand {
    color: #fff;
    font-size: 18px;
    font-weight: 600;
    text-decoration: none;
}
.topbar .nav-links {
    display: flex;
    gap: 16px;
}
.topbar .nav-links a {
    color: rgba(255,255,255,0.8);
    font-size: 14px;
    padding: 6px 12px;
    border-radius: 6px;
}
.topbar .nav-links a:hover {
    background: rgba(255,255,255,0.1);
    text-decoration: none;
    color: #fff;
}
.topbar .nav-links a.active {
    background: rgba(255,255,255,0.18);
    color: #fff;
}
.topbar-right {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 14px;
}
.user-chip {
    padding: 4px 10px;
    background: rgba(255,255,255,0.15);
    border-radius: 12px;
    font-size: 12px;
}

/* Language switcher */
.lang-switch {
    display: inline-flex;
    gap: 2px;
    background: rgba(255,255,255,0.1);
    border-radius: 6px;
    padding: 2px;
}
.lang-switch button {
    background: transparent;
    color: rgba(255,255,255,0.7);
    border: none;
    padding: 3px 8px;
    font-size: 11px;
    font-weight: 600;
    border-radius: 4px;
    cursor: pointer;
}
.lang-switch button.active {
    background: rgba(255,255,255,0.25);
    color: #fff;
}
.lang-switch button:hover { color: #fff; }

.logout-form { display: inline; }
.btn-link {
    background: none;
    border: none;
    color: rgba(255,255,255,0.85);
    cursor: pointer;
    font: inherit;
    font-size: 13px;
    padding: 4px 8px;
}
.btn-link:hover { color: #fff; text-decoration: underline; }

/* AI clean-up button: monochrome robot SVG + subtle violet wash so
 * the on-demand action stands out from the "+ Add line" sibling and
 * the operator understands the click triggers a model call. */
.btn-ai {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 10px;
    background: #ede7f6;
    color: #311b92;
    border: 1px solid #d1c4e9;
    border-radius: 4px;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    margin-left: 8px;
}
.btn-ai:hover  { background: #d1c4e9; }
.btn-ai:focus  { outline: 2px solid #7e57c2; outline-offset: 1px; }
.btn-ai__icon  { flex-shrink: 0; }
/* In-flight / disabled state -- mirrors .btn-primary rules from Krok 11b. */
.btn-ai[disabled],
.btn-ai.htmx-request,
form.htmx-request .btn-ai {
    opacity: 0.6;
    cursor: progress;
}

/* AI clean-up review affordances (Krok 11d). Highlights LLM-modified
 * cells with a soft amber background; .ai-action-bar appears above the
 * lines table after a swap to let the operator accept or revert. */
input.ai-changed {
    background: #fff8e1;
    box-shadow: inset 0 0 0 1px #ffc107;
}
.ai-action-bar {
    display: none;
    align-items: center;
    gap: 12px;
    padding: 6px 12px;
    margin: 8px 0;
    background: #ede7f6;
    border-radius: 4px;
    font-size: 12px;
}
.ai-action-bar__label { flex: 1; color: #311b92; }
.ai-action-bar .btn-link { color: #311b92; }
.ai-action-bar .btn-link:hover { color: #4527a0; }

/* Main */
main {
    padding: 24px;
    min-height: calc(100vh - 120px);
}

/* Review pages opt into a viewport-locked layout: the body fills 100vh,
 * topbar + footer stay put, and the form/PDF columns inside .review-page
 * get their own internal scroll. Without this the whole page scrolls,
 * pulling the PDF out of view as the user works down a long form. */
.body-review {
    height: 100vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.body-review > .topbar,
.body-review > .appfoot {
    flex: 0 0 auto;
}
.body-review > main {
    flex: 1 1 auto;
    min-height: 0;
    padding: 12px 24px;
    display: flex;
    flex-direction: column;
}

/* Footer */
.appfoot {
    padding: 12px 24px;
    border-top: 1px solid var(--line);
    color: var(--muted);
    text-align: right;
    background: var(--surface);
}

/* Login */
.login-card {
    max-width: 400px;
    margin: 48px auto;
    padding: 32px;
    background: var(--surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow-md);
}
.login-card h1 {
    margin: 0 0 4px;
    font-size: 22px;
    color: var(--primary);
}
.login-subtitle {
    margin: 0 0 24px;
    color: var(--muted);
    font-size: 13px;
}
.login-card form {
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.login-card label {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 12px;
    color: var(--muted);
    font-weight: 500;
}
.login-card input {
    padding: 9px 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    font-size: 14px;
    background: #fafafa;
}
.login-card input:focus {
    outline: none;
    border-color: var(--primary);
    background: #fff;
    box-shadow: 0 0 0 2px rgba(26,35,126,0.12);
}
.btn-primary {
    padding: 10px 16px;
    background: var(--primary);
    color: #fff;
    border: none;
    border-radius: var(--radius-sm);
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    margin-top: 4px;
}
.btn-primary:hover { background: var(--primary-dark); }
/* In-flight HTMX state + native disabled state. HTMX 2.x přidá
 * `.htmx-request` jen na **trigger element**: u `hx-post` na button
 * to je button, u `hx-post` na form to je form. Cílíme obojí, aby
 * vizuál fungoval univerzálně. `hx-disabled-elt` se postará o nativní
 * `disabled` atribut, aby opakované klikání / Enter neprojely.
 * Trojí signál pro uživatele: zšednutí, kurzor "progress", spinner. */
.btn-primary[disabled],
.btn-primary.htmx-request,
form.htmx-request .btn-primary {
    opacity: 0.6;
    cursor: progress;
}
.btn-primary.htmx-request,
form.htmx-request .btn-primary {
    position: relative;
    padding-right: 2.2em;
}
.btn-primary.htmx-request::after,
form.htmx-request .btn-primary::after {
    content: "";
    position: absolute;
    right: 0.8em;
    top: 50%;
    width: 1em;
    height: 1em;
    margin-top: -0.5em;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: btn-spin 0.7s linear infinite;
}
@keyframes btn-spin {
    to { transform: rotate(360deg); }
}

.login-help {
    margin-top: 18px;
    padding-top: 18px;
    border-top: 1px solid var(--line);
    font-size: 12px;
    color: var(--muted);
}

/* Flash */
.flash {
    padding: 10px 14px;
    border-radius: var(--radius-sm);
    margin-bottom: 14px;
    font-size: 13px;
}
.flash-error {
    background: var(--error-bg);
    color: var(--error-ink);
    border: 1px solid rgba(198,40,40,0.2);
}
.flash-success {
    background: var(--success-bg);
    color: var(--success-ink);
}

/* Dashboard */
.dashboard {
    max-width: 1100px;
    margin: 0 auto;
}
.dashboard h1 {
    font-size: 22px;
    color: var(--primary);
    margin: 0 0 16px;
}
.placeholder {
    background: var(--surface);
    padding: 32px;
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    color: var(--muted);
    text-align: center;
}

/* Upload */
.upload-zone {
    background: var(--surface);
    border-radius: var(--radius);
    padding: 16px;
    box-shadow: var(--shadow-sm);
    margin-bottom: 16px;
}
.upload-form { margin: 0; }
.upload-drop {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 18px 20px;
    border: 2px dashed var(--line);
    border-radius: var(--radius);
    cursor: pointer;
    transition: all 0.15s;
    background: #fafafa;
}
.upload-drop:hover,
.upload-zone.drag-over .upload-drop {
    border-color: var(--accent);
    background: #f0f7ff;
}
.upload-zone.drag-over .upload-drop {
    border-style: solid;
}
.upload-drop input[type="file"] {
    position: absolute;
    opacity: 0;
    pointer-events: none;
    width: 1px;
    height: 1px;
}
.upload-icon {
    font-size: 28px;
    color: var(--accent);
    flex: 0 0 auto;
}
.upload-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.upload-text strong { font-size: 14px; color: var(--ink); }
.upload-text small { font-size: 12px; color: var(--muted); }

.upload-flash {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 10px;
    padding: 10px 14px;
}
.upload-flash strong { font-weight: 600; }
.flash-dismiss {
    margin-left: auto;
    background: none;
    border: none;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    color: inherit;
    opacity: 0.6;
    padding: 0 4px;
}
.flash-dismiss:hover { opacity: 1; }

/* Queue toolbar */
.queue-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    align-items: center;
    margin-bottom: 8px;
    padding: 10px 12px;
    background: var(--surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
}
.status-pills {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}
.pill {
    background: #fafafa;
    border: 1px solid var(--line);
    border-radius: 16px;
    padding: 4px 12px;
    font-size: 12px;
    color: var(--muted);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: all 0.15s;
}
.pill:hover { background: #f0f0f0; }
.pill.active {
    background: var(--primary);
    border-color: var(--primary);
    color: #fff;
}
.pill .count {
    background: rgba(0, 0, 0, 0.08);
    border-radius: 8px;
    padding: 1px 7px;
    font-size: 11px;
    font-weight: 600;
}
.pill.active .count {
    background: rgba(255, 255, 255, 0.2);
    color: #fff;
}
.queue-search {
    flex: 1 1 260px;
    min-width: 200px;
    padding: 6px 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    font-size: 13px;
    background: #fafafa;
}
.queue-search:focus {
    outline: none;
    border-color: var(--primary);
    background: #fff;
}

/* Queue table */
.queue-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
    font-size: 13px;
}
.queue-table th {
    text-align: left;
    padding: 10px 12px;
    background: #fafafa;
    border-bottom: 1px solid var(--line);
    font-size: 11px;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.queue-table td {
    padding: 10px 12px;
    border-bottom: 1px solid #f4f4f4;
    vertical-align: middle;
}
.queue-table tr:last-child td { border-bottom: none; }
.queue-table tr:hover td { background: #fafafa; }
.queue-table tr.row-duplicate td:first-child { position: relative; }
.badge {
    display: inline-block;
    font-size: 10px;
    font-weight: 600;
    padding: 1px 6px;
    border-radius: 10px;
    margin-left: 6px;
    letter-spacing: 0.3px;
    vertical-align: middle;
}
.badge-duplicate {
    background: var(--warning-bg);
    color: var(--warning-ink);
    border: 1px solid rgba(230, 81, 0, 0.25);
    cursor: help;
}
.col-status { width: 24px; padding-right: 0; }
.col-size {
    text-align: right;
    font-family: 'SF Mono', 'Consolas', monospace;
    font-size: 12px;
    color: var(--muted);
    width: 90px;
}
.col-actions {
    width: 64px;
    text-align: right;
    padding-left: 0;
    white-space: nowrap;
}
.queue-row-delete,
.queue-row-retry {
    background: transparent;
    border: 1px solid transparent;
    color: var(--muted);
    font-size: 16px;
    line-height: 1;
    width: 24px;
    height: 24px;
    border-radius: 4px;
    cursor: pointer;
    padding: 0;
    opacity: 0.5;
    transition: opacity 0.15s, color 0.15s, background 0.15s, border-color 0.15s;
}
.queue-row-retry { margin-right: 2px; }
.queue-table tr:hover .queue-row-delete,
.queue-table tr:hover .queue-row-retry { opacity: 1; }
.queue-row-delete:hover {
    background: var(--error-bg);
    color: var(--error-ink);
    border-color: rgba(198, 40, 40, 0.3);
}
.queue-row-retry:hover {
    background: var(--success-bg);
    color: var(--primary);
    border-color: rgba(33, 150, 243, 0.3);
}
.col-filename a {
    color: var(--ink);
    text-decoration: none;
    font-weight: 500;
}
.col-filename a:hover {
    color: var(--primary);
    text-decoration: underline;
}
.col-filename .email-subject {
    display: block;
    font-size: 11px;
    color: var(--muted);
    margin-top: 2px;
}
.col-organization {
    color: var(--ink);
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.col-organization .muted {
    color: var(--muted);
    font-style: italic;
}
.col-status-name {
    width: 130px;
}
.col-status-name .status-name {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.3px;
    color: var(--muted);
}
.queue-sort-link {
    color: inherit;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    cursor: pointer;
}
.queue-sort-link:hover { color: var(--ink); }
.queue-sort-link.active { color: var(--ink); }
.queue-sort-link .sort-arrow {
    font-size: 10px;
    color: var(--primary);
}
.queue-pagination {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 12px;
    margin-top: 12px;
    font-size: 12px;
}
.queue-pagination .queue-page-info {
    color: var(--muted);
}
.queue-page-btn {
    background: var(--surface);
    border: 1px solid var(--line);
    color: var(--ink);
    padding: 4px 10px;
    border-radius: 4px;
    cursor: pointer;
    font-size: 12px;
    transition: background 0.15s, border-color 0.15s;
}
.queue-page-btn:hover:not(:disabled) {
    background: #f0f0f0;
    border-color: var(--primary);
}
.queue-page-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.status-dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: #9e9e9e;
}
.status-dot.status-uploaded { background: #9e9e9e; }
/* ocr_done = Azure finished but staging not done yet -> keep the
   "processing" colour, because the queue still links to the raw PDF
   until ready_for_review. Blue (clickable -> review form) is reserved
   for ready_for_review and later states. */
.status-dot.status-ocr_pending,
.status-dot.status-ocr_done { background: #ff9800; }
.status-dot.status-ready_for_review { background: #03a9f4; }
.status-dot.status-in_review { background: #673ab7; }
.status-dot.status-exported { background: #4caf50; }
.status-dot.status-rejected { background: #9e9e9e; opacity: 0.5; }
.status-dot.status-ocr_failed,
.status-dot.status-export_error { background: #f44336; }

.source-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: 10px;
    font-size: 11px;
    font-weight: 600;
}
.source-chip.source-upload {
    background: #e3f2fd;
    color: #0d47a1;
}
.source-chip.source-email {
    background: #f3e5f5;
    color: #6a1b9a;
}

/* Review pane.
 *
 * Layout strategy: the page itself scrolls, the PDF sticks to the top
 * of the viewport on the left, the form flows naturally on the right.
 * This lets the user scan every field without a nested scrollbar, and
 * keeps the PDF visible as they work down the form.
 */
.review-page {
    max-width: 1600px;
    margin: 0 auto;
    /* Inside .body-review main, fill the remaining viewport with a flex
     * column so review-header is fixed-height and review-layout takes
     * the rest, eligible for internal scroll on each side. */
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
    display: flex;
    flex-direction: column;
}
.review-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 8px;
    flex-wrap: wrap;
    gap: 8px;
    flex: 0 0 auto;
}
.review-header h1 {
    font-size: 20px;
    color: var(--primary);
    margin: 0;
}
.review-header h1 small {
    display: block;
    font-size: 12px;
    font-weight: 400;
    color: var(--muted);
    margin-top: 2px;
}
.back-link {
    font-size: 13px;
    color: var(--muted);
}
.review-layout {
    display: grid;
    /* 3-col grid: PDF | 6px splitter | form. JS updates the two `fr`
     * CSS vars from a persisted localStorage value; defaults to 50/50. */
    grid-template-columns:
        minmax(0, var(--review-pdf-fr, 1fr))
        6px
        minmax(0, var(--review-form-fr, 1fr));
    gap: 0;
    /* In .body-review the layout fills the available main area so the
     * children can scroll independently. align-items: stretch makes
     * both columns the same (full) height. */
    align-items: stretch;
    flex: 1 1 auto;
    min-height: 0;
}
.review-splitter {
    cursor: col-resize;
    background: var(--line);
    transition: background 0.15s;
    /* Wider hit target than the visible 6px without changing layout. */
    position: relative;
}
.review-splitter::before {
    content: "";
    position: absolute;
    top: 0; bottom: 0;
    left: -3px; right: -3px;
}
.review-splitter:hover,
.review-splitter--dragging {
    background: var(--accent);
}
.review-pdf {
    background: var(--surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    /* Parent .review-layout is fixed-height in .body-review; PDF fills
     * its grid cell and scrolls internally for multi-page documents. */
    height: 100%;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    /* When no input is focused, a failed click briefly flashes the
     * viewport so the user knows they need to select a field first. */
    transition: box-shadow 0.2s;
}
.review-pdf.pdf-needs-target {
    box-shadow: 0 0 0 2px var(--warning-ink);
}
.pdf-toolbar {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 6px 10px;
    background: #fafafa;
    border-bottom: 1px solid var(--line);
    font-size: 12px;
}
.pdf-toolbar button {
    background: transparent;
    border: 1px solid var(--line);
    border-radius: 4px;
    padding: 2px 10px;
    font-size: 12px;
    color: var(--ink);
    cursor: pointer;
    min-width: 28px;
}
.pdf-toolbar button:hover { background: #f0f0f0; }
.pdf-toolbar #pdf-zoom-label { font-variant-numeric: tabular-nums; }
.pdf-toolbar .pdf-hint {
    color: var(--muted);
    margin-left: auto;
    font-size: 11px;
}
.pdf-pages {
    flex: 1 1 auto;
    overflow: auto;
    padding: 12px;
    background: #f0f0f0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
}
.pdf-page-wrap {
    position: relative;
    background: #fff;
    box-shadow: var(--shadow-sm);
}
.pdf-page-wrap canvas {
    display: block;
    pointer-events: none; /* clicks go through to the text layer */
}
/* Word overlay: one invisible div per Azure DI word, positioned over
 * the rendered canvas. Click a word to assign; drag a marquee to
 * select multiple words in a spatial region (no cross-line bleed). */
.pdf-word-layer {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
    cursor: crosshair;
    user-select: none;
}
.pdf-word {
    position: absolute;
    background: transparent;
    border-radius: 2px;
    cursor: pointer;
    transition: background 0.05s;
}
.pdf-word:hover { background: rgba(33, 150, 243, 0.18); }
.pdf-marquee {
    position: absolute;
    border: 1px dashed var(--accent);
    background: rgba(33, 150, 243, 0.10);
    pointer-events: none;
    z-index: 3;
}

/* The most recently focused form input carries `.review-focus-target`
 * so the user can see where a PDF-click would land. */
.review-focus-target {
    outline: 2px solid var(--accent) !important;
    outline-offset: -1px;
}
/* Brief green flash after a PDF gesture assigns a value. */
.review-assign-flash {
    animation: review-assign-flash 0.6s ease-out;
}
@keyframes review-assign-flash {
    0%   { background: var(--success-bg); }
    100% { background: #fafafa; }
}
.review-form {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0; /* prevent grid child from overflowing its track */
    /* Internal vertical scroll so the form moves under a static PDF
     * + topbar instead of taking the whole page with it. */
    height: 100%;
    overflow-y: auto;
    overflow-x: hidden;
    padding-right: 4px;
}
.review-fieldset {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 6px 10px;
    box-shadow: var(--shadow-sm);
    margin: 0;
    min-width: 0;
}
.review-fieldset legend {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--muted);
    font-weight: 600;
    padding: 0 4px;
}
/* Header fields: auto-fit wrapping grid. Tight cap (140-200 px) so a
 * wide form column produces 4-5 columns of compact fields instead of
 * 2-3 stretched ones. .review-grid-wide and .review-grid-full still
 * let specific fields (CompanyName, textareas) span more space. */
.review-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 200px));
    gap: 6px;
}
.review-grid-wide { grid-column: span 2; }
.review-grid-full { grid-column: 1 / -1; }
.review-fieldset label {
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-size: 11px;
    color: var(--muted);
    min-width: 0;
}
.review-fieldset label input,
.review-fieldset label textarea {
    padding: 4px 7px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    font-size: 12px;
    background: #fafafa;
    color: var(--ink);
    font-family: inherit;
    width: 100%;
    min-width: 0;
}
.review-fieldset label input:focus,
.review-fieldset label textarea:focus {
    outline: none;
    border-color: var(--primary);
    background: #fff;
}
/* Read-only "computed from lines" fields. Same footprint as inputs so
   the row aligns; cursor + muted background signal "you can't type
   here". */
.review-fieldset label .field-derived,
output.field-derived {
    display: block;
    padding: 4px 7px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    font-size: 12px;
    background: #eeeeee;
    color: var(--ink);
    font-family: inherit;
    width: 100%;
    min-width: 0;
    cursor: not-allowed;
    text-align: right;
}
/* Per-VAT-rate breakdown table inside the totals fieldset. Borderless
   like the items table so the rate label and amount feel like one row,
   not a heavyweight grid. */
.review-vat-breakdown {
    width: 100%;
    border-collapse: collapse;
    font-size: 12px;
    margin: 6px 0;
}
.review-vat-breakdown th {
    text-align: left;
    color: var(--muted);
    font-weight: 500;
    padding: 3px 6px;
    border-bottom: 1px solid var(--line);
}
.review-vat-breakdown th.th-numeric { text-align: right; }
.review-vat-breakdown td {
    padding: 3px 6px;
    border-bottom: 1px dashed var(--line);
}
.review-vat-breakdown td:last-child { width: 30%; }
.review-vat-breakdown td input {
    width: 100%;
    padding: 3px 6px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    font-size: 12px;
    background: #fafafa;
    color: var(--ink);
    text-align: right;
}
.review-vat-breakdown td input:focus {
    outline: none;
    border-color: var(--primary);
    background: #fff;
}
.review-vat-breakdown .muted {
    color: var(--muted);
    font-style: italic;
}

/* ERP company lookup combobox.
   The wrapping fieldset/div is .company-combobox; one of its grid cells
   is .company-name-cell, which hosts the dropdown <ul.company-options>
   directly under the company_name input. The CompanyNo cell wraps its
   input with × button in .company-no-cell. */
.company-combobox {
    position: relative;
}
.company-name-cell {
    position: relative;
}
.company-options {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--surface);
    border: 1px solid var(--line);
    border-top: none;
    max-height: 280px;
    overflow-y: auto;
    z-index: 20;
    margin: 0;
    padding: 0;
    list-style: none;
    box-shadow: var(--shadow-md);
    font-size: 12px;
}
.company-options:empty {
    display: none;
    border: none;
}
.company-option {
    padding: 6px 8px;
    cursor: pointer;
    border-bottom: 1px solid var(--line);
}
.company-option:last-child {
    border-bottom: none;
}
.company-option:hover {
    background: #f0f4f9;
}
.company-option strong {
    display: block;
    font-weight: 600;
}
.company-option .muted {
    color: var(--muted);
    font-size: 11px;
}
.company-options .no-results {
    padding: 8px;
    color: var(--muted);
    font-style: italic;
    text-align: center;
}

/* Generic ID combobox -- krok 6d (Účtování dropdowns).
 *
 * Used for the four FK-backed Účtování fields. The visible <input>
 * carries the option label, a sibling hidden <input> carries the
 * Helios ID. Filter happens in JS (id_combobox.js). Optional "+"
 * button to the right (allow_create=true) triggers a creation
 * fetch -- only Zakázka has it. */
.id-combobox {
    display: flex;
    align-items: stretch;
    gap: 6px;
}
.id-combobox__field {
    position: relative;
    flex: 1 1 auto;
    min-width: 0;
}
.id-combobox__input {
    width: 100%;
}
.id-combobox__options {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    margin: 0;
    padding: 0;
    list-style: none;
    background: var(--surface);
    border: 1px solid var(--line);
    border-top: none;
    border-radius: 0 0 var(--radius-sm) var(--radius-sm);
    box-shadow: var(--shadow-md);
    max-height: 240px;
    overflow-y: auto;
    z-index: 30;
    font-size: 13px;
}
.id-combobox__option {
    padding: 6px 10px;
    cursor: pointer;
    border-bottom: 1px solid var(--line);
}
.id-combobox__option:last-child { border-bottom: none; }
.id-combobox__option:hover,
.id-combobox__option--active {
    background: #f0f4f9;
}
.id-combobox__option[hidden] { display: none; }
/* Inside the line-item table every <td> is overflow:hidden and the
 * .review-lines-scroll wrapper scrolls, which clips an absolutely
 * positioned dropdown to the cell. Switch the per-line combobox dropdown
 * to fixed positioning so it escapes the clip (mirrors .product-options);
 * coordinates are set by id_combobox.js positionFixedList(). */
.review-lines .id-combobox__options {
    position: fixed;
    left: auto;
    right: auto;
    z-index: 100;
}
.id-combobox__create {
    flex: 0 0 auto;
    align-self: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border-radius: 50%;
    border: 1px solid var(--accent);
    background: var(--surface);
    color: var(--accent);
    cursor: pointer;
    font-size: 18px;
    line-height: 1;
}
.id-combobox__create:hover {
    background: var(--accent);
    color: #fff;
}
.id-combobox__create:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}
.company-no-cell {
    display: flex;
    align-items: stretch;
    gap: 0;
}
.company-no-cell input {
    flex: 1;
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
    border-right: none;
}
.company-unmatch {
    width: 24px;
    flex: 0 0 24px;
    border: 1px solid var(--line);
    border-top-right-radius: var(--radius-sm);
    border-bottom-right-radius: var(--radius-sm);
    background: #fafafa;
    color: var(--muted);
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
}
.company-unmatch:hover {
    background: #fce4ec;
    color: var(--error-ink);
}
/* Horizontal scroll wrapper for the line-item table. The form column
 * has `overflow-x: hidden`, so when the user drag-resizes a column wider
 * than the form area, columns on the right would otherwise disappear
 * off-screen with no scrollbar. This wrapper isolates the scroll inside
 * the table area. */
.review-lines-scroll {
    overflow-x: auto;
    overflow-y: visible;
    /* Reserve ~half a row of slack below the last line so the horizontal
       scrollbar never overlaps it. The last row is often the empty
       "+ add" row, and hiding it under the scrollbar made it look like the
       table was complete while an empty line kept the Export button
       disabled. */
    padding-bottom: 18px;
}
.review-lines {
    width: 100%;
    border-collapse: collapse;
    font-size: 12px;
    table-layout: fixed;
}
/* Default column widths. Sum is wider than a typical viewport on
   purpose: the parent .review-lines-scroll has `overflow-x: auto`,
   so columns keep their width and the table scrolls horizontally
   when needed. Without an explicit width here col-description
   would collapse to 0 px under table-layout:fixed once the other
   columns' fixed widths exceed the viewport. Drag-resize in
   table_resize.js can still override per-user via inline style. */
.review-lines col.col-line-no      { width: 36px; }
.review-lines col.col-part-number  { width: 95px; }
/* Wide enough to fit the matched chip text + the unmatched-line
 * inline "Založit kartu" controls (SkupZbo select + "+" button). */
.review-lines col.col-match        { width: 140px; }
.review-lines col.col-description  { width: 240px; }
.review-lines col.col-quantity     { width: 95px; }
.review-lines col.col-unit         { width: 50px; }
.review-lines col.col-unit-price   { width: 100px; }
.review-lines col.col-last-price   { width: 100px; }
.review-lines col.col-vat-rate     { width: 60px; }
.review-lines col.col-line-total   { width: 110px; }
.review-lines col.col-delivery-date { width: 130px; }
.review-lines col.col-zakazka      { width: 150px; }
.review-lines col.col-remove       { width: 28px; }
/* Display-only row number rendered via CSS counter; auto-renumbers on
 * add/remove because tombstone rows (.review-line-deleted, hidden) are
 * excluded from the increment. The persisted LineNumber is assigned
 * server-side in save_review. */
.review-lines tbody { counter-reset: line-no; }
.review-lines tbody tr.review-line-row:not(.review-line-deleted) {
    counter-increment: line-no;
}
.review-lines tbody tr.review-line-row td.col-line-no::before {
    content: counter(line-no);
}
.review-lines tbody tr.review-line-row td.col-line-no {
    text-align: right;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    padding-right: 6px;
}
/* The part-number cell hosts the autocomplete dropdown beneath it;
 * position:relative anchors the absolutely-positioned .product-options
 * to the cell's bottom edge. */
.review-lines td.part-number-cell {
    position: relative;
}
.review-lines th {
    text-align: left;
    padding: 4px 6px;
    color: var(--muted);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.3px;
    font-weight: 600;
    border-bottom: 1px solid var(--line);
    border-right: 1px solid #f0f0f0;
    /* Resize handles overlay the right edge of each <th>; relative
       positioning lets them anchor to the cell. */
    position: relative;
    /* Clip oversized labels to the cell rather than letting them bleed
     * into adjacent columns. Right-aligned numeric labels (.th-numeric)
     * would otherwise overflow LEFT into POPIS at default widths. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Numeric columns: align header to the right so it lines up with the
 * right-aligned input values below. */
.review-lines th.th-numeric { text-align: right; }
.review-lines th:last-child { border-right: none; }
/* Odoo-style cells: subtle row separators, no per-cell rectangle, so
 * line items read as a unified table rather than a strip of widgets.
 * Vertical separator between columns is a faint dotted line that only
 * appears on hover -- keeps the resting state clean while still
 * giving the user a visual anchor while editing. */
.review-lines td {
    padding: 0;
    border-bottom: 1px solid #f0f0f0;
    border-right: 1px solid #f0f0f0;
    overflow: hidden;
}
.review-lines td:last-child { border-right: none; }
.review-lines tr:hover td {
    background: rgba(33, 150, 243, 0.04);
}
.review-lines input {
    width: 100%;
    padding: 5px 7px;
    border: 1px solid transparent;
    border-radius: 2px;
    font-size: 12px;
    background: transparent;
}
.review-lines input:focus {
    outline: none;
    border-color: var(--primary);
    background: #fff;
    box-shadow: 0 0 0 1px var(--primary) inset;
}
/* Numeric columns (Cena, Množství, DPH, Celkem) are right-aligned so
 * the decimal point stacks vertically column-by-column -- much easier
 * to scan a column of numbers than left-aligned text. */
.review-lines input[inputmode="decimal"] {
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.review-lines .col-remove { width: 28px; text-align: center; }
/* Drag handle injected by table_resize.js. 4 px wide, transparent
   except on hover so the column edge stays visually clean. */
.review-lines th .col-resize-handle {
    position: absolute;
    top: 0;
    right: 0;
    width: 6px;
    height: 100%;
    cursor: col-resize;
    user-select: none;
}
.review-lines th .col-resize-handle:hover,
.review-lines th .col-resize-handle.active {
    background: rgba(33, 150, 243, 0.25);
}
/* Tombstoned line rows: hidden from view but still in the form so
   their `lines[N].deleted=1` flag reaches the server. */
.review-lines .review-line-row.review-line-deleted { display: none; }
.review-line-remove {
    background: transparent;
    border: 1px solid var(--line);
    border-radius: 4px;
    color: var(--muted);
    width: 24px;
    height: 24px;
    line-height: 1;
    font-size: 14px;
    cursor: pointer;
    padding: 0;
}
.review-line-remove:hover {
    background: var(--error-bg);
    color: var(--error-ink);
    border-color: var(--error-ink);
}
#review-line-add {
    align-self: flex-start;
    margin-top: 8px;
    color: var(--primary);
    font-size: 12px;
    padding: 4px 10px;
}
.review-submit {
    position: sticky;
    bottom: 0;
    background: var(--bg);
    padding: 12px 0;
    display: flex;
    align-items: center;
    gap: 12px;
    z-index: 1;
}

/* Helios export -- krok 6. The button lives in .review-submit next
 * to Uložit; the result panel below the submit bar is the HTMX target
 * for outcome rendering. */
.helios-export-button[disabled] {
    cursor: not-allowed;
    opacity: 0.5;
}
.helios-already-exported {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border-radius: 4px;
    background: var(--success-bg);
    color: var(--success-ink);
    font-size: 0.9em;
}
.helios-already-exported code {
    background: transparent;
    font-weight: 600;
}
.helios-export-result {
    margin-top: 12px;
}
/* Read-only wrapper after Helios export. Neutralise the fieldset's
 * default border/margin/padding/min-width so it doesn't disturb the
 * form layout; the `disabled` attribute does the actual locking. */
.review-readonly {
    border: 0;
    margin: 0;
    padding: 0;
    min-inline-size: 0;
}
.review-readonly-notice {
    margin: 0 0 12px;
    padding: 8px 12px;
    border-radius: 4px;
    background: var(--success-bg);
    color: var(--success-ink);
    font-size: 0.9em;
}

/* Krok 6c -- inline "Založit kartu v Heliosu" controls next to the
 * ∅ chip in col-match. The SkupZbo <select> is kept narrow (its
 * dropdown still shows the full Nazev when open); the "+" button is
 * a compact circle. No floating panel -- everything sits in flow so
 * the table's overflow-x: auto wrapper can't clip it. */
.helios-create {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-left: 4px;
    vertical-align: middle;
}
.helios-create__skup {
    width: 52px;
    font-size: 11px;
    padding: 1px 2px;
    box-sizing: border-box;
}
.helios-create__confirm {
    width: 20px;
    height: 20px;
    padding: 0;
    line-height: 1;
    font-size: 14px;
    border: 1px solid var(--line);
    border-radius: 50%;
    background: var(--surface);
    color: var(--ink);
    cursor: pointer;
    user-select: none;
}
.helios-create__confirm:hover {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
}
.helios-create__confirm:disabled {
    opacity: 0.6;
    cursor: wait;
}
.helios-export-panel {
    padding: 10px 14px;
    border-radius: 4px;
    margin-top: 8px;
}
.helios-export-panel ul {
    margin: 6px 0 0 0;
    padding-left: 22px;
}
.helios-export-panel--success {
    background: var(--success-bg);
    color: var(--success-ink);
}
.helios-export-panel--blockers {
    background: var(--warning-bg);
    color: var(--warning-ink);
}
.helios-export-panel--error {
    background: var(--error-bg);
    color: var(--error-ink);
}
.helios-export-panel__meta,
.helios-export-panel__hint {
    margin: 4px 0 0 0;
    font-size: 0.85em;
    opacity: 0.85;
}

/* Narrower viewports: stack PDF above form so nothing gets cut. Also
 * fall back from .body-review's viewport-locked layout to normal page
 * scroll so the stacked form isn't squeezed into 40vh. */
@media (max-width: 960px) {
    .review-layout {
        grid-template-columns: 1fr;
        flex: none;
        min-height: 0;
    }
    .review-splitter { display: none; }
    .review-pdf { position: static; height: 60vh; }
    .body-review {
        height: auto;
        overflow: visible;
    }
    .body-review > main { padding: 24px; }
    .review-page { flex: none; min-height: 0; height: auto; }
    .review-form {
        height: auto;
        overflow: visible;
        padding-right: 0;
    }
}

/* Error pages */
.error-page {
    max-width: 480px;
    margin: 80px auto;
    text-align: center;
}
.error-page h1 {
    font-size: 64px;
    color: var(--primary);
    margin: 0 0 8px;
}

/* Per-template LLM prompt editor (krok 33). Native <dialog>;
   browsers that don't support showModal() degrade to inline render. */
.vendor-prompt-dialog {
    border: 1px solid #c5cae9;
    border-radius: 6px;
    padding: 0;
    width: min(720px, 90vw);
    max-height: 80vh;
    background: #fff;
    color: #212121;
}
.vendor-prompt-dialog::backdrop {
    background: rgba(0, 0, 0, 0.4);
}
.vendor-prompt-form {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 24px;
}
.vendor-prompt-form__title {
    margin: 0;
    font-size: 18px;
    font-weight: 600;
    color: #311b92;
}
.vendor-prompt-form__hint {
    margin: 0;
    font-size: 13px;
    color: #455a64;
    line-height: 1.4;
}
.vendor-prompt-form__textarea {
    width: 100%;
    box-sizing: border-box;
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    font-size: 13px;
    line-height: 1.45;
    padding: 8px;
    border: 1px solid #b0bec5;
    border-radius: 4px;
    resize: vertical;
    min-height: 220px;
}
.vendor-prompt-form__actions {
    display: flex;
    justify-content: flex-end;
    gap: 12px;
}

/* Prompt-template editor button — same outlined-secondary look as the
   modal's Cancel button below. Sits 24px to the right of the primary
   AI-clean button so an accidental click is unlikely. The .btn-link
   base supplies the reset (no background, no border by default), this
   rule replaces every visual it needs. */
.review-line-prompt-edit {
    float: right;
    color: var(--primary);
    background: #fff;
    border: 1px solid var(--primary);
    border-radius: 4px;
    font-size: 13px;
    padding: 6px 14px;
    cursor: pointer;
}
.review-line-prompt-edit:hover {
    background: #ede7f6;
    color: var(--primary);
    text-decoration: none;
}
.review-line-prompt-edit:focus {
    outline: 2px solid var(--primary);
    outline-offset: 1px;
}
.review-line-prompt-edit[disabled] {
    color: #b0bec5;
    border-color: #cfd8dc;
    background: #f5f5f5;
    cursor: not-allowed;
}
.review-line-prompt-edit[disabled]:hover {
    background: #f5f5f5;
    color: #b0bec5;
}

/* Secondary button — outlined neutral, used for modal Cancel etc. */
.btn-secondary {
    background: #fff;
    color: #455a64;
    border: 1px solid #b0bec5;
    border-radius: 4px;
    font: inherit;
    font-size: 13px;
    padding: 6px 14px;
    cursor: pointer;
}
.btn-secondary:hover {
    background: #eceff1;
    color: #263238;
}
.btn-secondary:focus {
    outline: 2px solid #78909c;
    outline-offset: 1px;
}
