/* event-scraper - "the ledger under the lamp".

   Adapted from agent-core's web/static/sdr.css (same author, see README
   "Licence and origin"). The bones came across intact: a light PAPER design
   rather than an inverted dark one, surfaces separated by lifting a white card
   off a tinted page and drawing a hairline round it, near-invisible shadows,
   and a single interactive accent kept off the semantic colour axis so that
   green / amber / red never mean two things at once.

   Three things are this service rather than that one:

   - THE ACCENT IS PETROL BLUE, not iris violet. The funnel is the screen this
     tool exists for, and its six stages need a ramp of their own; a ramp built
     from the accent hue reads as "further down the pipeline is further
     committed" without borrowing a semantic colour to say it. Violet was the
     other service's signature and this one should not wear it.
   - THE FUNNEL RAMP (--stage-1..6) is a real part of the system, not a chart
     afterthought. Each stage gets a rule above its figure in its own step of
     the ramp, and the same step tints that stage's column in the campaign
     table, so the two screens agree without anybody counting columns.
   - VERDICTS OWN GREEN / AMBER / RED, exclusively. match and pass are green,
     unsure is amber, no_match and fail are red, everywhere, and nothing
     decorative is allowed into those three.

   Type carries the hierarchy: a serif display for page titles and for the
   funnel figures (which are the largest thing on the screen by a wide margin),
   a system sans for prose, and a tabular mono for every number in a table.
   Self-contained: no CDN fonts, no scripts. */

:root {
  color-scheme: light;

  /* surface ladder: page -> card -> inset */
  --paper-0: #f4f4f1;   /* page: warm off-white */
  --paper-1: #ffffff;   /* card */
  --paper-2: #ececeb;   /* inset: inputs, pills, recessed rows */

  --line:   #e2e2de;    /* hairline inside a surface */
  --line-2: #9a9a94;    /* control border */

  --ink:   #16181a;     /* type: primary */
  --muted: #4f545a;     /* type: secondary */
  --faint: #676d74;     /* type: tertiary, still AA on paper */

  --accent:      #12566e;   /* petrol: links, focus, primary action */
  --accent-lo:   #0c3f52;   /* pressed */
  --accent-ink:  #ffffff;   /* type ON the accent */
  --accent-soft: #e6f0f4;   /* accent as a surface */
  --accent-line: #a9c9d6;   /* accent as a border */
  --accent-glow: rgba(18, 86, 110, .18);

  /* the funnel ramp: one hue, six steps, pale to committed */
  --stage-1: #cfe0e7;
  --stage-2: #a9c9d6;
  --stage-3: #7fb0c3;
  --stage-4: #4e90aa;
  --stage-5: #2a7291;
  --stage-6: #12566e;

  /* verdicts, and nothing else */
  --ok:        #0f6b47;
  --ok-soft:   #e3f3ec;
  --ok-line:   #97cfb6;
  --warn:      #7a5410;
  --warn-soft: #fbf0d9;
  --warn-line: #e0bf7d;
  --bad:       #ab2c22;
  --bad-soft:  #fceae8;
  --bad-line:  #e9a9a2;

  --shadow-1: 0 1px 2px rgba(22, 24, 26, .06);
  --shadow-2: 0 6px 18px rgba(22, 24, 26, .09);
  --shadow-3: 0 20px 44px rgba(22, 24, 26, .14);

  /* type scale: a real ratio, not one size everywhere */
  --serif: "Iowan Old Style", Georgia, ui-serif, "Times New Roman", serif;
  --sans:  system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --mono:  ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;

  --t-micro: 10.5px;
  --t-small: 12.5px;
  --t-body:  15px;
  --t-lead:  16.5px;
  --t-h2:    1.35rem;
  --t-h1:    clamp(1.9rem, 4.4vw, 2.85rem);
  --t-fig:   clamp(2rem, 3.6vw, 2.9rem);

  --radius:  10px;
  --dur:     .16s;
  --ease:    cubic-bezier(.16, 1, .3, 1);
}

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

body {
  background: var(--paper-0);
  color: var(--ink);
  font: var(--t-body)/1.55 var(--sans);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  /* one wash of light behind the header, in absolute pixels so it does not
     travel with the length of the page */
  background-image: linear-gradient(180deg, var(--paper-1) 0, transparent 200px);
  background-repeat: no-repeat;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }
a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; }

::selection { background: var(--accent-glow); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- header ---------- */

.top {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  padding: .8rem clamp(1rem, 4vw, 2.5rem);
  border-bottom: 1px solid var(--line);
  background: var(--paper-1);
  box-shadow: var(--shadow-1);
}
.top-spacer { flex: 1 1 auto; }

.brand {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  color: var(--ink);
  font-weight: 700;
  letter-spacing: .17em;
  font-size: 13px;
  text-transform: uppercase;
}
.brand:hover { text-decoration: none; }
.brand-sub { font-weight: 400; letter-spacing: .2em; font-size: 9.5px; color: var(--muted); margin-left: .35rem; }

/* brand mark: three stacked bars narrowing downward - the funnel itself,
   drawn from borders rather than an asset */
.brand-mark {
  width: 14px; height: 14px; flex: none;
  background:
    linear-gradient(var(--accent) 0 0) 0 1px / 14px 3px no-repeat,
    linear-gradient(var(--accent) 0 0) 2px 6px / 10px 3px no-repeat,
    linear-gradient(var(--accent) 0 0) 4px 11px / 6px 3px no-repeat;
  opacity: .95;
}

.topnav { display: flex; gap: .3rem; flex-wrap: wrap; }
.topnav-a {
  padding: .35rem .75rem;
  border-radius: 999px;
  color: var(--muted);
  font-size: var(--t-small);
  letter-spacing: .01em;
  transition: color var(--dur) ease, background var(--dur) ease;
}
.topnav-a:hover { color: var(--ink); background: var(--paper-2); text-decoration: none; }
.topnav-on { color: var(--accent-ink); background: var(--accent); font-weight: 600; }
.topnav-on:hover { color: var(--accent-ink); background: var(--accent-lo); }

.lang-row { display: flex; gap: .15rem; }
.lang-a {
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .08em;
  color: var(--faint); padding: .25rem .45rem; border-radius: 5px;
  transition: color var(--dur) ease, background var(--dur) ease;
}
.lang-a:hover { color: var(--ink); background: var(--paper-2); text-decoration: none; }
.lang-a.on { color: var(--accent); background: var(--accent-soft); font-weight: 700; }

.user-chip { display: flex; align-items: center; gap: .5rem; }
.user-name { font-size: var(--t-small); font-weight: 600; }
.user-role {
  font-size: 9px; letter-spacing: .11em; text-transform: uppercase;
  color: var(--faint); border: 1px solid var(--line); border-radius: 999px;
  padding: .1rem .45rem;
}
.user-role-lead { color: var(--accent); border-color: var(--accent-line); }
.logout-form { margin: 0; }
.logout-btn {
  border: 0; background: none; padding: .25rem .2rem; cursor: pointer;
  font: inherit; font-size: var(--t-small); color: var(--faint);
  border-bottom: 1px solid transparent;
  transition: color var(--dur) ease, border-color var(--dur) ease;
}
.logout-btn:hover { color: var(--bad); border-bottom-color: var(--bad); }
.logout-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------- page frame ---------- */

.wrap {
  width: 100%;
  max-width: 76rem;
  margin-inline: auto;
  padding: clamp(1.5rem, 4vw, 2.75rem) clamp(1rem, 4vw, 2.5rem) 3.5rem;
  flex: 1 0 auto;
}

.foot {
  border-top: 1px solid var(--line);
  padding: 1.1rem clamp(1rem, 4vw, 2.5rem);
  color: var(--faint);
  font-size: var(--t-small);
}

.crumb { margin: 0 0 .9rem; font-size: var(--t-small); color: var(--muted); }

.page-head { margin-bottom: 1.75rem; }
.page-head-split {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 1.5rem; flex-wrap: wrap;
}
.head-action { margin: .5rem 0 0; }

.page-h {
  margin: 0 0 .45rem;
  font-family: var(--serif);
  font-weight: 600;
  font-size: var(--t-h1);
  line-height: 1.04;
  letter-spacing: -.018em;
}
.lead {
  color: var(--muted);
  font-size: var(--t-lead);
  margin: 0;
  max-width: 62ch;
  text-wrap: pretty;
}
.lead-src { font-family: var(--mono); font-size: var(--t-small); word-break: break-all; }
.quiet { color: var(--faint); }
.quiet-note { color: var(--muted); font-size: var(--t-small); margin: .4rem 0 0; }

/* ---------- flash strip ---------- */

.flashes { display: grid; gap: .45rem; margin-bottom: 1.5rem; }
.flash {
  margin: 0;
  padding: .7rem .9rem;
  border-radius: 0 var(--radius) var(--radius) 0;
  font-size: var(--t-small);
  line-height: 1.5;
  background: var(--accent-soft);
  border-left: 3px solid var(--accent);
}
.flash-ok    { background: var(--ok-soft);  border-left-color: var(--ok);  color: var(--ink); }
.flash-error { background: var(--bad-soft); border-left-color: var(--bad); color: var(--ink); }

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

.panel {
  background: var(--paper-1);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: var(--shadow-1);
  padding: 1.4rem clamp(1.15rem, 3vw, 1.8rem);
  margin-block: 1.5rem;
}
.panel-quiet { background: transparent; box-shadow: none; border-style: dashed; }
.panel-h {
  margin: 0 0 .3rem;
  font-family: var(--serif);
  font-size: var(--t-h2);
  font-weight: 600;
  letter-spacing: -.008em;
}
.panel-lead { color: var(--muted); font-size: var(--t-small); margin: 0 0 1.15rem; max-width: 70ch; }
.panel-foot { margin: 1.15rem 0 0; font-size: var(--t-small); }

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

.field-label {
  display: block;
  margin: 1rem 0 .35rem;
  font-size: var(--t-micro);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--faint);
  font-weight: 600;
}
.field-hint { display: block; color: var(--faint); font-size: var(--t-small); }

.form-row { display: flex; gap: 1.15rem; flex-wrap: wrap; }
.field-grow { flex: 1 1 15rem; }
.field-narrow { flex: 0 1 10rem; }
.form-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-top: 1.25rem;
}

input[type=text], input[type=email], input[type=password], input[type=url],
input[type=number], input[type=search], select {
  width: 100%;
  background: var(--paper-1);
  color: var(--ink);
  border: 1px solid var(--line-2);
  border-radius: 8px;
  padding: .55rem .75rem;
  font: inherit;
  transition: border-color var(--dur) ease, box-shadow var(--dur) ease;
}
input:hover, select:hover { border-color: var(--accent-line); }
input:focus, select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-glow);
}

.filter-bar {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  margin-top: 1.35rem;
  padding: .7rem .85rem;
  background: var(--paper-2);
  border-radius: var(--radius);
}
.filter-label {
  font-size: var(--t-micro); letter-spacing: .12em; text-transform: uppercase;
  color: var(--faint); font-weight: 600;
}
.filter-bar select { width: auto; min-width: 12rem; background: var(--paper-1); }

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

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line-2);
  background: var(--paper-1);
  color: var(--ink);
  border-radius: 8px;
  padding: .5rem 1rem;
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  white-space: nowrap;
  transition: transform .08s ease, border-color var(--dur) ease,
              background var(--dur) ease, color var(--dur) ease;
}
.btn:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn:disabled { opacity: .42; cursor: not-allowed; transform: none; }
.btn:disabled:hover { border-color: var(--line-2); color: var(--ink); background: var(--paper-1); }

.btn-primary {
  background: var(--accent); border-color: var(--accent);
  color: var(--accent-ink); font-weight: 600;
}
/* on paper a brighter hover washes out; the press goes DARKER */
.btn-primary:hover:not(:disabled) {
  background: var(--accent-lo); border-color: var(--accent-lo); color: var(--accent-ink);
}
.btn-inline { padding: .38rem .8rem; font-size: 13px; }
.btn-accept:hover:not(:disabled) { border-color: var(--ok); color: var(--ok); background: var(--ok-soft); }
.btn-deny { color: var(--muted); }
.btn-deny:hover:not(:disabled) { border-color: var(--bad); color: var(--bad); background: var(--bad-soft); }

.inline-form { display: flex; gap: .4rem; align-items: center; flex-wrap: wrap; }
.inline-form form { margin: 0; }
.actions { margin-top: 1.4rem; }

/* ---------- the funnel ---------- */

/* Six stages on one rule. The figure is the loudest thing on the screen and
   the label sits under it, so the row reads as numbers first and words
   second; the coloured rule above each figure is that stage's step of the
   ramp, which is the same step the campaign table tints its column with. */
.funnel-panel { padding-bottom: 1.1rem; }
.funnel {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 0;
  counter-reset: stage;
}
.funnel-stage {
  position: relative;
  padding: .95rem .8rem 1rem;
  border-left: 1px solid var(--line);
  transition: background var(--dur) ease;
}
.funnel-stage:first-child { border-left: 0; }
.funnel-stage:hover { background: var(--paper-2); }
.funnel-stage::before {
  content: "";
  position: absolute; inset-inline: 0; top: 0; height: 3px;
  border-radius: 2px;
}
.funnel-scraped::before   { background: var(--stage-1); }
.funnel-targeted::before  { background: var(--stage-2); }
.funnel-matched::before   { background: var(--stage-3); }
.funnel-contacts::before  { background: var(--stage-4); }
.funnel-drafted::before   { background: var(--stage-5); }
.funnel-approved::before  { background: var(--stage-6); }

.funnel-n {
  display: block;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: .14em;
  color: var(--faint);
  margin-bottom: .25rem;
}
.funnel-fig {
  display: block;
  font-family: var(--serif);
  font-size: var(--t-fig);
  line-height: 1;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.03em;
  color: var(--ink);
}
.funnel-label {
  display: block;
  margin-top: .45rem;
  font-size: var(--t-small);
  font-weight: 600;
  letter-spacing: .01em;
}
.funnel-sub {
  display: block;
  margin-top: .15rem;
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--faint);
  text-wrap: pretty;
}

@media (max-width: 900px) {
  .funnel { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .funnel-stage:nth-child(3n + 1) { border-left: 0; }
  .funnel-stage:nth-child(n + 4) { border-top: 1px solid var(--line); }
}
@media (max-width: 520px) {
  .funnel { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .funnel-stage:nth-child(3n + 1) { border-left: 1px solid var(--line); }
  .funnel-stage:nth-child(odd) { border-left: 0; }
  .funnel-stage:nth-child(n + 3) { border-top: 1px solid var(--line); }
}

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

.table-scroll { overflow-x: auto; scrollbar-width: thin; }
.data-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.data-table th, .data-table td { padding: .65rem .55rem; text-align: left; vertical-align: top; }
.data-table thead th {
  font-size: var(--t-micro);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--faint);
  font-weight: 600;
  border-bottom: 2px solid var(--line-2);
  white-space: nowrap;
  vertical-align: bottom;
}
.data-table tbody tr {
  border-bottom: 1px solid var(--line);
  transition: background var(--dur) ease;
}
.data-table tbody tr:hover { background: var(--accent-soft); }
.data-table .num {
  text-align: right;
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
}
.num-zero { color: var(--faint); }

.cell-name { font-weight: 600; }
.cell-co { display: block; font-weight: 400; font-size: var(--t-small); color: var(--faint); }
.cell-host, .cell-when { font-family: var(--mono); font-size: var(--t-small); color: var(--muted); }
.cell-subject { max-width: 26rem; color: var(--muted); }
.cell-go { text-align: right; }

/* The stage columns carry the same ramp as the funnel, at a tint that stays
   legible behind the row hover. */
.stage-col { border-left: 1px solid var(--line); }
.stage-col-scraped   { box-shadow: inset 0 2px 0 -1px var(--stage-1); }
.stage-col-targeted  { box-shadow: inset 0 2px 0 -1px var(--stage-2); }
.stage-col-matched   { box-shadow: inset 0 2px 0 -1px var(--stage-3); }
.stage-col-contacts  { box-shadow: inset 0 2px 0 -1px var(--stage-4); }
.stage-col-drafted   { box-shadow: inset 0 2px 0 -1px var(--stage-5); }
.stage-col-approved  { box-shadow: inset 0 2px 0 -1px var(--stage-6); font-weight: 700; }

.queue-table .row-blocked { background: var(--bad-soft); }
.queue-table .row-blocked:hover { background: var(--bad-soft); }

/* ---------- chips: verdicts only ---------- */

.chip {
  display: inline-flex; align-items: center; gap: .3rem;
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: .05em;
  padding: .2rem .5rem;
  border-radius: 999px;
  border: 1px solid var(--line);
  color: var(--muted);
  white-space: nowrap;
}
.chip-quiet  { color: var(--faint); border-style: dashed; }
.chip-match, .chip-pass { border-color: var(--ok-line);   color: var(--ok);   background: var(--ok-soft); }
.chip-unsure            { border-color: var(--warn-line); color: var(--warn); background: var(--warn-soft); }
.chip-no_match, .chip-fail { border-color: var(--bad-line); color: var(--bad); background: var(--bad-soft); }

/* ---------- job list ---------- */

.job-list { list-style: none; margin: .6rem 0 0; padding: 0; display: grid; gap: .3rem; }
.job-row {
  display: flex; gap: .75rem; align-items: baseline; flex-wrap: wrap;
  font-family: var(--mono); font-size: var(--t-small);
  padding: .35rem 0; border-bottom: 1px solid var(--line);
}
.job-row:last-child { border-bottom: 0; }
.job-kind { font-weight: 700; color: var(--ink); }
.job-status { letter-spacing: .06em; text-transform: uppercase; font-size: 10px; }
.job-status-pending    { color: var(--faint); }
.job-status-processing { color: var(--accent); }
.job-status-done       { color: var(--ok); }
.job-status-failed     { color: var(--bad); }
.job-when { margin-left: auto; color: var(--faint); }

/* ---------- empty state ---------- */

.empty {
  border: 1px dashed var(--line-2);
  border-radius: 12px;
  padding: clamp(2rem, 6vw, 3.5rem);
  text-align: center;
  margin-block: 2rem;
}
.empty-title { margin: 0 0 .35rem; font-family: var(--serif); font-size: 1.3rem; }
.empty-sub { margin: 0 auto; color: var(--muted); font-size: 14px; max-width: 46ch; text-wrap: pretty; }

/* ---------- gate: login / setup / error ---------- */

.gate-body {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(1.5rem, 6vw, 4rem) 1rem;
  /* a single soft wash behind the card, so the gate is not the same flat
     ground as a working page */
  background-image: radial-gradient(120% 60% at 50% 0%, var(--accent-soft) 0%, transparent 62%);
}
.gate-wrap { width: 100%; max-width: 26rem; }
.gate-card {
  background: var(--paper-1);
  border: 1px solid var(--line);
  border-top: 3px solid var(--accent);
  border-radius: 14px;
  padding: clamp(1.6rem, 5vw, 2.3rem);
  box-shadow: var(--shadow-3);
}
.gate-brand { margin-bottom: 1.6rem; }
.gate-h {
  margin: 0 0 .35rem;
  font-family: var(--serif); font-weight: 600;
  font-size: clamp(1.65rem, 5vw, 2rem); line-height: 1.05; letter-spacing: -.018em;
}
.gate-lead { color: var(--muted); font-size: var(--t-small); margin: 0 0 .5rem; text-wrap: pretty; }
.gate-error {
  margin: 1rem 0 0;
  padding: .65rem .8rem;
  background: var(--bad-soft);
  border-left: 3px solid var(--bad);
  border-radius: 0 8px 8px 0;
  font-size: var(--t-small);
}
.gate-actions { margin-top: 1.5rem; }
.gate-submit { width: 100%; padding-block: .65rem; }
.gate-lang { margin-top: 1.4rem; justify-content: center; }
.gate-foot { margin: 1.25rem 0 0; text-align: center; color: var(--faint); font-size: var(--t-small); }

/* ---------- motion ---------- */

@media (prefers-reduced-motion: no-preference) {
  .rise { animation: rise .45s var(--ease) both; }
  @keyframes rise {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: translateY(0); }
  }
}
