/*
 * Upstimate Crawler dashboard.
 *
 * Density-first: this is an operator console that gets scanned, not read, so
 * every size below is deliberately tight and a full worklist fits on one
 * screen. Spacing flows from the --gap/--pad/--fs tokens, so the whole UI can
 * be loosened or tightened from one place rather than per-rule.
 */
:root {
  color-scheme: light dark;
  --bg: #f7f8fa;
  --surface: #ffffff;
  --fg: #131722;
  --muted: #626c7a;
  --line: #e2e6ec;
  --accent: #1d6fe0;
  --ok: #15803d;
  --warn: #b45309;
  --err: #b91c1c;

  --radius: 7px;
  --gap: 8px;      /* between blocks */
  --pad: 9px;      /* inside blocks  */
  --cell: 4px 7px; /* table cells    */
  --fs: 12.5px;    /* body           */
  --fs-sm: 11px;   /* secondary      */
  --fs-xs: 10px;   /* labels         */
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #101317;
    --surface: #171b21;
    --fg: #e8ecf2;
    --muted: #98a3b2;
    --line: #262c35;
    --accent: #6aa6ff;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: var(--fs)/1.35 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
}
h1, h2 { margin: 0; font-size: 13px; }
a { color: var(--accent); }

/* ---- chrome -------------------------------------------------------- */

.topbar {
  position: sticky; top: 0; z-index: 5;
  display: flex; align-items: center; justify-content: space-between;
  padding: 5px 12px;
  background: var(--surface); border-bottom: 1px solid var(--line);
}
.brand { font-weight: 650; font-size: 13px; display: flex; align-items: center; gap: 6px; }
.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ok); }
.topbar-right { display: flex; align-items: center; gap: 7px; }

main {
  max-width: 1400px; margin: 0 auto;
  padding: var(--gap) 12px 28px;
  display: grid; gap: var(--gap);
}

/* ---- tiles --------------------------------------------------------- */

.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 6px; }
.tile {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 5px 8px; display: flex; flex-direction: column;
}
.tile-label {
  font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .03em;
  color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tile-value { font-size: 16px; line-height: 1.2; font-variant-numeric: tabular-nums; }
.tile-action .tile-value { color: var(--accent); }

/* ---- panels -------------------------------------------------------- */

.panel {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: var(--pad);
}
.panel-head {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 6px; margin-bottom: 7px;
}
.panel-head h2 { flex: 1 1 auto; }
.panel-actions { display: flex; flex: 0 1 auto; align-items: center; gap: 5px; flex-wrap: wrap; }

/* ---- forms --------------------------------------------------------- */

label { display: block; font-size: var(--fs-xs); color: var(--muted); margin-bottom: 2px; }
input, textarea, select {
  width: 100%; padding: 4px 7px; font: inherit; color: var(--fg);
  background: var(--bg); border: 1px solid var(--line); border-radius: 6px;
}
textarea { resize: vertical; }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 6px; margin-top: 6px; }
.check { display: flex; align-items: center; gap: 6px; }
.check input { width: auto; }
.check label { margin: 0; }
.actions { display: flex; align-items: center; gap: 7px; margin-top: 7px; }
.hidden { display: none; }
.panel-actions select { width: auto; min-width: 130px; }
.panel-actions input[type="search"] { width: auto; min-width: 190px; }

/* ---- buttons ------------------------------------------------------- */

button {
  padding: 4px 9px; font: inherit; font-size: var(--fs-sm); line-height: 1.4;
  border-radius: 6px; cursor: pointer;
  background: var(--surface); color: var(--fg); border: 1px solid var(--line);
}
button:hover:not(:disabled) { border-color: var(--accent); }
button:disabled { opacity: .45; cursor: not-allowed; }
button.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
button.ghost { background: transparent; }
button.small { padding: 2px 7px; font-size: var(--fs-xs); }
button.danger { color: var(--err); }
button.link { flex: 0 0 auto; padding: 0; border: none; background: none; color: var(--accent); font-size: var(--fs-xs); }

.badge {
  font-size: var(--fs-xs); padding: 2px 7px; border: 1px solid var(--line);
  border-radius: 999px; color: var(--muted); white-space: nowrap;
}

/* ---- jobs ---------------------------------------------------------- */

.jobs { display: grid; gap: 5px; }
.job { border: 1px solid var(--line); border-radius: 6px; padding: 4px 7px; }
.job-head { display: flex; align-items: center; justify-content: space-between; gap: 7px; flex-wrap: wrap; }
.job-title { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; min-width: 0; }
.job-meta.inline { gap: 3px 9px; }
.job-buttons { display: flex; gap: 4px; }
.bar {
  height: 3px; border-radius: 999px; background: var(--bg);
  border: 1px solid var(--line); overflow: hidden; margin: 5px 0 4px;
}
.bar-fill { height: 100%; background: var(--accent); transition: width .4s ease; }
.job-meta { display: flex; flex-wrap: wrap; gap: 4px 11px; font-size: var(--fs-sm); color: var(--muted); }
.job-meta b { color: var(--fg); font-variant-numeric: tabular-nums; }
.job-current { margin-top: 4px; font-size: var(--fs-sm); color: var(--muted); word-break: break-word; }
.warnish b { color: var(--warn); }

.status {
  font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .03em; font-weight: 650;
  padding: 1px 6px; border-radius: 999px; border: 1px solid currentColor; margin-right: 6px;
}
.status-running { color: var(--ok); }
.status-paused, .status-queued { color: var(--warn); }
.status-error { color: var(--err); }
.status-done { color: var(--accent); }
.status-stopped { color: var(--muted); }

/* ---- activity log -------------------------------------------------- */

.log { list-style: none; margin: 0; padding: 0; max-height: 160px; overflow-y: auto; font-size: var(--fs-sm); }
.log li { padding: 2px 0; border-bottom: 1px solid var(--line); word-break: break-word; }
.log li:last-child { border-bottom: none; }
.log .time { color: var(--muted); margin-right: 6px; font-variant-numeric: tabular-nums; }
.log li.warn { color: var(--warn); }
.log li.error { color: var(--err); }

/* ---- tables -------------------------------------------------------- */

.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: var(--fs); }
th, td { text-align: left; padding: var(--cell); border-bottom: 1px solid var(--line); vertical-align: middle; }
th {
  font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .03em;
  color: var(--muted); font-weight: 600; white-space: nowrap;
}
th.num, td.num { text-align: right; font-variant-numeric: tabular-nums; }
tbody tr:hover { background: color-mix(in srgb, var(--accent) 5%, transparent); }

.chip {
  display: inline-block; margin: 1px 2px 1px 0; padding: 0 5px;
  font-size: var(--fs-xs); border: 1px solid var(--line); border-radius: 999px; color: var(--muted);
}
.chip-new { border-color: var(--warn); color: var(--warn); font-weight: 650; }
/* Agents can belong to a dozen markets; showing them all made every row tall.
   The inner span does the clipping -- a <td> cannot overflow-hide on its own,
   so without it the chips spilled over the next column. */
td.markets { width: 230px; max-width: 230px; }
td.markets .chips {
  display: block; max-width: 222px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.chip-more { border-style: dashed; cursor: default; }

.pager { display: flex; align-items: center; justify-content: center; gap: 9px; margin-top: 7px; }

/* ---- markets table ------------------------------------------------- */

#markets td:first-child, #markets th:first-child { min-width: 250px; }
#markets .market-name { font-weight: 600; display: flex; align-items: center; gap: 5px; }
#markets .market-url {
  display: block; max-width: 380px; font-size: var(--fs-xs); color: var(--muted); text-decoration: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#markets .market-url:hover { color: var(--accent); text-decoration: underline; }
.stamps { font-size: var(--fs-xs); color: var(--muted); }
td.dl, .wf-actions { white-space: nowrap; }
.wf-actions button { margin-right: 3px; }
.btn-link {
  display: inline-block; padding: 1px 6px; margin-right: 3px; font-size: var(--fs-xs);
  border: 1px solid var(--line); border-radius: 5px; text-decoration: none; color: var(--fg);
}
.btn-link:hover { border-color: var(--accent); color: var(--accent); }
.btn-link.accent { border-color: var(--warn); color: var(--warn); font-weight: 600; }

/* ---- market workflow states ---------------------------------------- *
 * Row background encodes pipeline position, so the table reads as a
 * worklist: bright = needs you, grey = handled.                         */

.wf td { transition: background-color .2s ease, opacity .2s ease; }

/* NEW / UPDATED — needs attention. */
.wf-new td, .wf-updated td { background: color-mix(in srgb, var(--accent) 9%, transparent); }
.wf-new .market-name, .wf-updated .market-name { font-weight: 700; }
.wf-updated td { box-shadow: inset 2px 0 0 var(--warn); }

/* CRAWLING — in progress. QUEUED — accepted, quieter. */
.wf-crawling td { background: color-mix(in srgb, var(--ok) 13%, transparent); }
.wf-queued td { background: color-mix(in srgb, var(--ok) 5%, transparent); }

/* DOWNLOADED — handled. IMPORT DONE — finished. */
.wf-downloaded td { background: color-mix(in srgb, var(--muted) 9%, transparent); opacity: .62; }
.wf-imported td { background: color-mix(in srgb, var(--muted) 12%, transparent); opacity: .5; }
.wf-imported .market-name, .wf-imported .market-url { text-decoration: line-through; }
.wf-downloaded:hover td, .wf-imported:hover td { opacity: .95; }

.wf-badge {
  display: inline-block; padding: 1px 6px; border-radius: 999px;
  font-size: var(--fs-xs); font-weight: 650; letter-spacing: .02em; text-transform: uppercase;
  border: 1px solid currentColor; white-space: nowrap;
}
.wf-badge-new { color: var(--accent); }
.wf-badge-updated { color: var(--warn); }
.wf-badge-crawling { color: var(--ok); }
.wf-badge-queued, .wf-badge-downloaded, .wf-badge-imported { color: var(--muted); }

.legend { display: inline-flex; align-items: center; gap: 4px; font-size: var(--fs-xs); color: var(--muted); margin-right: 4px; }
.key { width: 9px; height: 9px; border-radius: 2px; border: 1px solid var(--line); display: inline-block; }
.key-new { background: color-mix(in srgb, var(--accent) 30%, transparent); }
.key-crawling { background: color-mix(in srgb, var(--ok) 35%, transparent); }
.key-downloaded { background: color-mix(in srgb, var(--muted) 25%, transparent); }
.key-imported { background: color-mix(in srgb, var(--muted) 40%, transparent); }

/* ---- agents modal -------------------------------------------------- */

#agents-modal {
  width: min(1100px, 94vw);
  max-height: 88vh;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--fg);
  overflow: hidden;
}
#agents-modal::backdrop { background: rgb(0 0 0 / .5); }

.modal-head {
  position: sticky; top: 0; z-index: 1;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px;
  padding: var(--pad);
  background: var(--surface); border-bottom: 1px solid var(--line);
}
/* The table scrolls, the header and pager stay put. */
.modal-body { max-height: calc(88vh - 90px); overflow: auto; padding: 0 var(--pad); }
.modal-body thead th { position: sticky; top: 0; background: var(--surface); z-index: 1; }
#agents-modal .pager { padding: 6px var(--pad); border-top: 1px solid var(--line); margin: 0; }
#modal-close { font-size: 13px; line-height: 1; padding: 3px 7px; }

/* ---- misc ---------------------------------------------------------- */

.muted { color: var(--muted); }
.small { font-size: var(--fs-sm); }

/* login */
.login-wrap { min-height: 100dvh; display: grid; place-items: center; padding: 16px; }
.login-card {
  width: 100%; max-width: 300px; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius); padding: 16px;
}
.login-card h1 { margin-bottom: 12px; }
.login-card .field { margin-bottom: 8px; }
.login-card button { width: 100%; margin-top: 3px; }
.error { color: var(--err); font-size: var(--fs-sm); min-height: 15px; margin-top: 6px; }
