/* Fakturovna — all interface styling.
   One frame for every screen (ADR-017): a rail on the left, the work on the
   right, one status dot per document. Served by the StaticFiles mount; the
   link carries a ?v= built from this file's contents, because the deploy path
   (rsync, docker build, rollout) has no other cache-busting story.
   Order: tokens → base → rail → toolbar & controls → status → list → review →
   batches → dialogs → admin → utilities. */

/* ---- type ------------------------------------------------------------------
   IBM Plex Sans, self-hosted. It has to be: druzba runs on a LAN with no route
   out, so a <link> to Google Fonts would fail silently and every screen would
   fall back to the system stack — nobody would ever see the font that was
   chosen. `latin-ext` is not optional either; without it every š č ř ž ě ů in
   the interface comes from a different typeface.

   Plex Sans ships as one variable file per subset covering 100-700, so the two
   weights the interface uses (400 and 600) cost one download, not two. Plex Mono
   is static and needs a file per weight. 102 kB in total, cached for good:
   the filenames never change because the contents never do.

   IBM Plex is SIL OFL 1.1 — see app/static/fonts/README.md.
-------------------------------------------------------------------------------- */
@font-face {
  font-family:'IBM Plex Mono'; font-style:normal; font-weight:400;
  font-display:swap; src:url('/static/fonts/ibm-plex-mono-400-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family:'IBM Plex Mono'; font-style:normal; font-weight:400;
  font-display:swap; src:url('/static/fonts/ibm-plex-mono-400-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family:'IBM Plex Mono'; font-style:normal; font-weight:600;
  font-display:swap; src:url('/static/fonts/ibm-plex-mono-600-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family:'IBM Plex Mono'; font-style:normal; font-weight:600;
  font-display:swap; src:url('/static/fonts/ibm-plex-mono-600-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family:'IBM Plex Sans'; font-style:normal; font-weight:100 700;
  font-display:swap; src:url('/static/fonts/ibm-plex-sans-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family:'IBM Plex Sans'; font-style:normal; font-weight:100 700;
  font-display:swap; src:url('/static/fonts/ibm-plex-sans-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---- tokens ---------------------------------------------------------------- */
:root {
  --paper:#fafaf7; --card:#ffffff; --ground:#eceee8;
  --ink:#1b1f23; --mut:#6b7280;
  --line:#d6d8d0; --line-soft:#e6e7e2;
  --green:#1d6a4c; --green-soft:#e4efe9;
  --amber:#b4690e; --amber-soft:#faf0e0;
  --red:#b3402e; --red-soft:#f8e7e3;
  /* text-only amber: --amber is 4.23:1 on white, under the 4.5:1 AA needs.
     This is 6.56:1. Dots, bars and borders stay on --amber, where contrast is
     not what carries meaning. */
  --amber-ink:#8a4f0a;
  /* The boundary between the rail and the work surface. A step darker than
     --line on purpose: --line is the hairline *inside* a region (row
     separators), and the edge between two regions has to outrank it or the
     frame reads as one undivided sheet. */
  --edge:#c3c6bd;
  /* The header band, held by both .brand and .toolbar. One value rather than
     two, because the bug it fixes was exactly that the rail's height was fixed
     and the toolbar's was content-driven, so the two rules under them landed
     7-9px apart and the offset flipped sign from page to page. */
  --topbar:51px;
  --mono:'IBM Plex Mono',ui-monospace,'SF Mono',Menlo,monospace;
}

/* ---- base ------------------------------------------------------------------ */
* { box-sizing:border-box; }
html { height:100%; }
/* min-height, not height: a fixed body clips the sticky rail's containing block to one
   viewport and it scrolls away with the page */
body { min-height:100%; }
body { margin:0;
       font:13px/1.45 'IBM Plex Sans',system-ui,-apple-system,'Segoe UI',sans-serif;
       background:var(--paper); color:var(--ink); }
a { color:var(--green); }
b, strong { font-weight:600; }
h1, h2, h3 { font-weight:600; margin:0; }
h2 { font-size:14px; }
input, select, button, textarea { font:inherit; color:inherit; }
input[type=text], input[type=search], input[type=number], input[type=password],
input[type=email], input[type=date], input:not([type]), select, textarea {
  border:1px solid var(--line); border-radius:3px; padding:6px 8px;
  background:var(--card); min-width:0; }
input:disabled, input[readonly] { background:var(--ground); color:var(--mut); }
input[type=checkbox], input[type=radio] { accent-color:var(--green); margin:0; }
:focus-visible { outline:2px solid var(--green); outline-offset:1px; }
code, .mono { font-family:var(--mono); }
.idcode { font-family:var(--mono); font-size:12px; }
.mut { color:var(--mut); }
.small { font-size:12px; }
.tab { font-variant-numeric:tabular-nums; }
.grow, .sp { flex:1; }
.ellip { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
[hidden] { display:none !important; }
.link { color:var(--green); text-decoration:underline; }
.icon-sprite { position:absolute; width:0; height:0; overflow:hidden; }
.ic { width:1.05em; height:1.05em; flex:none; vertical-align:-.16em;
      fill:none; stroke:currentColor; stroke-width:1.75;
      stroke-linecap:round; stroke-linejoin:round; }

/* ---- frame ----------------------------------------------------------------- */
body.shell { display:grid; grid-template-columns:184px minmax(0,1fr); min-height:100vh; }
body.bare { display:flex; align-items:center; justify-content:center; }
main { display:flex; flex-direction:column; min-width:0; }
.work { padding:0 24px 24px; flex:1; display:flex; flex-direction:column; min-width:0; }

.rail { background:var(--card); border-right:2px solid var(--edge);
        display:flex; flex-direction:column; position:sticky; top:0; height:100vh;
        align-self:start; }
.brand { display:flex; align-items:center; gap:10px; height:var(--topbar);
         padding:0 16px; border-bottom:1px solid var(--line); color:var(--ink);
         text-decoration:none; }
/* Variant 06, the stamp, at both sizes it is used. The lettering is drawn, not
   set, so it takes the interface's own mono face and its accent through `color`
   rather than through `var()` inside presentation attributes, which browsers
   honour unevenly — and `textLength` pins the tracked wordmark to its frame, so
   a fallback face while Plex Mono loads cannot push it through the border. */
.brand .mark { height:26px; width:auto; flex:none; }
.brand b { font-size:15px; letter-spacing:-.01em; }
.brand .stamp, .brand .stampf { color:var(--green); }
.brand .stamp text, .brand .stampf text {
  font-family:var(--mono); font-weight:600; fill:currentColor; }
/* On the login card the mark is the wordmark — it carries the name itself, so
   nothing is set beside it and it may take the width the card allows. */
.bare .card .brand { height:auto; }
.bare .card .mark { height:auto; width:280px; max-width:100%; }
.railnav { padding:12px 12px; display:grid; gap:2px; }
.railnav a { display:flex; justify-content:space-between; align-items:center;
             padding:8px 10px; color:var(--ink); text-decoration:none; border-radius:3px; }
.railnav a:hover { background:var(--paper); }
.railnav a.on { background:var(--ground); font-weight:600; }
.railnav .cnt { color:var(--mut); font-weight:400; font-variant-numeric:tabular-nums; }
.subnav { display:grid; padding:2px 0 2px 14px; font-size:12px; }
.subnav a { padding:6px 10px; color:var(--mut); border-radius:0; }
.subnav a.on { background:none; color:var(--ink); font-weight:600;
               border-left:2px solid var(--green); margin-left:-2px; }
.railsec { padding:4px 16px 12px; font-size:12px; color:var(--mut);
           border-top:1px solid var(--line-soft); margin-top:6px;
           /* a flex column that may shrink: see .railsec .q below */
           display:flex; flex-direction:column; min-height:0; }
.railsec h3 { padding:10px 0 6px; font-size:11px; text-transform:uppercase;
              letter-spacing:.04em; color:var(--mut); }
/* The queue shows twelve entries now, not six. .rail is a fixed 100vh column
   that never scrolls, and .railfoot is held down by margin-top:auto — so the
   extra rows have nowhere to go but through the bottom edge, taking the
   language switch and the build tag off screen with them. The queue scrolls
   inside itself instead: it is the one part of the rail that has more to show
   than it has room for, so it is the part that gives way. min-height:0 lets it
   fall below the cap as well, on a viewport too short even for that. */
.railsec .q { display:grid; gap:5px; font-family:var(--mono);
              max-height:230px; min-height:0; overflow-y:auto; }
.railsec .q a, .railsec .q .cur { display:flex; align-items:center; gap:7px;
                                  color:var(--mut); text-decoration:none; }
.railsec .q a:hover { color:var(--ink); }
.railsec .q .cur { color:var(--ink); font-weight:600; }
.railsec .q .more { color:var(--mut); padding-left:15px; }
.railfoot { margin-top:auto; padding:12px 16px; border-top:1px solid var(--line);
            font-size:12px; color:var(--mut); }
.railfoot a { color:var(--mut); }
.langsw { margin:2px 0 0; }
.langsw button { border:0; background:none; padding:0; color:var(--mut); cursor:pointer; }
.langsw button.on { color:var(--ink); font-weight:600; cursor:default; }
.buildtag { margin-top:6px; font-family:var(--mono); font-size:11px; color:#a2a8b0; }

/* ---- toolbar & controls ---------------------------------------------------- */
.toolbar { display:flex; align-items:center; gap:12px; height:var(--topbar);
           padding:0 24px; border-bottom:1px solid var(--line); background:var(--card);
           min-width:0; white-space:nowrap; }
.toolbar .back { color:var(--mut); text-decoration:none; }
.toolbar .meta { color:var(--mut); overflow:hidden; text-overflow:ellipsis; min-width:0; }
.toolbar h2 { font-size:14px; }
.scope { display:inline-flex; align-items:center; gap:8px; padding:3px 6px 3px 9px;
         background:var(--ground); border:1px solid var(--line); color:var(--mut); }
.scope a { color:var(--mut); text-decoration:none; font-size:15px; line-height:1; }
.scope a:hover { color:var(--ink); }
/* The filters in force, named on the page instead of behind a folded drawer.
   They take .scope's shape rather than a new one: the batch tag stands right
   beside them and both say the same thing — you are looking at part of the
   list, here is the way out. The × drops its own filter and leaves the rest.
   flex:none, because the search box next to them shrinks first: a filter the
   reader cannot see is worse than a tight toolbar. */
.chips { display:flex; align-items:center; gap:6px; flex:none; }
.chip.filter { display:inline-flex; align-items:center; gap:8px; font-size:inherit;
               padding:3px 6px 3px 9px; border-radius:0; background:var(--ground); }
.chip.filter a { color:var(--mut); text-decoration:none; font-size:15px; line-height:1; }
.chip.filter a:hover { color:var(--ink); }
.crumbs { color:var(--mut); }
.crumbs b { color:var(--ink); }

.btn, button.btn, a.btn { display:inline-block; color:var(--ink); border:1px solid var(--line);
       padding:7px 12px; border-radius:3px; background:var(--card); text-decoration:none;
       cursor:pointer; white-space:nowrap; line-height:1.3; }
.btn:hover { background:var(--paper); }
.btn.primary { background:var(--green); border-color:var(--green); color:#fff;
               font-weight:600; padding:8px 14px; }
.btn.primary:hover { background:#185a40; }
.btn.small { padding:5px 12px; }
.btn:disabled, .btn.off { background:var(--line); border-color:var(--line);
                          color:var(--mut); cursor:default; }
.btn.danger { color:var(--red); }
.linkbtn { border:0; background:none; padding:0; color:var(--mut); cursor:pointer;
           text-decoration:underline; }
.pv-btn { border:1px solid var(--line); background:var(--card); color:var(--ink);
          padding:3px 8px; border-radius:3px; font-size:12px; cursor:pointer; }
.pv-btn:hover { border-color:var(--green); color:var(--green); }
.pv-btn.is-off { opacity:.35; pointer-events:none; }
.pv-btn.ico { display:inline-flex; align-items:center; justify-content:center; }

/* the saved views: one segment, the active view lifted */
.views { display:flex; gap:2px; background:var(--ground); padding:2px; border-radius:4px;
         flex:none; }
.view { padding:6px 12px; color:var(--ink); text-decoration:none; border-radius:3px;
        display:inline-flex; align-items:center; gap:6px; }
.view:hover { background:rgba(255,255,255,.6); }
.view.on { background:var(--card); font-weight:600; box-shadow:0 1px 0 var(--line); }
.badge { display:inline-block; font-variant-numeric:tabular-nums; font-weight:600; }
.badge.err { color:var(--red); }
.badge.warn { color:var(--amber-ink); }
.badge.ok { color:var(--green); }
.badge.plain { color:var(--mut); font-weight:400; }
.view .badge::before { content:'· '; color:var(--mut); font-weight:400; }
.railnav .badge { font-weight:400; }

.searchform { display:contents; }
.search { flex:1 1 120px; min-width:0; max-width:300px; background:var(--paper);
          padding:7px 10px; }
.filterdrawer { position:relative; }
.filterdrawer > summary { list-style:none; cursor:pointer; }
.filterdrawer > summary::-webkit-details-marker { display:none; }
.filterdrawer[open] > summary .btn { background:var(--ground); }
.filterpanel { position:absolute; top:calc(100% + 6px); left:0; z-index:30;
               background:var(--card); border:1px solid var(--line); border-radius:3px;
               box-shadow:0 4px 12px rgba(0,0,0,.08); padding:14px 16px; width:520px;
               white-space:normal; }
.filterpanel .formgrid { grid-template-columns:repeat(3, minmax(0,1fr)); }
.filterpanel .acts { display:flex; gap:12px; align-items:center; margin-top:12px; }

/* the overview: four tiles that are links, the queue button, the last runs */
.tiles { display:grid; grid-template-columns:repeat(4, minmax(0,1fr)); gap:12px; margin-top:16px; }
.tile { display:flex; flex-direction:column; gap:4px; padding:14px 16px; text-decoration:none;
        color:var(--ink); background:var(--card); border:1px solid var(--line);
        border-top:3px solid var(--line); min-width:0; }
.tile:hover { background:var(--paper); }
.tile > b { font-size:28px; line-height:1; font-variant-numeric:tabular-nums; }
.tile .lbl { font-weight:600; }
.tile .sub { font-size:12px; color:var(--mut); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.tile.red { border-top-color:var(--red); } .tile.red > b { color:var(--red); }
.tile.amber { border-top-color:var(--amber); } .tile.amber > b { color:var(--amber-ink); }
.tile.green, .tile.ok { border-top-color:var(--green); } .tile.green > b { color:var(--green); }
.startrow { display:flex; align-items:center; gap:14px; margin-top:16px; flex-wrap:wrap; }
.facts { display:flex; gap:14px; flex-wrap:wrap; padding:12px 0; font-size:12px; color:var(--mut); }
.facts .k { color:var(--mut); text-transform:uppercase; letter-spacing:.04em; font-size:11px; margin-right:4px; }
.facts a { color:var(--mut); }

/* the status strip: the overview's warnings, on the list in one line */
.strip { display:flex; align-items:center; gap:14px; padding:6px 24px; flex-wrap:wrap;
         border-bottom:1px solid var(--line); font-size:12px; color:var(--mut);
         background:var(--paper); }
.strip a { color:var(--mut); }
.strip .amber { color:var(--amber-ink); }
.strip .warnk { color:var(--red); }

/* ---- status ---------------------------------------------------------------- */
.dot { display:inline-block; width:8px; height:8px; border-radius:50%; flex:none;
       background:var(--line); vertical-align:0; }
.dot.red { background:var(--red); }
.dot.amber { background:var(--amber); }
.dot.green { background:var(--green); }
.dot.grey { background:var(--line); }
.dot.processing { box-shadow:0 0 0 2px var(--amber-soft); }
.legend .dot { width:7px; height:7px; margin-right:4px; }
.chip { color:var(--mut); font-size:11px; border:1px solid var(--line); padding:0 4px;
        border-radius:2px; white-space:nowrap; }
.chip.amber { color:var(--amber-ink); border-color:var(--amber); }

/* ---- the list (Doklady) ---------------------------------------------------- */
.fbox { border:1px solid var(--line); border-left-width:3px; background:var(--card);
        padding:8px 12px; margin:14px 0 0; }
.fbox ul { margin:4px 0 0; padding-left:18px; color:var(--mut); }
.fbox.greenv, .fbox.ok { border-color:var(--green); }
.fbox.greenv strong, .fbox.ok strong { color:var(--green); }
.fbox.amber, .fbox.warn { border-color:var(--amber); }
.fbox.amber strong, .fbox.warn strong { color:var(--amber-ink); }
.fbox.red, .fbox.err { border-color:var(--red); }
.fbox.red strong, .fbox.err strong { color:var(--red); }
.fbox.grey, .fbox.blue { border-color:var(--line); }
.fbox.grey strong, .fbox.blue strong { color:var(--mut); }

.bulk { display:flex; align-items:center; gap:14px; padding:8px 24px; margin:0 -24px;
        background:var(--ground); border-bottom:1px solid var(--line); }
.bulk b { font-variant-numeric:tabular-nums; }

/* Every table header in the app, in one place. They used to be four separate
   declarations that agreed on 11px and disagreed on weight (600/400/600), on
   padding, and on whether they had a background at all — so they read as four
   different kinds of thing. 12px rather than 11px, and more air above the rule,
   so a header reads as the names of the columns rather than as a caption. */
.list thead th.c,
.runs > div.hd > span,
table.data th { font-size:12px; font-weight:600; text-transform:uppercase;
                letter-spacing:.05em; color:var(--mut);
                border-bottom:1px solid var(--line); }

/* A table with a frame: header on --ground, hairlines between rows. Widths are
   fixed so a column sits in the same place on every page; the text columns
   (document, supplier, sender) absorb whatever is left.

   The table scrolls inside .tblwrap so the page itself never scrolls sideways —
   the same arrangement .runs-scroll uses for the run table. The min-width lives
   on the wrapped table only: .list is a shape, not one screen, and a narrow
   table has no reason to be held open. The number is the budget below added up:
   796px of fixed columns against 33% of shares needs 796/0.67 = 1188px before
   the fixed columns start giving up pixels, so 1200.

   Dropping the tax-point and due-date columns is what brought this under a
   laptop: the work surface is the viewport less the 186px rail and 48px of
   padding, so a 1440-wide window has 1206px and the list no longer scrolls
   sideways at all. Below that it still does, which is what .tblwrap is for. */
.tblwrap { overflow-x:auto; }
.tblwrap .list { min-width:1200px; }
.list { width:100%; border-collapse:collapse; table-layout:fixed; margin-top:12px;
        background:var(--card); border:1px solid var(--line); }
/* 48px, not 36: the supplier cell carries a second, muted line now (.name .sub)
   and two lines do not sit in 36. The header keeps 36 — it has one line and
   never gets a second, and a header as tall as its rows stops reading as a
   header. */
.list th.c, .list td.c { padding:0 10px; border-bottom:1px solid var(--line-soft);
                          vertical-align:middle; text-align:left; white-space:nowrap;
                          overflow:hidden; text-overflow:ellipsis; }
.list th.c { height:36px; }
.list td.c { height:48px; }
.list thead th.c { background:var(--ground); }
/* A sortable header is the header, not a link inside it: it inherits colour,
   size and letter-spacing, so the row still reads as the names of the columns
   and only the cursor and the underline say it can be clicked. */
.list th.c a.sortlink { display:inline-flex; align-items:center; gap:4px;
                        color:inherit; font:inherit; letter-spacing:inherit;
                        text-decoration:none; cursor:pointer; }
.list th.c a.sortlink:hover { text-decoration:underline; }
/* The arrow is a hint, not a second label — faint enough that eleven of them
   do not turn the header into a row of glyphs. The column actually sorted on
   carries .on and pulls both its name and its arrow up to --ink, which is what
   distinguishes it from the ten that merely offer to sort. */
.list th.c .arrow { font-size:9px; line-height:1; color:var(--line); }
.list th.c a.sortlink.on, .list th.c a.sortlink.on .arrow { color:var(--ink); }
.list tbody tr:last-child td.c { border-bottom:0; }
.list tbody tr:hover td.c { background:var(--paper); }
.list tbody tr.sel td.c { background:var(--green-soft); }
/* The widths are one budget, not eleven separate decisions, and the budget was
   redrawn as a whole when the tax-point and due-date columns went and the one
   solved/reason column became two (who, and when). Fixed: 36 + 22 + 116 + 64 +
   110 + 112 + 110 + 76 + 150 = 796px. What is left is split between the three
   columns that hold prose — document 13%, supplier 12%, sender 8% — as
   percentages, which in a fixed-layout table are shares of what is left rather
   than promises: a page that omits one of them simply gives its share to the
   others. The shares are deliberately modest, because every point spent here
   is a point the table cannot fit on a laptop. */
.list .sel { width:36px; padding-right:0; }
.list .dot-c { width:22px; padding:0; }
/* The id column had no width at all, so a fixed-layout table gave it whatever
   was left and the ellipsis ate it — invisible while the mask was six letters,
   obvious at nine. Sized for `sequence.MAX_LENGTH`, so the next mask change
   does not bring it back. */
.list .c.idc { width:116px; font-variant-numeric:tabular-nums; }
.list .c.typ { width:64px; }
.list .c.doc { width:13%; }
/* The supplier's name, with its registration number as the muted second line —
   the widest share after the document, because a company name is what the eye
   looks for when it scans the list for one invoice. */
.list .c.supplier { width:12%; }
.list .c.num { width:110px; font-variant-numeric:tabular-nums; }
.list .c.amt { width:112px; text-align:right; font-variant-numeric:tabular-nums; }
.list .c.sender { width:8%; color:var(--mut); }
/* Who closed the document, and when — two cells, because one column holding a
   name and a date could not be sorted on either. The date takes tabular figures
   so the column reads as a column; the name does not need them. */
.list .c.solved { width:110px; color:var(--mut); }
.list .c.when { width:76px; color:var(--mut); font-variant-numeric:tabular-nums; }
/* Outside the budget above: neither column is in the list's row any more. .c.vs
   has no template rendering it at all, and .c.why is the pre-split reason cell,
   kept only until the list stops rendering it. */
.list .c.vs { width:96px; font-variant-numeric:tabular-nums; }
.list .c.why { width:10%; }
/* Due dates carry their state in colour: past due, and due today or tomorrow.
   Not on .c.due, so the template can paint the whole cell or just the date. */
.list .due.over { color:var(--red); }
.list .due.soon { color:var(--amber-ink); }
.list .c.act { width:150px; text-align:right; }
.list .idcode { text-decoration:none; }
.list a.idcode:hover { text-decoration:underline; }
/* Two-line cells: a name, and a muted line under it — the supplier with its
   registration number, and the document where the template puts a second line
   under the filename. The clipping has to move off the cell and onto each line,
   because the cell's own white-space:nowrap would run both of them into one;
   and each line clips separately, so a long name cannot push the line under it
   out of sight. */
.list .c.doc, .list .c.supplier { white-space:normal; }
.list .c.doc .name, .list .c.supplier .name, .list .name .sub,
.list .c.doc .sub, .list .c.supplier .sub {
  display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* Both nestings: the sub-line is a sibling of the name when the name is a link,
   and a child of it when the whole cell is one. */
.list .name .sub, .list .c.doc .sub, .list .c.supplier .sub {
  font-size:12px; color:var(--mut); font-weight:400; }
.doc .head { display:flex; gap:8px; align-items:baseline; min-width:0; }
.doc .head .name { font-weight:600; color:var(--ink); text-decoration:none;
                   overflow:hidden; text-overflow:ellipsis; white-space:nowrap; flex:0 1 auto; }
.doc .head a.name:hover { text-decoration:underline; }
.doc .head .num { flex:0 1 auto; overflow:hidden; text-overflow:ellipsis; }
.doc .head .chip { flex:none; }
.why .reason { color:var(--mut); }
.why .reason.red { color:var(--red); }
.why .reason svg { vertical-align:-2px; margin-right:4px; }
.pact { color:var(--green); font-weight:600; text-decoration:none; }
.pact:hover { text-decoration:underline; }
.more { border:0; background:none; color:var(--mut); padding:0 2px; margin-left:8px;
        cursor:pointer; font-size:14px; line-height:1; letter-spacing:1px; border-radius:3px; }
.more:hover, .more[aria-expanded=true] { color:var(--ink); }
.dl { color:var(--ink); text-decoration:none; font-weight:600; }
.dl:hover { text-decoration:underline; }
.dl.off { color:var(--mut); font-weight:400; }
.list-foot .legend { display:inline; text-transform:none; font-size:12px; }
.list tr.empty td.c { height:auto; padding:40px 24px; text-align:center; color:var(--mut); }
/* The second line under an empty table: this view is empty, the system is not,
   and here is the search across all of them. Quieter than the sentence above
   it — it is an offer, not the answer — but the way out has to look clickable,
   so the link keeps the underline it has everywhere else. */
.emptyhint { display:block; margin-top:8px; font-size:12px; color:var(--mut); }
.emptyhint a { color:var(--green); text-decoration:underline; }
.list-foot { padding:10px 0; font-size:12px; color:var(--mut); display:flex;
             justify-content:space-between; gap:14px; flex-wrap:wrap; margin-top:auto; }
.list-foot a { color:var(--mut); }
.list-foot a.on { color:var(--ink); text-decoration:none; }
.pager { display:flex; justify-content:flex-end; gap:6px; margin-top:14px; font-size:12px; }
.pager a, .pager span { padding:4px 8px; border:1px solid var(--line); border-radius:3px;
                        color:var(--ink); text-decoration:none; }
.pager span.on { background:var(--ink); color:#fff; border-color:var(--ink); }
.pager span.gap { border:0; color:var(--mut); padding:4px; }

/* the row menu, one element for the whole list, positioned by script */
.menu { position:absolute; z-index:40; background:var(--card); border:1px solid var(--line);
        border-radius:3px; box-shadow:0 4px 12px rgba(0,0,0,.08); min-width:190px;
        padding:0; text-align:left; }
.menu a, .menu span { display:block; padding:8px 12px; color:var(--ink); text-decoration:none; }
.menu a:hover { background:var(--paper); }
.menu a.sep { border-top:1px solid var(--line-soft); }
.menu .mut { color:var(--mut); }
.menu span { font-size:12px; }
.menu a.danger { color:var(--red); }

/* ---- review (Kontrola) ----------------------------------------------------- */
/* Typed, so a bad value can never take the layout with it. An untyped custom
   property holding nonsense makes every declaration that uses it invalid at
   computed-value time — here that turned two grid tracks into one and dropped
   the document below the form. Typed, the nonsense is ignored and the initial
   value stands. */
/* 48%, not 320px: the work is comparing a scan against a form, and at 320px on a
   1440px screen the scan gets 22% of the width — unreadable without zooming, so
   the first act of every document was a zoom. The narrow step still exists and
   is one click away; it is just no longer what somebody meets on their first
   day. The remembered setting (localStorage) outranks this for anyone who has
   already chosen. */
@property --pv-w {
  syntax: '<length-percentage>';
  inherits: true;
  initial-value: 48%;
}

/* The document's share of the width is a variable, so widening it narrows the
   form beside it rather than pushing the form out of the way. The old "big" mode
   collapsed to one column and stacked the page above the form, which meant that
   reading the document and reading the field you were fixing could not happen at
   once — the one thing the split screen exists for. */
/* The document sits on the left, the form on the right. It used to be the other
   way round, which sent the eye from a field rightwards to the page and back
   across the whole width for every value being checked. Source on the left is
   the order this reads in anyway — where am I (rail), what have I got
   (document), what do I do with it (form).
   Placed by column rather than by DOM order: the form stays first in the markup,
   so tabbing starts in the fields and a narrow screen still stacks the document
   under the form rather than pushing the work below the fold. */
.review { display:grid; grid-template-columns:var(--pv-w, 48%) minmax(0,1fr); flex:1;
          margin:0 -24px -24px; }
.revmain { grid-column:2; padding:18px 24px 24px; min-width:0; }
.preview { grid-column:1; grid-row:1;
           border-right:1px solid var(--line); background:var(--ground); padding:12px;
           display:flex; flex-direction:column; gap:10px; position:sticky; top:0;
           height:100vh; overflow:hidden; }
.preview .pvbar { display:flex; justify-content:space-between; align-items:center;
                  font-size:12px; color:var(--mut); gap:8px; flex-wrap:wrap; }
.preview .pvbar .pv-btn { padding:2px 6px; }
.pv-wrap { position:relative; overflow:auto; background:var(--card); border:1px solid var(--line);
           flex:1; min-height:0; }
/* Zoom scales the page inside its pane and the pane scrolls, so the whole
   document stays reachable at any magnification. The magnifier this replaces
   showed a 600x340 window that followed the cursor: it could only ever show one
   figure at a time, it hid the cursor to do it, and nothing it revealed could be
   scrolled, compared or kept on screen while you typed the value into the form. */
.pv-wrap img { display:block; width:calc(100% * var(--pv-zoom, 1)); max-width:none;
               height:auto; cursor:zoom-in; }
.review.pv-wide .pv-wrap img { cursor:zoom-out; }
/* while a drag is under way the cursor belongs to the page being moved, not to
   what a click would have done */
.pv-wrap.is-dragging img, .pvfull-scroll.is-dragging img { cursor:grabbing; }
.pv-wrap.is-dragging, .pvfull-scroll.is-dragging { user-select:none; }
.preview .pvbar .pv-z { font-variant-numeric:tabular-nums; min-width:38px;
                        text-align:center; }

.errbox { border:1px solid var(--red); border-left-width:3px; background:var(--card);
          padding:10px 14px; margin-bottom:20px; }
.errbox .top { display:flex; justify-content:space-between; align-items:baseline; gap:12px;
               flex-wrap:wrap; }
.errbox .top b { color:var(--red); }
.errbox ol { margin:6px 0 0; padding-left:18px; line-height:1.7; }
.errbox ol a { color:var(--ink); }
.errbox.amber { border-color:var(--amber); }
.errbox.amber .top b { color:var(--amber-ink); }
.errbox .acts { display:flex; gap:14px; margin-top:8px; }
.errbox .acts .danger { color:var(--red); }
.errbox .mut { color:var(--mut); }

.sec { margin-top:22px; }
.sec:first-child, .parties .sec { margin-top:0; }
.sech { display:flex; justify-content:space-between; align-items:baseline; gap:12px;
        border-bottom:1px solid var(--ink); padding-bottom:5px; margin-bottom:10px; }
.sech b { font-size:13px; }
.sech .st { font-size:12px; color:var(--mut); }
.sech .st.ok { color:var(--green); }
.sech .st.warn { color:var(--amber-ink); }
.sech .st.err { color:var(--red); }
.sech .st .take { color:var(--green); font-weight:600; text-decoration:none; }
.parties { display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:24px; }
.fields { display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:10px 12px;
          font-size:12px; }
.fields.c4 { grid-template-columns:repeat(4, minmax(0,1fr)); }
.fields.c5 { grid-template-columns:repeat(5, minmax(0,1fr)); }
.f { display:grid; gap:3px; color:var(--mut); min-width:0; align-content:start; }
.f.full { grid-column:1 / -1; }
.f.s2 { grid-column:span 2; }
.f input, .f select { width:100%; font-size:13px; color:var(--ink); }
.f.mono input { font-family:var(--mono); }
.f.num input { text-align:right; font-family:var(--mono); }
.f.err input, .f.err select { border-color:var(--red); }
/* select as well as input: the type of document is a select, and a warning on
   it left the one field the warning is about looking untouched. */
.f.warn input, .f.warn select { border-color:var(--amber); }
.f.key input { border-color:var(--ink); }
.fmsg { color:var(--red); }
.fmsg.ok { color:var(--green); }
.fmsg.warn { color:var(--amber-ink); }
/* two or three inputs under one label: "Ulice a číslo", "PSČ a město", IBAN · účet / banka */
.f .two { display:grid; gap:6px; }
.f .two.n1 { grid-template-columns:minmax(0,1fr) 72px; }
.f .two.n2 { grid-template-columns:80px minmax(0,1fr); }
.f .two.eq { grid-template-columns:repeat(2, minmax(0,1fr)); }
.f .two.cur { grid-template-columns:minmax(0,1fr) 56px; }
.f .two.iban { grid-template-columns:minmax(0,1fr) 120px 60px; }
.okline { display:flex; align-items:center; gap:6px; color:var(--green); font-size:12px;
          margin:0 0 20px; }
.okline.warn { color:var(--amber-ink); }
.fmsg .suggest { color:var(--green); font-weight:600; }
details.more { grid-column:1 / -1; font-size:12px; }
details.more > summary { color:var(--mut); cursor:pointer; list-style:none; }
details.more > summary::before { content:'+ '; }
details.more[open] > summary::before { content:'− '; }
details.more > summary::-webkit-details-marker { display:none; }
details.more .fields { margin-top:10px; }

.lines { display:grid; grid-template-columns:minmax(0,1fr) 48px 88px 110px 56px 20px; gap:6px;
         font-size:12px; align-items:center; }
.lines .lbody, .lines .lrow, .rates .lbody, .rates .lrow { display:contents; }
.lines .lh { color:var(--mut); white-space:nowrap; }
.lines .lh.r, .lines .r { text-align:right; }
.lines input { font-size:12px; padding:6px 8px; width:100%; }
.lines input.r { text-align:right; font-family:var(--mono); }
.lines .rm { color:var(--mut); text-decoration:none; text-align:center; border:0;
             background:none; cursor:pointer; padding:0; }
.lines .add { color:var(--green); font-weight:600; text-decoration:none; grid-column:1 / 4;
              border:0; background:none; cursor:pointer; padding:0; text-align:left; }
.lines .sum { text-align:right; font-weight:600; font-variant-numeric:tabular-nums; }
.lines .sum.red { color:var(--red); }
.lines .sumlbl { grid-column:span 2; color:var(--mut); }
.recap { margin-top:14px; padding-top:12px; border-top:1px solid var(--line-soft); }
.rates { display:grid; grid-template-columns:repeat(3, minmax(0,1fr)) 20px; gap:6px;
         font-size:12px; align-items:center; margin-top:10px; }
.rates input { font-size:12px; width:100%; text-align:right; font-family:var(--mono); }
.rates .lh { color:var(--mut); }
.rates .lh.r { text-align:right; }
.rates .rm { color:var(--mut); border:0; background:none; cursor:pointer; padding:0; text-align:center; }
.recap .fields { margin-top:12px; }
.subnote { margin:10px 0 0; font-size:12px; color:var(--mut); }
.subnote a { color:var(--green); font-weight:600; text-decoration:none; }
.subnote a.mut { color:var(--mut); font-weight:400; }
details.why { margin-top:14px; font-size:12px; color:var(--mut); }
details.why > summary { cursor:pointer; }
details.why ul { margin:6px 0 0; padding-left:18px; }
details.why li.warn { color:var(--amber-ink); }

/* "What we ran into", built as .errbox.amber rather than as the 12px muted line
   details.why used to be. What it lists is why a document is on this screen at
   all, and it was the smallest thing on the page — read as a footnote, and
   skipped. Same frame as the error box above it, one step down in colour, so
   the two read as one pair: what has to be fixed, and what is worth a look.
   Still a <details>: the count in the summary is always there, the list is
   opened by whoever wants it. */
.whybox { border:1px solid var(--amber); border-left-width:3px; background:var(--card);
          padding:10px 14px; margin-bottom:20px; }
.whybox > summary { cursor:pointer; color:var(--amber-ink); font-weight:600; }
.whybox > summary .mut { color:var(--mut); font-weight:400; }
.whybox ul { margin:6px 0 0; padding-left:18px; line-height:1.7; }
/* One bullet, one severity — the box holds both, so neither may be read off the
   frame around them. */
.whybox li.warn { color:var(--amber-ink); }
.whybox li.crit { color:var(--red); }
/* A bullet may be a link to the field it is about. --ink like the links in
   .errbox: a whole list in --green reads as navigation rather than as findings,
   and the severity is still carried by the marker, which keeps the li's colour. */
.whybox a { color:var(--ink); text-decoration:none; }
.whybox a:hover { text-decoration:underline; }
.versions { font-size:12px; color:var(--mut); }
.versions table { border-collapse:collapse; margin-top:6px; }
.versions td { padding:2px 10px 2px 0; }

.savebar { display:flex; align-items:center; gap:14px; padding:12px 24px;
           border-top:1px solid var(--line); background:var(--card); position:sticky;
           bottom:0; z-index:20; grid-column:1 / -1; }
.savebar .why { color:var(--mut); font-size:12px; }
.savebar .nosave { color:var(--mut); font-size:12px; }
.savebar #dismiss-btn { color:var(--red); border:0; background:none; cursor:pointer;
                        padding:0; }

/* ---- batches (Dávky) ------------------------------------------------------- */
.pagehead { display:flex; align-items:baseline; justify-content:space-between; gap:12px;
            padding:14px 0 8px; border-bottom:1px solid var(--ink); }
.pagehead b { font-size:14px; }
.pagehead .n { color:var(--mut); font-weight:400; }
.pagehead .st { font-size:12px; color:var(--mut); }
.pagehead .st a { color:var(--mut); }
.pagehead.later { padding-top:26px; }
/* A heading directly above a table does not need a rule of its own: the table's
   header row already draws one, and two hairlines 40px apart — one --ink, one
   --line — is what made that block read as busy. The heading keeps its spacing
   and gives the rule up to the header below it. */
.pagehead.over-table { border-bottom:0; padding-bottom:2px; }
.legend { display:flex; gap:14px; font-size:11px; color:var(--mut); text-transform:uppercase;
          letter-spacing:.04em; }
.legend .sq { display:inline-block; width:9px; height:9px; vertical-align:-1px; margin-right:4px;
              background:var(--line); }
.sq.green { background:var(--green); } .sq.amber { background:var(--amber); }
.sq.red { background:var(--red); } .sq.grey { background:var(--edge); }
/* Both of these are grids whose rows are `display:contents`, so the row itself
   paints nothing and the separator exists only as a border-bottom on each cell.
   That is why `align-items:center` had to go: it sized every cell to its own
   content and centred it in the track, so a cell holding a button — ~14px taller
   than its text neighbours — carried its border ~7px lower and the hairline
   stepped mid-row. Cells stretch to the full track height now, and the content
   is centred inside each one instead. */
.sources { display:grid; grid-template-columns:120px minmax(0,1fr) auto; }
.sources > div { display:contents; }
.sources > div > span { display:flex; align-items:center; min-width:0;
                        padding:10px 8px 10px 0; border-bottom:1px solid var(--line-soft); }
.sources > div > span:last-child { padding-right:0; justify-content:flex-end; }
.sources .desc { flex-direction:column; align-items:flex-start; justify-content:center; gap:2px; }
.sources .k { color:var(--mut); }
.sources .warn { font-size:12px; color:var(--amber-ink); }
.sources form { margin:0; display:inline; }

/* ten columns do not fit a laptop at every zoom; the table scrolls in its own
   box so the page itself never scrolls sideways */
.runs-scroll { overflow-x:auto; }
.runs { display:grid; min-width:1054px;
        grid-template-columns:152px 132px minmax(90px,1fr) 62px 62px 62px 74px 74px 130px 86px 116px; }
.runs > div { display:contents; }
.runs > div > span { display:flex; align-items:center; min-width:0;
                     padding:11px 8px 11px 0; border-bottom:1px solid var(--line-soft); }
.runs > div > span:last-child { padding-right:0; justify-content:flex-end; }
.runs > div.hd > span { align-items:flex-end; padding:0 8px 9px 0; }
/* after the .hd rule, or it loses to it on equal specificity — which is what
   left the last header label sitting 8px inboard of its own column */
.runs > div.hd > span:last-child { padding-right:0; justify-content:flex-end; }
/* the name is one token — wrapped over two lines it stops reading as a date */
.runs .bname { font-variant-numeric:tabular-nums; white-space:nowrap; }
.runs .src { color:var(--mut); overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
             display:block; }
.runs .src.mono { font-size:12px; }
.runs .prog { padding-right:14px; }
.runs .prog .bar { flex:1 1 auto; min-width:0; }
.runs .n { justify-content:flex-end; text-align:right;
           font-variant-numeric:tabular-nums; font-weight:600; }
.runs .n.zero { color:var(--mut); font-weight:400; }
.runs .n a { text-decoration:none; }
.runs .n a.done { color:var(--green); }
.runs .n a.waiting { color:var(--amber-ink); }
.runs .n a.problems { color:var(--red); }
.runs .go { color:var(--green); font-weight:600; text-decoration:none; }
.runs .go.mut { color:var(--mut); font-weight:400; }
.runs form { margin:0; }
.runs .state { flex-direction:column; align-items:flex-start; justify-content:center;
               gap:2px; font-size:12px; color:var(--mut); }
.runs .state small { overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
                     max-width:100%; font-size:11px; }
.runs .act { justify-content:flex-end; }
/* The track is painted, because the segments no longer have to carry the whole
   meaning by themselves: `grey` (a person set the document aside) has to read as
   filled, and an empty batch as not filled, and before this both were var(--line)
   on no background at all. */
.bar { display:flex; height:10px; gap:2px; background:var(--line-soft); }
.bar.open { background:repeating-linear-gradient(90deg, var(--line) 0 2px, transparent 2px 5px); }
.bar.broken { border:1px solid var(--red); gap:0; }
.bar i { display:block; }
.bar .green { background:var(--green); } .bar .amber { background:var(--amber); }
.bar .red { background:var(--red); } .bar .grey { background:var(--edge); }
.runs .empty { grid-column:1 / -1; padding:30px 0; text-align:center; color:var(--mut); }

/* ---- dialogs & overlays ---------------------------------------------------- */
.modal { position:fixed; inset:0; z-index:70; background:rgba(27,31,35,.18);
         display:flex; align-items:center; justify-content:center; padding:16px; }
.modalbox { width:520px; max-width:100%; background:var(--card); border:1px solid var(--line);
            border-radius:4px; box-shadow:0 12px 32px rgba(0,0,0,.14); margin:0; }
.modalhead { display:flex; justify-content:space-between; align-items:center;
             padding:14px 20px; border-bottom:1px solid var(--line); }
.modalhead b { font-size:14px; }
.modalhead .x { border:0; background:none; color:var(--mut); cursor:pointer; padding:2px;
                display:inline-flex; border-radius:3px; }
.modalbody { padding:20px; }
.modalfoot { display:flex; align-items:center; gap:12px; padding:12px 20px;
             border-top:1px solid var(--line); background:var(--paper); }
.dropzone { display:block; border:1px dashed var(--mut); border-radius:4px; padding:26px;
            text-align:center; color:var(--mut); background:var(--paper); cursor:pointer; }
.dropzone b { color:var(--ink); display:block; margin-bottom:4px; }
.dropzone.dragging { border-color:var(--green); background:var(--green-soft); }
#file-input { position:absolute; width:1px; height:1px; opacity:0; overflow:hidden; }
.files { margin-top:14px; display:grid; gap:6px; }
.files:empty { display:none; }
.files > div { display:flex; justify-content:space-between; gap:12px; padding:8px 10px;
               border:1px solid var(--line-soft); border-radius:3px; }
.files > div > span:first-child { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.files a { color:var(--mut); }
.radios { margin-top:16px; display:grid; gap:8px; }
.radios label { display:flex; gap:8px; align-items:center; }

#askbox { position:fixed; inset:0; background:rgba(27,31,35,.18); display:none;
          align-items:center; justify-content:center; z-index:80; padding:16px; }
#askbox.on { display:flex; }
.askbody { background:var(--card); border:1px solid var(--line); border-radius:4px;
           padding:20px; max-width:420px; width:100%;
           box-shadow:0 12px 32px rgba(0,0,0,.14); }
.askbody h3 { margin:0 0 6px; font-size:14px; }
.askbody p { margin:0 0 16px; line-height:1.5; }
.askacts { display:flex; gap:10px; justify-content:flex-end; }
#ask-yes { background:var(--green); color:#fff; border:1px solid var(--green);
           padding:7px 14px; border-radius:3px; font-weight:600; cursor:pointer; }

#busy { position:fixed; inset:0; background:rgba(250,250,247,.9); display:none;
        align-items:center; justify-content:center; z-index:90; }
#busy.on { display:flex; }
.busybox { background:var(--card); border:1px solid var(--line); border-radius:4px;
           padding:24px 32px; text-align:center; max-width:22rem;
           box-shadow:0 12px 32px rgba(0,0,0,.14); }
.busybox h3 { margin:12px 0 4px; font-size:14px; }
.busybox p { margin:0; color:var(--mut); font-size:12px; }
.busybar { height:6px; border-radius:3px; background:var(--line-soft); overflow:hidden; }
.busybar i { display:block; height:100%; width:35%; background:repeating-linear-gradient(90deg,
    var(--green) 0 2px, transparent 2px 5px, var(--green) 5px 9px, transparent 9px 11px);
    animation:slide 1.4s ease-in-out infinite; }
@keyframes slide { 0%{transform:translateX(-100%);} 100%{transform:translateX(300%);} }

/* ---- admin (Správa) -------------------------------------------------------- */
.settings { max-width:760px; padding-top:8px; }
.srows { display:grid; grid-template-columns:220px 1fr; gap:14px 24px; padding:14px 0;
         align-items:start; }
.srows .k { min-width:0; }
.srows .k .sub { color:var(--mut); font-size:12px; font-weight:400; }
.srows .v { display:flex; align-items:center; gap:12px; flex-wrap:wrap; min-width:0; }
.srows .v.col { flex-direction:column; align-items:stretch; gap:8px; }
.srows .v .note { font-size:12px; color:var(--mut); }
.srows .v .note.amber { color:var(--amber-ink); }
.srows .v .full { flex:1; }
.srows input.short { width:80px; text-align:right; font-family:var(--mono); }
.srows input.mono { font-family:var(--mono); }
.srows label.inl { display:inline-flex; align-items:center; gap:6px; color:var(--mut); font-size:12px; }
.srows .v table.data { margin:0; }
.srows .v form { margin:0; }
.settings .sech .st a { color:var(--mut); }
.settings .sech a.st { text-decoration:none; }
.settings > p.mut, .settings .sec > p.mut { font-size:12px; margin:0 0 8px; }
.settings .fbox { margin:10px 0; }
.settings .rowacts-inline a { color:var(--mut); }
.settings .linkbtn.danger { color:var(--red); }
.settings .buildtag { margin:0; font-size:13px; color:var(--ink); }
.segment { display:flex; gap:2px; background:var(--ground); padding:2px; border-radius:4px;
           width:max-content; }
.segment label { padding:5px 12px; color:var(--mut); border-radius:3px; cursor:pointer; }
.segment label input { position:absolute; opacity:0; width:1px; height:1px; }
.segment label.on { background:var(--card); color:var(--ink); font-weight:600;
                    box-shadow:0 1px 0 var(--line); }
.evidence { display:grid; grid-template-columns:auto 1fr; gap:6px 14px;
            font-variant-numeric:tabular-nums; align-items:baseline; }
.evidence b.big { font-size:20px; text-align:right; }
.evidence b.green { color:var(--green); }
.evidence b.red { color:var(--red); }
.evidence b.mut { color:var(--mut); }
.evidence .foot { grid-column:1 / -1; border-top:1px solid var(--line-soft); padding-top:8px;
                  font-size:12px; color:var(--mut); }
.formactions { display:flex; align-items:center; gap:14px; padding:16px 0 0;
               border-top:1px solid var(--line); margin-top:8px; flex-wrap:wrap; }
.formactions .note { color:var(--mut); font-size:12px; max-width:52ch; }
.formgrid { display:grid; grid-template-columns:repeat(auto-fit, minmax(200px, 1fr));
            gap:10px 12px; align-items:end; }
.formgrid > label { display:grid; gap:3px; font-size:12px; color:var(--mut); min-width:0; }
.formgrid input, .formgrid select { width:100%; color:var(--ink); font-size:13px; }
.formgrid > label.chk { grid-template-columns:auto 1fr; align-items:center; gap:8px;
                        color:var(--ink); align-self:center; }
.formgrid > .full { grid-column:1 / -1; }
table.data { width:100%; border-collapse:collapse; margin-bottom:4px; }
table.data th { text-align:left; padding:9px 8px 11px 0; }
table.data td { padding:9px 8px 9px 0; border-bottom:1px solid var(--line-soft);
                vertical-align:middle; }
table.data td.num, table.data th.num { text-align:right; font-variant-numeric:tabular-nums; }
table.data td.num { font-family:var(--mono); }
table.data .rowacts-inline { display:flex; gap:8px; align-items:center; }
table.data .rowacts-inline form { margin:0; }
.note-amber { color:var(--amber-ink); }

/* ---- pages without a work grid (help, login, processing) ------------------- */
.card { background:var(--card); border:1px solid var(--line); border-radius:4px;
        padding:20px; margin-top:20px; max-width:760px; }
.bare .card { width:360px; max-width:100%; margin:0; text-align:center; }
.bare .card form { display:flex; flex-direction:column; gap:10px; }
.bare .card .btn.primary { margin-top:4px; }
.bare .card .brand { justify-content:center; border:0; padding:0 0 18px; }
.bare .card h2 { font-size:15px; margin:0 0 4px; }
.tips { padding-left:18px; line-height:1.8; }
.settings > p.mut { max-width:640px; }
.flags { border:1px solid var(--red); border-left-width:3px; padding:8px 12px; margin:10px 0;
         color:var(--red); list-style:none; text-align:left; }
.flags li { list-style:none; }
.flow { max-width:640px; margin:14px 0 0; }
.fstep { display:flex; gap:14px; border:1px solid var(--line-soft); border-radius:3px;
         padding:12px 14px; }
.fstep p { margin:4px 0 0; color:var(--mut); }
.fnote { color:var(--green); }
.fnum { flex:0 0 24px; height:24px; border-radius:50%; background:var(--ink); color:#fff;
        display:flex; align-items:center; justify-content:center; font-weight:600; font-size:12px; }
.farrow { text-align:center; color:var(--mut); padding:4px 0; }
.farrow small { color:var(--mut); }

/* Readable by a screen reader, invisible on screen. The status dot in the list
   carried its meaning in a `title` attribute, which a keyboard never surfaces,
   a screen reader reads inconsistently on a bare <i>, and touch does not have
   at all — so for anyone not using a mouse the column was a coloured circle
   with no name. The dot stays exactly as it looks; the label now exists in the
   accessibility tree beside it. */
.vh { position:absolute; width:1px; height:1px; padding:0; margin:-1px;
      overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0; }

/* ---- motion ---------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  .btn, .railnav a, .view, .menu a { transition:background .1s; }
}
@media (prefers-reduced-motion: reduce) {
  .busybar i { animation:none; width:100%; }
}
@media (max-width: 900px) {
  /* one column, and the explicit placements have to go with it or `grid-column:2`
     would invent a second track that nothing else knows about */
  .review { grid-template-columns:1fr; }
  .revmain, .preview { grid-column:1; grid-row:auto; }
  .preview { position:static; height:auto; border-right:0; border-top:1px solid var(--line); }
}

/* ---- message detail (Detail zprávy) --------------------------------------- */
.mailcard { padding:18px 20px 20px; max-width:900px; }
.mailhead { display:grid; grid-template-columns:1fr 1fr; gap:12px 24px; margin:0 0 18px; }
.mailhead > div.wide { grid-column:1/-1; }
.mailhead dt { font-size:12px; color:var(--mut); margin:0 0 2px; }
.mailhead dd { margin:0; }
.mailcard h3 { font-size:13px; color:var(--mut); font-weight:600; margin:18px 0 8px;
               border-top:1px solid var(--line-soft); padding-top:14px; }
/* the sender's own line breaks are how the message reads; wrap rather than
   scroll, because a quoted thread is wide and the page must not be */
.mailbody { margin:0; white-space:pre-wrap; word-break:break-word; font:inherit;
            background:var(--paper); border:1px solid var(--line-soft); padding:12px 14px;
            max-height:420px; overflow:auto; }
.mailsibs { list-style:none; margin:0; padding:0; display:grid; gap:6px; }
.mailsibs li { display:flex; gap:10px; align-items:baseline; }
.mailsibs li span:not(.chip) { color:var(--mut); overflow:hidden; text-overflow:ellipsis;
                               white-space:nowrap; }

/* ---- the full view (Zvětšení) --------------------------------------------- */
/* The form stays where it was and goes soft behind, rather than being replaced:
   the reader has not left the document they were fixing, they have leaned in. */
body.pv-open { overflow:hidden; }
.pvfull { position:fixed; inset:0; z-index:80; display:flex; flex-direction:column;
          background:rgba(27,31,35,.42); backdrop-filter:blur(5px);
          -webkit-backdrop-filter:blur(5px); }
.pvfull-bar { flex:none; display:flex; justify-content:space-between; align-items:center;
              gap:12px; padding:10px 16px; background:var(--card);
              border-bottom:1px solid var(--line); font-size:12px; color:var(--mut); }
.pvfull-bar > span { display:flex; align-items:center; gap:6px; }
.pvfull-scroll { flex:1; min-height:0; overflow:auto; padding:20px; }
/* 100 % is the width of the page inside the view, so a scan opens at the size it
   can be read at; the zoom goes below 1 for the whole-page look. */
/* grab, not zoom-in: in here a click does not resize anything, it moves the page */
.pvfull-scroll img { cursor:grab; display:block; margin:0 auto;
                     width:calc(min(1180px, 88%) * var(--pvf-zoom, 1));
                     max-width:none; height:auto;
                     box-shadow:0 6px 28px rgba(27,31,35,.35); background:#fff; }
@media (prefers-reduced-motion: no-preference) {
  /* not while dragging: an animating width moves the ground under the pointer
     and the page appears to fight back */
  .pvfull-scroll:not(.is-dragging) img { transition:width .12s ease-out; }
}
