/*
 * How the app looks.
 *
 * In plain English: every colour, size and spacing in the outreach app is decided
 * in this one file. It is the mock-up Ilia approved on 9 Aug 2026, moved across
 * unchanged — the design was signed off, so nothing here was redecided while
 * building.
 *
 * Two parts, in this order:
 *   1. The tokens — the palette, the type scale, and every component.
 *   2. The calm layer — the pass that made the screen quieter: fewer boxes, fewer
 *      borders, and red saved for the two things that actually want Jace's
 *      attention. It comes second because it deliberately overrides part one.
 *
 * In the mock-up the calm layer lived in the page itself and would have been lost
 * on the way across. It is folded in here on purpose.
 */

/*
 * Every colour, font and reusable piece of the outreach app's look, in one file.
 *
 * In plain English: this is the paint box. The three mock-ups all read from it, so they
 * look like the same product rather than three different ones. Every colour and font
 * below was taken from the live riftbiolabs.com stylesheet (see docs/website-design.md) —
 * none of it was guessed at or matched by eye.
 *
 * This file is written to be lifted into src/web/static/css/tokens.css unchanged when the
 * real app gets built. Nothing in here is specific to a mock-up.
 *
 * House rules baked in:
 *   - Archivo Black for the wordmark and page titles. Tight, NEGATIVE tracking.
 *   - JetBrains Mono, all caps, wide tracking for labels, chips and counts.
 *   - Inter, sentence case, for anything you actually read — table rows, bios, DM copy.
 *     Wide-tracked caps never go inside a table row; they're unreadable at length.
 *   - One solid red button per screen. The moment there are two, neither is primary.
 *   - Sharp corners. No gradients, no animation, no second accent colour.
 */

/* ─── Palette ─────────────────────────────────────────────────────────────────
   Straight from the live site's .dark token block. The site has one theme; so
   does this. #F2F2F2 is the primary text, NOT pure white — pure white is
   reserved for text sitting on the red fill. */

:root {
  --bg:            #0A0A0A;   /* the near-black ground                        */
  --card:          #141414;   /* bordered panels, dropdowns, rows             */
  --muted-fill:    #1F1F1F;   /* inactive fills, hover states                 */
  --border:        #292929;   /* every 1px hairline                           */
  --text:          #F2F2F2;   /* headlines and body                           */
  --text-muted:    #ADADAD;   /* sub-copy, secondary numbers                  */
  --on-red:        #FFFFFF;   /* only text on the red fill is pure white      */

  --red:           #E42532;   /* THE brand red. There is only one.            */
  --red-hover:     #D11A26;   /* the solid button's :hover                    */
  --red-soft:      #E4253280; /* softened border, 50%                         */
  --red-glow:      #E4253259; /* drop shadow, 35%                             */
  --red-wash:      #E4253214; /* faint row tint — derived, used sparingly     */

  --destructive:   #DF3A3A;   /* ERRORS ONLY. Never decorative.               */

  /* Type */
  --font-display: "Archivo Black", "Archivo", ui-sans-serif, system-ui, sans-serif;
  --font-sans:    "Inter", ui-sans-serif, system-ui, sans-serif;
  --font-mono:    "JetBrains Mono", ui-monospace, SFMono-Regular, monospace;

  /* The real working range for wide-tracked caps on the site is .15em–.3em.
     The wider the tracking, the smaller the type has to be. */
  --track-label:  .18em;
  --track-wide:   .24em;
  --track-tight: -.015em;   /* headlines only, and negative on purpose */

  /* Layout — PC only. 1440 is the design target, 1280 is the hard floor. */
  --app-width:    1440px;
  --min-width:    1280px;
  --header-h:     56px;
  --mocknav-h:    36px;
}

/* ─── Reset and page ─────────────────────────────────────────────────────── */

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  min-width: var(--min-width);
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* A faint red glow bleeding down from the top edge, as on the site. Static. */
body::before {
  content: "";
  position: fixed;
  inset: 0 0 auto 0;
  height: 320px;
  background: radial-gradient(ellipse 800px 300px at 50% -80px, #E4253214, transparent 70%);
  pointer-events: none;
  z-index: 0;
}

h1, h2, h3, h4 { margin: 0; font-weight: 400; }
p { margin: 0 0 10px; }
a { color: inherit; }
button { font: inherit; color: inherit; cursor: pointer; }
input, select, textarea { font: inherit; color: inherit; }

::selection { background: var(--red); color: var(--on-red); }

/* ─── Typography roles ───────────────────────────────────────────────────── */

/* Page titles and the wordmark. Caps, heavy, tracked tight and negative. */
.display {
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: var(--track-tight);
  line-height: 1.05;
}

.page-title { font-family: var(--font-display); text-transform: uppercase;
              letter-spacing: var(--track-tight); font-size: 22px; }

/* Eyebrows and technical labels — mono, caps, the widest tracking here.
   Red when it marks a section, grey when it's an instruction. */
.eyebrow {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: var(--track-wide);
  color: var(--text-muted);
}
.eyebrow--red { color: var(--red); }

/* Column headers, counts, anything that is a label rather than a sentence. */
.label {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: var(--track-label);
  color: var(--text-muted);
}

/* Numbers that should line up in a column. */
.num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

.muted { color: var(--text-muted); }
.small { font-size: 12px; }
.strong { font-weight: 600; }

/* ─── App shell ──────────────────────────────────────────────────────────── */

.app { position: relative; z-index: 1; }

/* The mock-up navigator. Deliberately styled as a strip of tape across the top
   so nobody mistakes it for part of the product. */
.mocknav {
  display: flex;
  align-items: center;
  gap: 14px;
  height: var(--mocknav-h);
  padding: 0 18px;
  background: repeating-linear-gradient(135deg, #1F1F1F, #1F1F1F 10px, #191919 10px, #191919 20px);
  border-bottom: 1px solid var(--border);
}
.mocknav__tag {
  font-family: var(--font-mono); font-size: 9px; font-weight: 500;
  letter-spacing: var(--track-wide); text-transform: uppercase;
  color: var(--bg); background: var(--text-muted); padding: 2px 7px;
}
.mocknav__links { display: flex; gap: 2px; margin-left: auto; }
.mocknav__link {
  font-family: var(--font-mono); font-size: 10px; font-weight: 500;
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--text-muted); background: none; border: 1px solid transparent;
  padding: 4px 10px;
}
.mocknav__link:hover { color: var(--text); border-color: var(--border); }
.mocknav__link.is-active { color: var(--text); background: var(--bg); border-color: var(--border); }

/* The real header, on every screen of every concept. */
.topbar {
  display: flex;
  align-items: center;
  gap: 18px;
  height: var(--header-h);
  padding: 0 18px;
  background: var(--card);
  border-bottom: 1px solid var(--border);
}
.wordmark {
  font-family: var(--font-display); text-transform: uppercase;
  letter-spacing: var(--track-tight); font-size: 15px; white-space: nowrap;
}
.wordmark .accent { color: var(--red); }
.topbar__spacer { margin-left: auto; }

/* The Needs Response counter. The one status use of brand red. */
.needs-count {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 11px;
  border: 1px solid var(--red-soft);
  background: var(--red-wash);
  font-family: var(--font-mono); font-size: 10px; font-weight: 500;
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--red);
}
.needs-count b { font-size: 13px; font-weight: 500; }

/* The master switch — top level on every screen, never buried in settings. */
.master {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 5px 11px; border: 1px solid var(--border); background: var(--bg);
}
.master__label {
  font-family: var(--font-mono); font-size: 10px; font-weight: 500;
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-muted);
}
/* The word next to it — ON or OFF — so the state is readable and not only a
   position. A switch alone is ambiguous at a glance; the word never is. */
.master__state {
  font-family: var(--font-mono); font-size: 10px; font-weight: 500;
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text);
  min-width: 22px;
}

.switch { width: 34px; height: 18px; border: 1px solid var(--border);
          background: var(--muted-fill); position: relative; flex: none; }
.switch::after { content: ""; position: absolute; top: 2px; left: 2px;
                 width: 12px; height: 12px; background: var(--text-muted); }
.switch.is-on { border-color: var(--red); background: var(--red-wash); }
.switch.is-on::after { left: auto; right: 2px; background: var(--red); }

/* The master switch reads the opposite way round to every other switch here, and
   deliberately so. Everywhere else ON is the unusual state and earns the red.
   Here ON is the app simply working — calm, quiet, nothing to look at — and OFF
   is the state that wants Jace's eye, because a switched-off machine sends
   nothing and sources nobody until somebody turns it back on. Red stays what it
   is everywhere else in this file: attention, not decoration. No second colour
   is introduced. */
.switch--master.is-on { border-color: var(--border); background: var(--muted-fill); }
.switch--master.is-on::after { left: auto; right: 2px; background: var(--text); }
.switch--master.is-off { border-color: var(--red); background: var(--red-wash); }
.switch--master.is-off::after { left: 2px; right: auto; background: var(--red); }
.master:has(.switch--master.is-off) { border-color: var(--red-soft); }
.master:has(.switch--master.is-off) .master__state { color: var(--red); }

/* ─── Banners ────────────────────────────────────────────────────────────── */

.banner {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 11px 16px; border: 1px solid var(--border); background: var(--card);
  font-size: 13px;
}
.banner__dot { width: 7px; height: 7px; margin-top: 6px; flex: none; background: var(--text-muted); }
.banner--breaker { border-color: var(--destructive); background: #DF3A3A12; }
.banner--breaker .banner__dot { background: var(--destructive); }
.banner--human { border-color: var(--red-soft); background: var(--red-wash); }
.banner--human .banner__dot { background: var(--red); }

/* ─── Buttons ────────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 8px 14px;
  background: none; border: 1px solid var(--border);
  font-family: var(--font-mono); font-size: 10px; font-weight: 500;
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--text); white-space: nowrap;
}
.btn:hover { border-color: var(--text-muted); background: var(--muted-fill); }
.btn--solid { background: var(--red); border-color: var(--red); color: var(--on-red); }
.btn--solid:hover { background: var(--red-hover); border-color: var(--red-hover); }
.btn--ghost { border-color: transparent; color: var(--text-muted); }
.btn--ghost:hover { color: var(--text); border-color: var(--border); }
.btn--danger { border-color: #DF3A3A55; color: var(--destructive); }
.btn--danger:hover { border-color: var(--destructive); background: #DF3A3A12; }
.btn--sm { padding: 5px 9px; font-size: 9px; }
.btn--block { width: 100%; }
.btn[disabled] { opacity: .4; cursor: not-allowed; }

/* ─── Status chips ───────────────────────────────────────────────────────────
   One per state in the pipeline. Grey by default — red is reserved for
   "Needs Response!" so that it means one thing and stays loud. */

.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 8px; border: 1px solid var(--border); background: var(--muted-fill);
  font-family: var(--font-mono); font-size: 9px; font-weight: 500;
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--text-muted); white-space: nowrap;
}
.chip::before { content: ""; width: 5px; height: 5px; background: currentColor; flex: none; }
.chip--found        { color: #8A8A8A; }
.chip--shortlisted  { color: var(--text); }
.chip--dm_sent      { color: var(--text); border-color: #3A3A3A; }
.chip--replied      { color: var(--red); border-color: var(--red-soft); background: var(--red-wash); }
.chip--in_conversation { color: var(--text); border-color: var(--text-muted); }
.chip--signed       { color: var(--text); background: #262626; border-color: #444; }
.chip--no_reply     { color: var(--text-muted); border-style: dashed; }
.chip--archived     { color: #7A7A7A; background: transparent; border-style: dotted; }
.chip--needs_human  { color: var(--red); border-color: var(--red-soft); }
.chip--low_eng      { color: var(--text-muted); border-style: dashed; }
.chip--plain::before { display: none; }

/* ─── Cards and panels ───────────────────────────────────────────────────── */

.card { background: var(--card); border: 1px solid var(--border); }
.card__head {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px; border-bottom: 1px solid var(--border);
}
.card__body { padding: 16px; }
.rule { height: 1px; background: var(--border); border: 0; margin: 16px 0; }

/* ─── Filters ────────────────────────────────────────────────────────────── */

.filterbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 16px; border-bottom: 1px solid var(--border); background: var(--card);
}
.seg { display: flex; border: 1px solid var(--border); }
.seg button {
  padding: 5px 11px; background: none; border: 0; border-right: 1px solid var(--border);
  font-family: var(--font-mono); font-size: 10px; font-weight: 500;
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-muted);
}
.seg button:last-child { border-right: 0; }
.seg button.is-active { background: var(--muted-fill); color: var(--text); }
.seg button:hover { color: var(--text); }

.field { display: inline-flex; align-items: center; gap: 8px; }
.input, .select {
  padding: 5px 9px; background: var(--bg); border: 1px solid var(--border);
  color: var(--text); font-size: 13px; min-width: 0;
}
.input:focus, .select:focus { outline: 1px solid var(--red); outline-offset: -1px; }
/* Wide enough that a six-figure follower cap (250000) isn't clipped. */
.input--num { width: 96px; font-family: var(--font-mono); }

/* The Low Engagement toggle. OFF by default, and it REVEALS flagged creators
   rather than hiding them — fit-scoring.md: never a silent delete. */
.toggle { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
.toggle .switch { width: 28px; height: 15px; }
.toggle .switch::after { width: 9px; height: 9px; }

.check {
  width: 14px; height: 14px; flex: none;
  border: 1px solid var(--border); background: var(--bg); position: relative;
}
.check.is-on { border-color: var(--red); background: var(--red); }
.check.is-on::after {
  content: ""; position: absolute; left: 4px; top: 1px; width: 4px; height: 8px;
  border: solid var(--on-red); border-width: 0 1.5px 1.5px 0; transform: rotate(45deg);
}
.check.is-some { border-color: var(--red); }
.check.is-some::after {
  content: ""; position: absolute; left: 2px; top: 5px; width: 8px; height: 2px; background: var(--red);
}

/* ─── Tables ─────────────────────────────────────────────────────────────────
   Column headers are mono caps. Row CONTENT is Inter, sentence case — wide
   tracked caps in a row of 200 creators is unreadable, which is the whole
   reason docs/website-design.md keeps the outreach UI separate from the site. */

.table { width: 100%; border-collapse: collapse; }
.table th {
  text-align: left; padding: 9px 12px;
  border-bottom: 1px solid var(--border); background: var(--card);
  font-family: var(--font-mono); font-size: 10px; font-weight: 500;
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-muted);
  white-space: nowrap;
}
.table td { padding: 11px 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.table tbody tr:hover { background: var(--card); }
.table tbody tr.is-selected { background: var(--muted-fill); }
.table tbody tr.is-needs { box-shadow: inset 3px 0 0 var(--red); }
.table tbody tr.is-archived td { opacity: .55; }
.table .col-check { width: 34px; }
.table .col-num { text-align: right; }

.handle { font-weight: 500; }
.handle__sub { color: var(--text-muted); font-size: 12px; }

/* Platform tag — two letters, mono, no logos. We don't redraw other people's marks. */
.plat {
  display: inline-block; padding: 2px 5px; border: 1px solid var(--border);
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .1em; color: var(--text-muted);
}

/* Engagement cell. "unknown" is a real value and is never shown as 0 or a dash. */
.eng { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.eng__floor { color: var(--text-muted); font-size: 11px; }
.eng--under { color: var(--text); }
.eng--unknown { color: var(--text-muted); font-style: normal; }

/* ─── Bulk action bar ────────────────────────────────────────────────────── */

.bulkbar {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 16px; background: var(--muted-fill); border-bottom: 1px solid var(--border);
}
.bulkbar__count {
  font-family: var(--font-mono); font-size: 10px; font-weight: 500;
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text);
}

.pager { display: flex; align-items: center; gap: 10px; padding: 11px 16px; border-top: 1px solid var(--border); }
.pager__pages { display: flex; gap: 2px; margin-left: auto; }
.pager__pages button {
  min-width: 26px; padding: 3px 6px; background: none; border: 1px solid var(--border);
  font-family: var(--font-mono); font-size: 10px; color: var(--text-muted);
}
.pager__pages button.is-active { background: var(--muted-fill); color: var(--text); }

/* ─── Key / value rows, used all over the detail screens ─────────────────── */

.kv { display: grid; grid-template-columns: 132px 1fr; gap: 7px 14px; align-items: baseline; }
.kv dt {
  font-family: var(--font-mono); font-size: 10px; font-weight: 500;
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-muted);
}
.kv dd { margin: 0; font-size: 13px; }

/* ─── DM thread ──────────────────────────────────────────────────────────── */

.thread { display: flex; flex-direction: column; gap: 10px; }
.msg { max-width: 82%; padding: 10px 13px; border: 1px solid var(--border); background: var(--bg); font-size: 13px; }
.msg--out { align-self: flex-start; }
.msg--in { align-self: flex-end; background: var(--muted-fill); border-color: #3A3A3A; }
.msg__meta {
  display: flex; gap: 10px; margin-bottom: 6px;
  font-family: var(--font-mono); font-size: 9px; letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--text-muted);
}
.msg p { margin: 0 0 8px; white-space: pre-wrap; }
.msg p:last-child { margin: 0; }

/* An unresolved {{placeholder}} is shown as-is. That's what the app really does
   when profile/brand.yaml still has a FILL_IN in it — see docs/open-questions.md. */
.ph { color: var(--red); font-family: var(--font-mono); font-size: 12px; border-bottom: 1px dashed var(--red-soft); }

/* ─── The runs/ screenshot placeholder ───────────────────────────────────────
   A labelled empty frame at the real aspect ratio. Deliberately NOT a drawn
   copy of the Instagram or TikTok message window — an invented rendering of
   someone else's UI sitting inside Jace's tool could be mistaken for proof of
   a send that never happened. The real capture lands here when Playwright runs. */

.shot {
  position: relative; aspect-ratio: 16 / 10; background: var(--bg);
  border: 1px dashed #3A3A3A;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  background-image: repeating-linear-gradient(45deg, #111 0 1px, transparent 1px 11px);
}
.shot__label {
  font-family: var(--font-mono); font-size: 10px; font-weight: 500;
  letter-spacing: var(--track-wide); text-transform: uppercase; color: var(--text-muted);
}
.shot__path { font-family: var(--font-mono); font-size: 11px; color: #6E6E6E; }

/* ─── Sending limits ─────────────────────────────────────────────────────── */

/* The warning block. Permanent, above the inputs, never collapsible. */
.warn { border: 1px solid var(--red-soft); background: var(--red-wash); padding: 15px 17px; }
.warn h3 { font-family: var(--font-display); text-transform: uppercase;
           letter-spacing: var(--track-tight); font-size: 14px; color: var(--red); margin-bottom: 8px; }
.warn p { font-size: 13px; color: var(--text); }
.warn p:last-child { margin-bottom: 0; }

.meter { height: 6px; background: var(--muted-fill); border: 1px solid var(--border); position: relative; }
.meter__fill { position: absolute; inset: 0 auto 0 0; background: var(--text-muted); }
.meter__fill--hot { background: var(--red); }

.readout { display: flex; flex-direction: column; gap: 4px; }
.readout__num { font-family: var(--font-mono); font-size: 20px; }

/* Second-confirmation dialog, shown as a state rather than wired up. */
.modal-scrim { position: absolute; inset: 0; background: #0A0A0ACC; display: flex;
               align-items: center; justify-content: center; padding: 40px; }
.modal { width: 520px; background: var(--card); border: 1px solid var(--destructive); }
.modal__head { padding: 14px 18px; border-bottom: 1px solid var(--border); }
.modal__body { padding: 18px; font-size: 13px; }
.modal__foot { display: flex; gap: 10px; justify-content: flex-end; padding: 14px 18px; border-top: 1px solid var(--border); }

/* ─── Slide-over drawer (concept B) ──────────────────────────────────────── */

.drawer-wrap { position: absolute; inset: 0; display: flex; justify-content: flex-end; pointer-events: none; }
.drawer-scrim { position: absolute; inset: 0; background: #0A0A0A99; }
.drawer {
  position: relative; width: 560px; height: 100%; overflow: auto;
  background: var(--card); border-left: 1px solid var(--border); pointer-events: auto;
}

/* ─── Misc ───────────────────────────────────────────────────────────────── */

.stack   { display: flex; flex-direction: column; }
.row     { display: flex; align-items: center; }
.gap-6   { gap: 6px; }  .gap-10 { gap: 10px; } .gap-16 { gap: 16px; } .gap-24 { gap: 24px; }
.grow    { flex: 1 1 auto; min-width: 0; }
.pad-16  { padding: 16px; }
.pad-24  { padding: 24px; }
.mt-8    { margin-top: 8px; }  .mt-16 { margin-top: 16px; } .mt-24 { margin-top: 24px; }
.center  { align-items: center; }
.between { justify-content: space-between; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.avatar {
  width: 30px; height: 30px; flex: none; background: var(--muted-fill);
  border: 1px solid var(--border); display: flex; align-items: center; justify-content: center;
  font-family: var(--font-mono); font-size: 11px; color: var(--text-muted);
}
.avatar--lg { width: 52px; height: 52px; font-size: 16px; }

.post-thumb {
  aspect-ratio: 1; background: var(--muted-fill); border: 1px solid var(--border);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  font-family: var(--font-mono); font-size: 10px; color: #6E6E6E;
}

.keycap {
  display: inline-block; min-width: 20px; padding: 2px 6px; text-align: center;
  border: 1px solid var(--border); background: var(--muted-fill);
  font-family: var(--font-mono); font-size: 10px; color: var(--text-muted);
}

.screen { display: none; }
.screen.is-active { display: block; }


/* ═════════════════════════════════════════════════════════════════════════════
   PART 2 — THE CALM LAYER
   Overrides of everything above, moved here from the mock-up's own <style> block
   so it survives the port. Nothing below invents a colour: they are all tokens
   from part one, used less often.
   ═════════════════════════════════════════════════════════════════════════════ */

/* ─────────────────────────────────────────────────────────────────────────
   The calm layer. Everything here is an override of _tokens.css, kept in
   this file so the other two concepts are untouched. Nothing below invents
   a colour — they are all existing tokens, used less often.
   ───────────────────────────────────────────────────────────────────────── */

:root {
  --line-soft: #1C1C1C;   /* the inside-a-table hairline: quieter than --border */
  --dim:       #7E7E7E;   /* third-level text, below --text-muted              */
}

.screen { position: relative; }
.gap-4 { gap: 4px; }
.gap-8 { gap: 8px; }

/* ── Breathing room. The old layout was tight everywhere at once. ───────── */
.pad-16 { padding: 22px 24px; }
.gap-16 { gap: 20px; }

/* ── The alarm bar. Same words, no red wash — a red edge is enough. ─────── */
.banner--breaker {
  border: 1px solid var(--border);
  border-left: 3px solid var(--destructive);
  background: var(--card);
}

/* ── Queue filters. Was ten bordered boxes in a row; now it reads as a line
      of words, and only the one you are standing in is filled. ──────────── */
/* Tracking is .13em rather than the .18em label default, and the padding is tight:
   all eleven queues have to sit on one line at the 1280px floor. */
.qrail { display: flex; flex-wrap: wrap; align-items: center; gap: 0; }
.qtab {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 9px; border: 1px solid transparent; background: none;
  font-family: var(--font-mono); font-size: 10px; font-weight: 500;
  letter-spacing: .13em; text-transform: uppercase; color: var(--text-muted);
}
.qtab b { font-family: var(--font-mono); font-size: 11px; font-weight: 500; color: var(--dim); }
.qtab:hover { color: var(--text); background: var(--card); }
.qtab:hover b { color: var(--text); }
.qtab.is-active { background: var(--muted-fill); color: var(--text); box-shadow: inset 2px 0 0 var(--red); }
.qtab.is-active b { color: var(--text); }
.qtab--needs { color: var(--red); }
.qtab--needs b { color: var(--red); }
.qtab--needs.is-active { color: var(--red); }
/* A deliberate line break rather than an accidental one: the seven pipeline queues
   sit on the first row, the three cross-cutting views on the second. This holds at
   1280 as well as 1440, instead of one stray filter wrapping on its own. */
.qrail__break { flex-basis: 100%; height: 4px; }
.qtab--special { color: var(--dim); }
.qtab--special b { color: var(--dim); }

/* ── Filters. One row, inside the card, with the long explanation cut to
      the seven words that carry the meaning. ────────────────────────────── */
.filterbar { padding: 12px 16px; gap: 14px; border-bottom: 1px solid var(--line-soft); }
.filterbar .label { color: var(--dim); }
.seg { border-color: var(--line-soft); }
.seg button { border-right-color: var(--line-soft); }

/* ── The table. Fainter internal rules, more room per row. ──────────────── */
.table th {
  border-bottom: 1px solid var(--border);
  color: var(--dim);
  padding: 11px 14px;
  letter-spacing: .12em;   /* column headers are read constantly — tighter */
}
.table td { padding: 14px 14px; border-bottom: 1px solid var(--line-soft); }
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover { background: #101010; }
.table tbody tr.is-selected { background: var(--muted-fill); }

.handle { font-weight: 500; }
.handle__sub { color: var(--dim); font-size: 12px; }

/* Platform now lives beside the creator's name, so the column is gone. */
.plat-inline {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .08em;
  color: var(--dim); border: 0; padding: 0;
}

/* ── Status. The big one. A dot and ordinary words instead of a chip with a
      border and a fill. Red is left for the two things that want you. ───── */
.st {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--text-muted); white-space: nowrap;
}
.st::before { content: ""; width: 6px; height: 6px; flex: none; background: currentColor; }
.st--found          { color: var(--dim); }
.st--shortlisted    { color: var(--text-muted); }
.st--dm_sent        { color: var(--text-muted); }
.st--replied        { color: var(--red); font-weight: 600; }
.st--in_conversation{ color: var(--text); }
.st--signed         { color: var(--text); }
.st--no_reply       { color: var(--text-muted); }
.st--archived       { color: var(--dim); }

/* Flags sit under the status, quiet, as words rather than boxes. */
.flags { display: flex; flex-direction: column; gap: 3px; margin-top: 5px; }
.flag {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--dim);
}
.flag--human { color: var(--red); }

/* Engagement: the number stays legible, the floor steps back. */
.eng { font-size: 13px; }
.eng__floor { color: var(--dim); font-size: 10px; }

/* ── Row actions. Present on every row, but they only draw themselves when
      you are actually on that row. Twelve rows no longer means 30 boxes. ── */
/* Hidden rather than dimmed, at Ilia's call on 9 Aug 2026. They stay in the page and
   stay keyboard-reachable — :focus-within brings them back for anyone tabbing. */
.rowacts { opacity: 0; }
tr:hover .rowacts, tr:focus-within .rowacts { opacity: 1; }
.rowacts .btn { border-color: var(--line-soft); color: var(--text-muted); }
.rowacts .btn--danger { color: var(--destructive); border-color: #DF3A3A33; }
.rowacts .btn:hover { border-color: var(--text-muted); color: var(--text); background: var(--muted-fill); }
.rowacts .btn--danger:hover { border-color: var(--destructive); color: var(--destructive); }

/* ── Bulk bar. Actions only; the reassurance moved to the table's footer,
      where it is said once instead of every time you select something. ──── */
.bulkbar { background: var(--muted-fill); border-bottom: 1px solid var(--line-soft); padding: 10px 16px; }

.pager { border-top: 1px solid var(--line-soft); }

/* ── Sending limits. The warning keeps the two paragraphs that change what
      you do; the rest folds away. Red edge instead of a red field. ─────── */
.warn {
  border: 1px solid var(--border);
  border-left: 3px solid var(--red);
  background: var(--card);
  padding: 18px 20px;
}
.warn h3 { font-size: 14px; }
.warn p { color: var(--text-muted); }
.warn p strong { color: var(--text); }
.warn details { margin-top: 10px; }
.warn summary {
  cursor: pointer; list-style: none;
  font-family: var(--font-mono); font-size: 10px; font-weight: 500;
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-muted);
}
.warn summary:hover { color: var(--text); }
.warn summary::-webkit-details-marker { display: none; }
.warn summary::before { content: "+ "; }
.warn details[open] summary::before { content: "– "; }
.warn details p { margin-top: 10px; }

.chip--breaker { color: var(--destructive); border-color: #DF3A3A55; background: #DF3A3A12; }
.chip--clear   { color: var(--dim); border-color: var(--line-soft); background: none; }

.readout__num { font-size: 20px; }
.kv { grid-template-columns: 140px 1fr; gap: 9px 14px; }
.kv dt { color: var(--dim); }

/* ── Governor checks. Ten red boxes read as ten alarms. A pass is a small
      grey tick; red is kept for a check that actually failed. ──────────── */
.tick {
  width: 14px; height: 14px; flex: none; position: relative;
  border: 1px solid var(--line-soft); background: var(--bg);
}
.tick::after {
  content: ""; position: absolute; left: 4px; top: 1px; width: 4px; height: 8px;
  border: solid var(--text-muted); border-width: 0 1.5px 1.5px 0; transform: rotate(45deg);
}
.tick--fail { border-color: var(--destructive); }
.tick--fail::after { border-color: var(--destructive); }
.checkrow { color: var(--text-muted); }
.checkrow .strong { color: var(--text); font-weight: 500; }

/* A passed run in the log is ordinary; only a failure earns a chip. */
.verdict-ok {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--dim);
}

.table th[data-sort] { cursor: pointer; user-select: none; }
.table th[data-sort]:hover { color: var(--text); }
.sort-arrow { display: inline-block; width: 9px; color: var(--text); }

.drawer-wrap, .modal-scrim { z-index: 5; }
.drawer { width: 580px; }
.card__head { border-bottom-color: var(--line-soft); }


/* ═════════════════════════════════════════════════════════════════════════════
   PART 3 — THE REAL APP'S SHELL
   The few things a mock-up never needed: moving between screens, signing in, and
   telling Jace that a button did something. Same tokens, no new colours.
   ═════════════════════════════════════════════════════════════════════════════ */

/* Navigation. In the mock-up this was the striped strip at the top, which was a
   mock-up control and has been deleted. These are the real three screens. */
.appnav { display: flex; align-items: center; gap: 2px; }
.appnav__link {
  padding: 7px 10px; text-decoration: none;
  font-family: var(--font-mono); font-size: 10px; font-weight: 500;
  letter-spacing: .13em; text-transform: uppercase; color: var(--text-muted);
}
.appnav__link:hover { color: var(--text); background: var(--muted-fill); }
.appnav__link.is-active { color: var(--text); box-shadow: inset 0 -2px 0 var(--red); }
.appnav__link--quiet { color: var(--dim); }

/* A short line confirming what just happened. Errors stay up longer and take the
   red edge, because they are the ones worth reading. */
.toast {
  position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%); z-index: 40;
  max-width: 560px; padding: 11px 16px;
  background: var(--card); border: 1px solid var(--border); border-left: 3px solid var(--text-muted);
  color: var(--text); font-size: 13px; box-shadow: 0 6px 24px #0009;
}
.toast--bad { border-left-color: var(--destructive); }

/* Recent posts in the drawer. In the mock-up these were six grey squares reading
   "Post 1"; here each one is a real post, showing its own engagement rate and
   linking out to it. A rate that was never worked out shows as a dash. */
.post-thumb { text-decoration: none; gap: 4px; }
a.post-thumb:hover { border-color: var(--text-muted); }
.post-thumb__rate { font-size: 12px; color: var(--text); }
.post-thumb__when { font-size: 9px; color: var(--dim); }

/* A run with no screenshot. Said plainly rather than left as an empty frame —
   a missing capture is a real problem, not a gap in the layout. */
.shot--missing { border-color: #DF3A3A55; }
.shot--missing .shot__label { color: var(--destructive); }

/* Multi-line input, for pasting a list of handles. */
textarea.input { font-family: var(--font-sans); line-height: 1.5; resize: vertical; width: 100%; }

/* ── Sign-in ──────────────────────────────────────────────────────────────── */

.login-body {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  background: var(--bg); padding: 24px;
}
.login-card {
  width: 100%; max-width: 340px; padding: 30px 28px;
  background: var(--card); border: 1px solid var(--border);
}
.login-card h1 {
  font-family: var(--font-display); font-size: 20px; letter-spacing: .01em; margin: 0;
}
.login-sub {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--dim); margin: 6px 0 22px;
}
.login-card label {
  display: block; margin-bottom: 6px;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--text-muted);
}
.login-card input {
  width: 100%; margin-bottom: 16px; padding: 8px 10px;
  background: var(--bg); border: 1px solid var(--border); color: var(--text); font-size: 14px;
}
.login-card input:focus { outline: 1px solid var(--red); outline-offset: -1px; }
.login-card button {
  width: 100%; padding: 9px; cursor: pointer;
  background: var(--text); border: 0; color: var(--bg);
  font-family: var(--font-mono); font-size: 11px; font-weight: 500;
  letter-spacing: var(--track-label); text-transform: uppercase;
}
.login-error {
  margin: 0 0 14px; padding: 9px 11px; font-size: 13px;
  color: var(--destructive); border: 1px solid #DF3A3A55; background: #DF3A3A12;
}
