/* Palette taken from the waterfall renderer itself: #0d0d1a ground,
   #ccccdd text, #33334a rules. */
:root {
  --ground:#f6f6fa; --surface:#fff; --alt:#eeeef4;
  --ink:#14141f; --soft:#4c4c60; --faint:#74748c;
  --rule:#dcdce6; --accent:#3e46a0; --accent-ink:#fff;
  --ok:#1c6b39; --ok-bg:#e2f0e7; --run:#8f5000; --run-bg:#f8eddb;
  --bad:#98202c; --bad-bg:#f8e5e7;
}
@media (prefers-color-scheme: dark) {
  :root {
    --ground:#0d0d1a; --surface:#15151f; --alt:#1c1c2a;
    --ink:#d6d6e4; --soft:#a3a3ba; --faint:#7d7d96;
    --rule:#33334a; --accent:#9aa0f0; --accent-ink:#0d0d1a;
    --ok:#5fc281; --ok-bg:#16281d; --run:#e0a44a; --run-bg:#2b2113;
    --bad:#ef8d97; --bad-bg:#2e181b;
  }
}
*{box-sizing:border-box}
body{margin:0;background:var(--ground);color:var(--ink);
  font:15px/1.6 ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif}
main{max-width:940px;margin:0 auto;padding:28px 20px 60px}

.top{display:flex;align-items:center;justify-content:space-between;gap:16px;
  max-width:940px;margin:0 auto;padding:18px 20px;border-bottom:1px solid var(--rule)}
.brand{display:flex;align-items:center;gap:11px;color:var(--ink);
  text-decoration:none;font-weight:600}
.brand em{display:block;font-style:normal;font-weight:400;font-size:12.5px;color:var(--faint)}
.mark{width:26px;height:26px;border-radius:5px;flex:none;border:1px solid var(--rule);
  background:repeating-linear-gradient(180deg,var(--accent) 0 2px,transparent 2px 6px)}
.who{display:flex;align-items:center;gap:12px}

.panel{background:var(--surface);border:1px solid var(--rule);border-radius:9px;
  padding:24px 26px;margin-bottom:20px}
.panel.narrow{max-width:420px;margin:56px auto}
.center{text-align:center}
.head-row{display:flex;align-items:center;justify-content:space-between;
  gap:16px;margin-bottom:18px;flex-wrap:wrap}
h1{font-size:23px;margin:0 0 10px;letter-spacing:-.01em}
.head-row h1{margin:0}
p{margin:0 0 14px}
.muted{color:var(--soft)}
.small{font-size:13px}
.right{text-align:right}
a{color:var(--accent)}

button,.button{font:inherit;font-weight:500;cursor:pointer;border-radius:6px;
  padding:9px 16px;border:1px solid transparent;background:var(--accent);
  color:var(--accent-ink);text-decoration:none;display:inline-block}
button:hover,.button:hover{filter:brightness(1.08)}
button:disabled{opacity:.6;cursor:default}
.ghost{background:transparent;color:var(--soft);border-color:var(--rule)}
.button.small{padding:5px 11px;font-size:13px}
.actions{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin-top:18px}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

.stack{display:flex;flex-direction:column;gap:8px}
.stack p{margin:0}
label{font-size:13px;color:var(--soft)}
input[type=email],input[type=password],select{font:inherit;padding:9px 11px;
  border:1px solid var(--rule);border-radius:6px;background:var(--ground);
  color:var(--ink);width:100%}
select{cursor:pointer}

.drop{border:2px dashed var(--rule);border-radius:9px;padding:32px 20px;
  text-align:center;background:var(--ground);margin-top:20px}
.drop.over{border-color:var(--accent);background:var(--alt)}
.drop p{margin:0 0 8px}
.drop p:last-child{margin:0}

.upload,.ready{border:1px solid var(--rule);border-radius:9px;padding:18px;
  background:var(--ground);margin-top:20px}
.ready p:last-child{margin-bottom:0}
.row{display:flex;justify-content:space-between;gap:12px;margin-bottom:8px;
  font-variant-numeric:tabular-nums}
.bar{height:7px;border-radius:4px;background:var(--alt);overflow:hidden}
.bar>div{height:100%;width:0;background:var(--accent);transition:width .3s ease}
.minibar{height:4px;border-radius:3px;background:var(--alt);overflow:hidden;
  margin-top:5px;max-width:120px}
.minibar>div{height:100%;background:var(--run);transition:width .3s ease}
@media (prefers-reduced-motion:reduce){.bar>div,.minibar>div{transition:none}}

.alert{color:var(--bad);background:var(--bad-bg);border-radius:6px;padding:10px 13px}

table.jobs{width:100%;border-collapse:collapse;font-size:14px}
table.jobs th{text-align:left;font-size:11.5px;letter-spacing:.07em;
  text-transform:uppercase;color:var(--faint);font-weight:600;padding:9px 10px;
  border-bottom:1px solid var(--rule)}
table.jobs th.right{text-align:right}
table.jobs td{padding:12px 10px;border-bottom:1px solid var(--rule);
  color:var(--soft);vertical-align:top}
table.jobs td.name{color:var(--ink);font-weight:500}
table.jobs tr.empty td{color:var(--faint);text-align:center;padding:26px}

.pill{display:inline-block;font-size:12px;font-weight:600;padding:2px 9px;
  border-radius:20px;background:var(--alt);color:var(--faint);white-space:nowrap}
.pill.ok{background:var(--ok-bg);color:var(--ok)}
.pill.run{background:var(--run-bg);color:var(--run)}
.pill.bad{background:var(--bad-bg);color:var(--bad)}

.foot{max-width:940px;margin:0 auto;padding:20px;border-top:1px solid var(--rule);
  color:var(--faint);font-size:12.5px}
@media (max-width:560px){
  table.jobs th:nth-child(2),table.jobs td:nth-child(2),
  table.jobs th:nth-child(3),table.jobs td:nth-child(3){display:none}
}

.count{font-size:12px;color:var(--faint);margin-top:5px;
  font-variant-numeric:tabular-nums}
.count b{color:var(--ink);font-weight:600}

/* Result cell: a note above a row of buttons. Loose inline-block buttons
   wrapped raggedly and sat flush against each other. */
.cellstack{display:flex;flex-direction:column;align-items:stretch;gap:8px;
  width:100%}
/* Long messages wrap and clamp instead of forcing the table wider than its
   panel; the full text is on the cell's title attribute. */
.cellstack .note{text-align:right;line-height:1.35;white-space:normal;
  overflow-wrap:anywhere;display:-webkit-box;-webkit-line-clamp:3;
  -webkit-box-orient:vertical;overflow:hidden}
/* Buttons stack in this narrow column, so they share one width and centre
   their labels — ragged buttons of three different widths read as broken. */
.btnrow{display:flex;flex-direction:column;align-items:stretch;gap:6px;width:100%}
.btnrow > *{white-space:nowrap;text-align:center;justify-content:center;
  display:block;width:100%}

/* Filenames truncate in the MIDDLE: the head shrinks with an ellipsis while
   the tail — extension and the part that distinguishes one clip from another —
   always stays visible. CSS alone cannot do this, hence the two spans. */
table.jobs{table-layout:fixed}
table.jobs td.name{padding-right:18px}
.midtrunc{display:flex;min-width:0;max-width:100%}
.midtrunc .head{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.midtrunc .tail{white-space:nowrap;flex:none}
/* A fixed result column keeps the buttons inside the card. Everything else
   shares what is left. */
table.jobs th:last-child,table.jobs td:last-child{width:12.5rem}
table.jobs th:nth-child(2),table.jobs td:nth-child(2){width:7rem}
table.jobs th:nth-child(3),table.jobs td:nth-child(3){width:9rem}
table.jobs th:nth-child(4),table.jobs td:nth-child(4){width:9rem}
table.jobs td{vertical-align:top}
button.small{padding:5px 11px;font-size:13px}

input[type=number]{font:inherit;padding:9px 11px;border:1px solid var(--rule);
  border-radius:6px;background:var(--ground);color:var(--ink);width:100%;
  font-variant-numeric:tabular-nums}
