/* Pulse — dark command center */
:root {
  --bg: #0B0F17;
  --surface: #10151F;
  --surface-2: #161D2B;
  --surface-3: #1D2536;
  --border: #232C3D;
  --border-2: #2E3A52;
  --text: #E8EDF6;
  --text-2: #97A3B8;
  --muted: #5E6B82;
  --accent: #3D7BE8;
  --c-revenue: #3D7BE8;
  --c-spend: #C9782E;
  --c-profit: #2CA476;
  --c-extra: #B75BC0;
  --good: #2CA476;
  --warn: #C99A2E;
  --bad: #D25454;
  --neutral: #5E6B82;
  --radius: 10px;
  font-size: 15px;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
  -webkit-font-smoothing: antialiased;
}
.boot { padding: 4rem; text-align: center; color: var(--text-2); display: flex; flex-direction: column; align-items: center; gap: 14px; }
.boot-logo { border-radius: 50%; filter: drop-shadow(0 0 20px rgba(61,123,232,0.25)); }
button { font: inherit; cursor: pointer; }
input, select, textarea { font: inherit; }
a { color: var(--accent); text-decoration: none; }

/* ---------- layout ---------- */
.shell { display: flex; flex-direction: column; min-height: 100vh; }
.topbar {
  display: flex; align-items: center; gap: 16px;
  padding: 10px 20px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 50;
  flex-wrap: wrap;
}
.logo { display: flex; align-items: center; gap: 8px; margin-right: 8px; }
.logo .mark { width: 28px; height: 28px; border-radius: 50%; flex-shrink: 0; }
.logo .name { font-weight: 700; letter-spacing: 0.06em; font-size: 1.05rem; }
.logo .sub { color: var(--muted); font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; }
/* The nav scrolls within itself rather than making the whole page wider.
   Phones already did this; tablets did not, so adding a twelfth page was enough
   to push every screen between 700 and about 950px into sideways scroll -- and
   a panel that slides under your thumb reads as broken long before anyone
   works out it is only the nav. Below its natural width this simply never
   applies, so nothing changes on a desktop. */
.nav { display: flex; gap: 2px; min-width: 0; overflow-x: auto; flex-wrap: nowrap; scrollbar-width: none; }
.nav::-webkit-scrollbar { display: none; }
.nav a { white-space: nowrap; }
.nav a {
  color: var(--text-2); padding: 7px 13px; border-radius: 8px; font-size: 0.92rem;
  font-weight: 600;
}
.nav a.active { color: var(--text); background: var(--surface-3); }
.nav a:hover { color: var(--text); }
.topbar .spacer { flex: 1; }
.sync-meta { color: var(--muted); font-size: 0.78rem; text-align: right; line-height: 1.3; }

.main { flex: 1; padding: 22px; max-width: 1500px; width: 100%; margin: 0 auto; }

/* ---------- controls ---------- */
.btn {
  background: var(--surface-3); color: var(--text);
  border: 1px solid var(--border-2); border-radius: 8px;
  padding: 7px 14px; font-size: 0.9rem;
}
.btn:hover { border-color: var(--accent); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.btn.primary:hover { filter: brightness(1.1); }
.btn.danger { color: #F2A0A0; border-color: #5A2F2F; }
.btn.small { padding: 4px 10px; font-size: 0.8rem; }
.btn:disabled { opacity: 0.5; cursor: default; }

/* Match ALL text-ish inputs, including ones with no explicit type attribute —
   a bare <input name="x"> must never fall back to the browser's white default. */
input:not([type=checkbox]):not([type=radio]):not([type=file]), select, textarea {
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border-2); border-radius: 8px;
  padding: 7px 10px; font-size: 0.9rem;
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--accent); }
input[type=number] { text-align: right; }
label.field { display: flex; flex-direction: column; gap: 4px; font-size: 0.8rem; color: var(--text-2); }

.range-bar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.range-bar input[type=date] {
  padding: 5px 9px; font-size: 0.8rem; border-radius: 8px; transition: border-color .12s, box-shadow .12s;
}
.range-bar input[type=date].custom-active {
  border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset;
}

/* Segmented control — one visual language for date presets, report views, market filters */
.seg {
  display: inline-flex; background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 999px; padding: 3px; gap: 2px; flex-wrap: wrap;
}
.seg-btn {
  background: none; border: none; color: var(--text-2);
  padding: 6px 14px; border-radius: 999px; font-size: 0.82rem; font-weight: 500;
  cursor: pointer; white-space: nowrap; transition: background .12s, color .12s;
}
.seg-btn:hover:not(.active) { color: var(--text); }
.seg-btn.active {
  background: var(--accent); color: #fff; font-weight: 600;
  box-shadow: 0 1px 6px rgba(61,123,232,0.45);
}
.seg-divider { width: 1px; align-self: stretch; background: var(--border); margin: 0 2px; }

/* ---------- cards & tiles ---------- */
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 18px;
}
.card h2 { font-size: 0.95rem; font-weight: 600; margin-bottom: 12px; color: var(--text); }
.card h2 .hint { color: var(--muted); font-weight: 400; font-size: 0.78rem; margin-left: 8px; }

.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-bottom: 18px; }
.tile {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 14px 16px;
}
.tile .label { color: var(--text-2); font-size: 0.76rem; letter-spacing: 0.05em; text-transform: uppercase; }
.tile .value { font-size: 1.55rem; font-weight: 700; margin-top: 4px; font-variant-numeric: tabular-nums; }
.tile .delta { font-size: 0.78rem; margin-top: 3px; font-variant-numeric: tabular-nums; }
.tile .delta.up { color: var(--good); }
.tile .delta.down { color: var(--bad); }
.tile .delta.flat { color: var(--muted); }
.tile.hero { grid-column: span 2; }
.tile.hero .value { font-size: 2.1rem; }
.value.pos { color: var(--c-profit); }
.value.neg { color: var(--bad); }
/* same red/green outside a .value tile — e.g. a difference cell in a table */
td.pos, .pos { color: var(--c-profit); }
td.neg, .neg { color: var(--bad); }

.grid-2 { display: grid; grid-template-columns: 2fr 1fr; gap: 18px; align-items: start; }
@media (max-width: 1000px) { .grid-2 { grid-template-columns: 1fr; } }
.stack { display: flex; flex-direction: column; gap: 18px; }

/* ---------- tables ---------- */
.tbl-wrap { overflow-x: auto; }
table.data { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
table.data th {
  text-align: right; color: var(--text-2); font-weight: 500; font-size: 0.75rem;
  text-transform: uppercase; letter-spacing: 0.04em;
  padding: 8px 10px; border-bottom: 1px solid var(--border-2); white-space: nowrap;
}
table.data th:first-child, table.data td:first-child { text-align: left; }
table.data td {
  padding: 9px 10px; border-bottom: 1px solid var(--border);
  font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap;
}
table.data tr:last-child td { border-bottom: none; }
table.data tbody tr:hover { background: var(--surface-2); }
table.data tr.clickable { cursor: pointer; }
table.data td.name { max-width: 320px; overflow: hidden; text-overflow: ellipsis; }
/* A name and the chips that say what it is doing. `text-overflow` clips the END
   of a box, so a chip written after a long name is the first thing to disappear
   — losing precisely the part that has to stay readable. Only the name shrinks
   here; everything after it keeps its width whatever the name costs. */
.name-row { display: flex; align-items: center; gap: 6px; min-width: 0; }
.name-row > .nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.name-row > :not(.nm) { flex: none; }
/* Funnel P&L: the name is how the row is identified at a glance, so it is never
   shortened, at any width. The table is already inside a `.tbl-wrap`, so the
   numbers are a sideways scroll away rather than a guess at a trimmed name. */
table.data.full-names td.name { max-width: none; overflow: visible; }
table.data.full-names td.name .nm { overflow: visible; text-overflow: clip; }
table.data tfoot td { border-top: 1px solid var(--border-2); font-weight: 600; border-bottom: none; }
td .sub { color: var(--muted); font-size: 0.75rem; }

.num-pos { color: var(--c-profit); }
.num-neg { color: var(--bad); }

/* ---------- chips / signals ---------- */
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  border-radius: 999px; padding: 2px 10px; font-size: 0.75rem; font-weight: 600;
}
.chip::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.chip.scale { color: #43C98A; background: rgba(44,164,118,0.12); }
.chip.watch { color: #D9B14A; background: rgba(201,154,46,0.12); }
.chip.weak { color: #C98A6A; background: rgba(201,120,46,0.10); }
.chip.kill { color: #E07070; background: rgba(210,84,84,0.13); }
.chip.low-data { color: var(--muted); background: rgba(94,107,130,0.15); }
.chip.status-active { color: #43C98A; background: rgba(44,164,118,0.12); }
.chip.status-paused { color: var(--muted); background: rgba(94,107,130,0.15); }
.chip.status-error, .chip.status-killed { color: #E07070; background: rgba(210,84,84,0.13); }

/* ---------- chart ---------- */
.chart-box { position: relative; }
.chart-box svg { display: block; width: 100%; height: auto; }
.chart-legend { display: flex; gap: 16px; margin-bottom: 8px; flex-wrap: wrap; }
.chart-legend .item { display: flex; align-items: center; gap: 6px; font-size: 0.8rem; color: var(--text-2); }
.chart-legend .swatch { width: 14px; height: 3px; border-radius: 2px; }
.tooltip {
  position: absolute; pointer-events: none; z-index: 20;
  background: var(--surface-3); border: 1px solid var(--border-2);
  border-radius: 8px; padding: 8px 12px; font-size: 0.8rem;
  box-shadow: 0 6px 20px rgba(0,0,0,0.45);
  display: none; min-width: 150px;
}
.tooltip .t-date { color: var(--text-2); margin-bottom: 5px; font-size: 0.75rem; }
.tooltip .t-row { display: flex; justify-content: space-between; gap: 14px; font-variant-numeric: tabular-nums; }
.tooltip .t-row .k { display: flex; align-items: center; gap: 6px; color: var(--text-2); }
.tooltip .t-row .dot { width: 8px; height: 8px; border-radius: 50%; }

/* ---------- breadcrumb ---------- */
.crumbs { display: flex; align-items: center; gap: 6px; margin-bottom: 14px; font-size: 0.88rem; flex-wrap: wrap; }
.crumbs button {
  background: none; border: none; color: var(--accent); padding: 2px 4px; font-size: 0.88rem;
}
.crumbs .sep { color: var(--muted); }
.crumbs .here { color: var(--text); font-weight: 600; }

/* ---------- forms / auth ---------- */
.auth-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center; }
.auth-card { width: 380px; max-width: 92vw; }
.auth-card .logo { justify-content: center; margin-bottom: 18px; }
.auth-card .logo .mark { width: 44px; height: 44px; }
.auth-card form { display: flex; flex-direction: column; gap: 12px; }
.form-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end; }
.error-msg { color: #E07070; font-size: 0.85rem; }
.ok-msg { color: #43C98A; font-size: 0.85rem; }

/* ---------- settings ---------- */
.settings-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; align-items: start; }
@media (max-width: 1100px) { .settings-grid { grid-template-columns: 1fr; } }
.list-row {
  display: flex; align-items: center; gap: 10px; padding: 9px 0;
  border-bottom: 1px solid var(--border); font-size: 0.9rem; flex-wrap: wrap;
}
.list-row:last-child { border-bottom: none; }
.list-row .grow { flex: 1; min-width: 120px; }
.list-row .meta { color: var(--muted); font-size: 0.78rem; }

.funnel-row { flex-direction: column; align-items: stretch; gap: 8px; }
.funnel-row-main { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.funnel-row-main .grow { flex: 1; min-width: 120px; }
.funnel-row-shopify {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding-left: 2px; font-size: 0.85rem;
}
.funnel-row-shopify .funnel-url { flex: 1; min-width: 220px; }
.funnel-row-shopify .funnel-scan:disabled { opacity: 0.45; cursor: not-allowed; }

.variant-list { display: flex; flex-direction: column; gap: 2px; max-height: 340px; overflow-y: auto; }
.variant-row {
  display: flex; align-items: center; gap: 10px; padding: 8px 4px;
  border-bottom: 1px solid var(--border); cursor: pointer;
}
.variant-row:last-child { border-bottom: none; }
.variant-row input[type=checkbox] { width: 16px; height: 16px; accent-color: var(--accent); flex-shrink: 0; }
.variant-row .grow { flex: 1; }

.section-title { font-size: 1.15rem; font-weight: 700; margin: 4px 0 16px; }
.page-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }

.toast {
  position: fixed; bottom: 22px; right: 22px; z-index: 100;
  background: var(--surface-3); border: 1px solid var(--border-2);
  border-radius: 10px; padding: 12px 18px; font-size: 0.9rem;
  box-shadow: 0 8px 30px rgba(0,0,0,0.5);
}
.toast.err { border-color: #5A2F2F; }
/* ---------- operations tree (Market → Setup → Profile → Campaign) ----------
   Three levels, each visually distinct so you can find your place at a glance:
   market = plain heading, setup = raised card, profile = quiet row. Facts are
   grouped and label-prefixed instead of floating as loose grey text. */
.tree-market { padding: 6px 10px 12px; }
.tree-row {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 10px; border-radius: 8px; cursor: pointer; transition: background .12s;
}
.tree-row:hover { background: var(--surface-2); }
.tree-row .caret { color: var(--muted); width: 12px; font-size: 0.75rem; flex-shrink: 0; }
.tree-name { font-weight: 600; }

/* market header */
.tree-row.market { padding: 10px 8px; }
.tree-row.market .tree-name { font-size: 1.05rem; font-weight: 700; letter-spacing: .01em; }
.tree-row.market:hover { background: transparent; }

/* setup = the main unit of work, so give it a card of its own */
.tree-setup {
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 10px; margin: 8px 0; overflow: hidden;
}
.tree-setup > .tree-row.setup { padding: 11px 12px; border-radius: 0; }
.tree-setup > .tree-row.setup:hover { background: var(--surface-3); }
.setup-title { font-weight: 650; font-size: 0.95rem; letter-spacing: .01em; }
.setup-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; background: var(--muted); }
.setup-dot.scale { background: #43C98A; box-shadow: 0 0 6px rgba(67,201,138,.5); }
.setup-dot.watch { background: #E8C24A; }
.setup-dot.kill { background: #E07070; }
.setup-dot.low-data { background: var(--muted); }
.tree-setup > .tree-children { padding: 2px 10px 10px 26px; }
.tree-setup.closed > .tree-row.setup { border-bottom: none; }

/* profile rows sit quietly under their setup */
.tree-profile { border-left: 2px solid var(--border); margin: 2px 0; padding-left: 8px; }
.tree-profile.employee { border-left-color: rgba(44,164,118,0.4); }
.tree-profile.admin { border-left-color: rgba(61,123,232,0.35); }
.tree-profile > .tree-row.profile { padding: 7px 8px; }
.profile-name { font-weight: 550; font-size: 0.9rem; min-width: 92px; }
.profile-kind {
  font-size: 0.62rem; font-weight: 700; letter-spacing: .06em;
  padding: 2px 5px; border-radius: 4px; flex-shrink: 0;
}
.profile-kind.admin { color: #7FB0FF; background: rgba(61,123,232,0.16); }
.profile-kind.employee { color: #43C98A; background: rgba(44,164,118,0.15); }

/* grouped facts — labelled, so "ROAS" reads as an agency not a metric */
.tree-facts { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }
.tree-facts .fact { font-size: 0.78rem; color: var(--text-2); white-space: nowrap; }
/* Rented accounts come with names like "#5882 - Gio Ad Account 3 - Shalev
   [ROAS A] 7496 - PP - RHKA". One of those wraps the whole profile onto a
   second line and pushes its buttons out of the row they belong to, so the
   name is cut and the full one hangs on the title. The part that identifies
   the account is at the front anyway. */
.tree-facts .fact.acct { max-width: 300px; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 900px) { .tree-facts .fact.acct { max-width: 180px; } }
.tree-facts .fact b {
  color: var(--muted); font-weight: 600; font-size: 0.68rem;
  text-transform: uppercase; letter-spacing: .05em; margin-right: 4px;
}
.empty-hint { color: var(--muted); font-size: 0.82rem; padding: 6px 0 4px 10px; }

.setup-note {
  font-size: 0.74rem; color: #E8C24A; background: rgba(201,154,46,0.14);
  padding: 2px 9px; border-radius: 999px; white-space: nowrap;
}
.tree-actions { margin-left: auto; display: flex; gap: 5px; align-items: center; flex-shrink: 0; }
.tree-row .meta { font-size: 0.78rem; color: var(--muted); }
/* keep row actions calm until you're actually on the row */
.btn.ghost { background: transparent; border-color: transparent; color: var(--muted); }
.tree-row:hover .btn.ghost { border-color: var(--border-2); color: var(--text-2); }
.btn.ghost:hover { background: var(--surface-3); color: var(--text); }
.btn.ghost.danger:hover { color: #F2A0A0; border-color: #5A2F2F; }

/* ---------- inline editing ---------- */
.chip-select {
  appearance: none; border: none; border-radius: 999px; cursor: pointer;
  padding: 3px 22px 3px 10px; font-size: 0.75rem; font-weight: 600;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 10px center, right 6px center;
  background-size: 4px 4px, 4px 4px; background-repeat: no-repeat;
}
.chip-select.scale { color: #43C98A; background-color: rgba(44,164,118,0.12); }
.chip-select.watch { color: #D9B14A; background-color: rgba(201,154,46,0.12); }
.chip-select.kill { color: #E07070; background-color: rgba(210,84,84,0.13); }
.chip-select.low-data { color: var(--muted); background-color: rgba(94,107,130,0.15); }
.chip-select option { background: var(--surface-3); color: var(--text); }

.budget-cell { cursor: pointer; border-radius: 6px; padding: 2px 6px; margin: -2px -6px; display: inline-block; }
.budget-cell:hover { background: var(--surface-3); outline: 1px solid var(--border-2); }
.set-budget { font-size: 0.78rem; font-style: italic; }
.budget-edit { display: inline-flex; align-items: center; gap: 6px; }
.budget-input { width: 92px; text-align: right; padding: 4px 8px; }

.page-row { display: flex; gap: 6px; align-items: center; margin-bottom: 6px; }
.page-row .page-input { flex: 1; }

/* ---------- activity log ---------- */
.log-list { display: flex; flex-direction: column; }
.log-row {
  display: flex; align-items: baseline; gap: 12px; padding: 9px 0;
  border-bottom: 1px solid var(--border); font-size: 0.88rem; flex-wrap: wrap;
}
.log-row:last-child { border-bottom: none; }
.log-time { color: var(--muted); font-size: 0.78rem; font-variant-numeric: tabular-nums; min-width: 44px; }
.log-text { flex: 1; min-width: 220px; line-height: 1.45; }
.log-text b { color: var(--text); font-weight: 650; }
.log-area {
  color: var(--muted); font-size: 0.72rem; text-transform: uppercase;
  letter-spacing: .05em; white-space: nowrap;
}
/* A launch row can be opened to show what it was submitted with. Only those
   rows, so the affordance means something: most log lines are a sentence and
   have nothing further behind them. */
.log-row.log-openable { cursor: pointer; margin: 0 -8px; padding-left: 8px; padding-right: 8px; border-radius: 6px; }
.log-row.log-openable:hover { background: var(--surface-2); }
.log-open {
  color: var(--accent, #5b8def); font-size: 0.72rem; white-space: nowrap;
  border: 1px solid var(--border-2); border-radius: 999px; padding: 1px 8px;
}
.log-row.log-openable:hover .log-open { border-color: var(--accent, #5b8def); }

/* ---------- permissions ---------- */
.perm-table th { text-align: center; }
.perm-table th:first-child, .perm-table td:first-child { text-align: left; }
.perm-table td { text-align: center; }
.perm-table input[type=checkbox] { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }
.perm-user-grid { display: flex; flex-direction: column; }
.perm-user-row {
  display: flex; align-items: center; gap: 12px; padding: 8px 0;
  border-bottom: 1px solid var(--border); font-size: 0.86rem;
}
.perm-user-row:last-child { border-bottom: none; }
.perm-user-row .grow { flex: 1; }
.perm-user-row .meta { display: block; color: var(--muted); font-size: 0.74rem; margin-top: 2px; }
.perm-user-row select { width: 160px; }

/* ---------- unsaved-changes bar ---------- */
#save-bar {
  position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%);
  z-index: 150; display: flex; align-items: center; gap: 14px;
  background: var(--surface-3); border: 1px solid var(--accent);
  border-radius: 12px; padding: 12px 16px;
  box-shadow: 0 10px 40px rgba(0,0,0,0.55);
  animation: save-bar-in .16s ease-out;
  max-width: min(680px, calc(100vw - 32px));
}
@keyframes save-bar-in {
  from { opacity: 0; transform: translate(-50%, 10px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}
.save-bar-text { font-size: 0.88rem; min-width: 0; }
.save-bar-text .sub {
  color: var(--text-2); font-size: 0.76rem; margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#save-bar .btn { flex-shrink: 0; }
/* a staged-but-unsaved value reads differently from a saved one */
.sub.staged { color: #E8C24A; }
.chip.kind-admin { color: #7FB0FF; background: rgba(61,123,232,0.15); }
.chip.kind-employee { color: #43C98A; background: rgba(44,164,118,0.14); }

/* FB profile lifecycle — colours mirror the tracking sheet's own coding,
   retuned for the dark surface so they stay legible. */
.chip.st-nothing    { color: #98A3B5; background: rgba(152,163,181,0.14); }
.chip.st-prw1       { color: #E8D48A; background: rgba(232,212,138,0.13); }
.chip.st-prw2       { color: #EDC24A; background: rgba(237,194,74,0.16); }
.chip.st-pgw1       { color: #B79CF5; background: rgba(139,111,232,0.20); }
.chip.st-pgw2       { color: #A585F2; background: rgba(122,92,224,0.26); }
.chip.st-boost      { color: #C9B2F2; background: rgba(180,150,235,0.16); }
.chip.st-ppe        { color: #7FC4FF; background: rgba(110,180,250,0.16); }
.chip.st-active     { color: #43C98A; background: rgba(44,164,118,0.14); }
.chip.st-restricted { color: #F0A16A; background: rgba(224,145,63,0.16); }
.chip.st-banned     { color: #FF8A8A; background: rgba(190,40,40,0.28); }
.campaigns-table { margin-top: 4px; }
.row-actions { white-space: nowrap; display: flex; gap: 4px; justify-content: flex-end; }
.winner-star {
  cursor: pointer; color: var(--border-2); margin-right: 6px; font-size: 0.95rem;
  transition: color .12s, transform .12s; display: inline-block;
}
.winner-star:hover { transform: scale(1.2); color: var(--warn); }
.winner-star.on { color: #E8C24A; text-shadow: 0 0 8px rgba(232,194,74,0.5); }
.due-soon { color: #D9B14A; }

/* ---------- modal ---------- */
.modal-wrap {
  position: fixed; inset: 0; z-index: 200; background: rgba(6,10,16,0.72);
  display: flex; align-items: flex-start; justify-content: center; padding: 5vh 16px; overflow-y: auto;
  backdrop-filter: blur(2px);
}
.modal {
  background: var(--surface); border: 1px solid var(--border-2); border-radius: 12px;
  width: 560px; max-width: 100%; box-shadow: 0 18px 60px rgba(0,0,0,0.6);
}
.modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 18px; border-bottom: 1px solid var(--border);
}
.modal-head h2 { font-size: 1rem; font-weight: 600; }
.modal-x { background: none; border: none; color: var(--text-2); font-size: 1rem; padding: 4px 8px; border-radius: 6px; }
.modal-x:hover { background: var(--surface-3); color: var(--text); }
.modal-body { padding: 16px 18px; display: flex; flex-direction: column; gap: 12px; }
.modal-body input, .modal-body select, .modal-body textarea { width: 100%; }
.modal-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 560px) { .modal-grid { grid-template-columns: 1fr; } }
.modal-foot { display: flex; align-items: center; gap: 10px; padding-top: 6px; border-top: 1px solid var(--border); margin-top: 4px; padding-top: 14px; }
/* A modal that slides in against the right edge instead of centring.
   For reading something ABOUT a row while the row is still on screen: the
   reason an ad is flagged belongs beside the list it was clicked from, not
   over the middle of it. Same modal markup, positioned differently, so it
   keeps the close button, the backdrop click and the Escape key for free. */
.modal-wrap:has(.side-modal) { align-items: stretch; justify-content: flex-end; padding: 0; }
.side-modal {
  width: 420px; border-radius: 0; border-right: none; border-top: none; border-bottom: none;
  display: flex; flex-direction: column; max-height: 100vh; overflow-y: auto;
}
/* Full width on a phone, where 420px of a 375px screen is just "covered". */
@media (max-width: 560px) {
  .modal-wrap:has(.side-modal) { align-items: flex-end; }
  .side-modal { width: 100%; max-height: 85vh; border-radius: 12px 12px 0 0; border: 1px solid var(--border-2); }
}

/* Confirm dialog — replaces the browser's native confirm() so a destructive
   action always names the exact thing it is about to remove. */
.confirm-modal { width: 430px; }
.modal-wrap:has(.confirm-modal) { align-items: center; padding: 16px; }
.confirm-subject {
  background: var(--surface-2); border: 1px solid var(--border-2); border-left: 3px solid var(--accent);
  border-radius: 8px; padding: 10px 12px; font-weight: 600; font-size: .92rem;
  word-break: break-word; line-height: 1.35;
}
.confirm-message { color: var(--text-2); font-size: .85rem; line-height: 1.5; }
.btn.danger-solid {
  background: #7A2B2B; border-color: #9B3A3A; color: #FFE8E8; font-weight: 600;
}
.btn.danger-solid:hover { background: #913333; border-color: #B84545; color: #fff; }

.awaiting-box { border-top: 1px solid var(--border); padding-top: 10px; }
.alert-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 0 22px 14px; padding: 11px 16px;
  background: rgba(210,84,84,0.12); border: 1px solid #7A2B2B; border-left: 4px solid var(--bad);
  border-radius: 8px; color: #F2C4C4; font-size: 0.88rem;
}
.alert-bar .alert-dot {
  width: 9px; height: 9px; border-radius: 50%; background: var(--bad); flex-shrink: 0;
  animation: alert-pulse 1.6s ease-in-out infinite;
}
@keyframes alert-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.25; } }
.alert-bar .alert-fix { color: #F2A0A0; font-size: 0.8rem; }
@media (prefers-reduced-motion: reduce) { .alert-bar .alert-dot { animation: none; } }

input[type=color].market-color {
  width: 30px; height: 26px; padding: 2px; border-radius: 6px; cursor: pointer;
  background: var(--surface-2); border: 1px solid var(--border-2); flex-shrink: 0;
}

.guide-sub {
  margin-top: 5px; padding-left: 10px; border-left: 2px solid var(--border-2);
  color: var(--text-2); font-size: 0.83rem; line-height: 1.55; font-weight: 400;
}

.sys-check { border-bottom: 1px solid var(--border); }
.sys-check:last-child { border-bottom: none; }
.sys-check > summary {
  display: flex; align-items: flex-start; gap: 10px; padding: 10px 0;
  cursor: pointer; list-style: none;
}
.sys-check > summary::-webkit-details-marker { display: none; }
.sys-check > summary:hover b { color: #fff; }
.sys-check.ok   .health-dot { background: var(--good); }
.sys-check.warn .health-dot { background: var(--warn); }
.sys-check.fail .health-dot { background: var(--bad); }
.sys-check.warn > summary b { color: #E0C070; }
.sys-check.fail > summary b { color: #F2A0A0; }
.sys-body { padding: 0 0 12px 19px; }
.sys-why {
  color: var(--text-2); font-size: 0.82rem; line-height: 1.6;
  border-left: 2px solid var(--border-2); padding-left: 10px; margin-bottom: 10px;
}

.health-row { display: flex; align-items: flex-start; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--border); }
.health-row:last-child { border-bottom: none; }
.health-dot { width: 9px; height: 9px; border-radius: 50%; margin-top: 6px; flex-shrink: 0; }
.health-row.ok   .health-dot { background: var(--good); }
.health-row.warn .health-dot { background: var(--warn); }
.health-row.fail .health-dot { background: var(--bad); }
.health-row.warn b { color: #E0C070; }
.health-row.fail b { color: #F2A0A0; }
.health-fix { color: var(--accent); white-space: nowrap; }

.acct-bm { border: 1px solid var(--border); border-radius: 10px; margin-bottom: 10px; overflow: hidden; }
.acct-bm-head {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; background: var(--surface-2); border-bottom: 1px solid var(--border);
}
.acct-market-group { padding: 8px 12px; }
.acct-market-group + .acct-market-group { border-top: 1px dashed var(--border); }
.acct-market-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.acct-row {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 6px 0 6px 10px; border-left: 2px solid var(--border);
}
.acct-row + .acct-row { border-top: 1px solid var(--border); }
.acct-name { flex: 1 1 240px; min-width: 0; font-size: 0.88rem; }
.acct-row select { max-width: 150px; }
.acct-fee { white-space: nowrap; }
.acct-track { display: flex; align-items: center; }

.conn-card {
  border: 1px solid var(--border); border-radius: 10px;
  padding: 12px 14px; margin-bottom: 10px; background: var(--surface-2);
}
.conn-card.is-error { border-color: #7A2B2B; background: rgba(210,84,84,0.06); }
.conn-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.conn-name { font-weight: 600; }
.conn-err { color: #F2A0A0; font-size: 0.8rem; margin-top: 6px; }
.conn-body {
  margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--border);
  display: flex; flex-direction: column; gap: 8px;
}
.conn-field-label {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 0.8rem; color: var(--text-2);
}
.conn-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.add-conn > summary { cursor: pointer; color: var(--accent); font-size: 0.88rem; padding: 6px 0; }

.portal-guide { flex-basis: 100%; margin-top: 6px; font-size: 0.8rem; color: var(--text-2); }
.portal-guide summary { cursor: pointer; color: var(--accent); }
.portal-guide ol { margin: 8px 0 6px 18px; display: flex; flex-direction: column; gap: 4px; }

.portal-token-row {
  flex-basis: 100%; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--border);
}

.day-picker { display: flex; gap: 6px; flex-wrap: wrap; }
.day-chip { position: relative; cursor: pointer; }
.day-chip input { position: absolute; opacity: 0; pointer-events: none; }
.day-chip span {
  display: inline-block; padding: 6px 12px; border-radius: 999px;
  border: 1px solid var(--border-2); color: var(--text-2); font-size: 0.82rem; transition: all .12s;
}
.day-chip input:checked + span { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }

/* ---------- tasks ---------- */
.task-row {
  display: flex; align-items: center; gap: 12px; padding: 12px 0;
  border-bottom: 1px solid var(--border); flex-wrap: wrap;
}
.task-row:last-child { border-bottom: none; }
.task-row.done { opacity: 0.55; }
.task-row.done .task-title { text-decoration: line-through; }
.task-main { flex: 1; min-width: 240px; }
.task-title { font-weight: 600; font-size: 0.92rem; }
.task-body { color: var(--text-2); font-size: 0.83rem; margin-top: 3px; line-height: 1.45; }
.task-meta { display: flex; gap: 12px; margin-top: 5px; flex-wrap: wrap; }
.task-meta .meta { font-size: 0.76rem; color: var(--muted); }

.mono { font-family: Consolas, monospace; font-size: 0.82rem; }
ol.guide { margin: 0 0 10px 18px; font-size: 0.84rem; line-height: 1.6; color: var(--text-2); }
ol.guide li { margin-bottom: 5px; }
ol.guide b { color: var(--text); }
.muted { color: var(--muted); }
.mt { margin-top: 14px; }

/* ---------- phones ----------
   Wide metric tables cannot become readable at 390px by shrinking — 14 columns
   is 14 columns. So the page itself never scrolls sideways; only a table does,
   inside its own box, with the name column pinned so a scrolled row still tells
   you what it is. Everything else stacks. */
@media (max-width: 700px) {
  :root { font-size: 14px; }

  .main { padding: 12px; }
  .topbar { padding: 8px 12px; gap: 10px; }
  .logo .sub { display: none; }            /* "SCALE ROOM" is noise on a phone */
  .topbar .spacer { display: none; }

  /* the nav scrolls on its own line rather than wrapping into a tall block */
  .nav {
    order: 3; width: 100%;
    overflow-x: auto; flex-wrap: nowrap;
    -webkit-overflow-scrolling: touch; scrollbar-width: none;
  }
  .nav::-webkit-scrollbar { display: none; }
  .nav a { white-space: nowrap; padding: 7px 11px; }

  .range-bar { order: 4; width: 100%; gap: 8px; }
  .range-bar .seg { flex-wrap: nowrap; overflow-x: auto; max-width: 100%; scrollbar-width: none; }
  .range-bar .seg::-webkit-scrollbar { display: none; }
  .range-bar input[type=date] { flex: 1 1 130px; min-width: 0; }

  .tiles { grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); gap: 8px; }
  .tile { padding: 10px 12px; }
  .tile .value { font-size: 1.25rem; }
  .tile.hero { grid-column: span 2; }
  .tile.hero .value { font-size: 1.6rem; }

  .card { padding: 13px; }
  .grid-2, .settings-grid { grid-template-columns: 1fr; }

  /* keep the row's identity visible while the metrics scroll under it */
  .tbl-wrap { -webkit-overflow-scrolling: touch; }
  table.data { font-size: 0.8rem; }
  table.data th, table.data td { padding: 7px 8px; }
  table.data th:first-child, table.data td:first-child {
    position: sticky; left: 0; z-index: 1; background: var(--surface);
    box-shadow: 1px 0 0 var(--border);
  }
  table.data tbody tr:hover td:first-child { background: var(--surface-2); }
  table.data td.name { max-width: 160px; }

  /* The full-name tables, on a phone. The first column is pinned here so the
     metrics scroll under it, which means a column that grows with the name
     would pin itself wider than the screen and the numbers would have nowhere
     to appear — scrolling right just drags the name along. So the name still
     shows in full, over as many lines as it needs, instead of running off
     sideways. Nothing is cut and the metrics stay reachable.

     The floor matters as much as the ceiling: `max-width` alone is only a
     ceiling, and the name is the one column here that can shrink, so the
     browser squeezed it to 58px and wrapped a long name over fourteen lines. */
  table.data.full-names td.name { min-width: 150px; max-width: 170px; white-space: normal; }
  table.data.full-names td.name .name-row { flex-wrap: wrap; }
  table.data.full-names td.name .nm { white-space: normal; overflow-wrap: anywhere; }

  /* forms and rows stack instead of forcing a fixed width */
  .form-row { gap: 8px; }
  .form-row > .field, .form-row > label.field { flex: 1 1 100%; min-width: 0; }
  input:not([type=checkbox]):not([type=radio]), select, textarea { max-width: 100%; }
  .list-row { flex-wrap: wrap; gap: 6px; }
  .list-row .grow { min-width: 100%; }

  .modal { width: 100%; }
  .modal-wrap { padding: 8px; align-items: flex-start; }
  .modal-grid { grid-template-columns: 1fr; }

  .conn-row, .acct-row { gap: 6px; }
  .acct-row select { max-width: 100%; flex: 1 1 130px; }
  .acct-name { flex: 1 1 100%; }

  .sys-body { padding-left: 0; }
  .health-fix { white-space: normal; }

  /* long unbreakable tokens (act_1236…, webhook URLs) must not widen the page */
  .mono, .acct-name, .conn-name, td.name, .log-text { overflow-wrap: anywhere; }
}

/* very narrow — drop the second hero column so tiles stay legible */
@media (max-width: 420px) {
  .tiles { grid-template-columns: 1fr 1fr; }
  .tile.hero { grid-column: span 2; }
  .page-head { flex-wrap: wrap; gap: 8px; }
}

/* Today's row in the monthly report — the one you're still adding to, so it
   should be findable without counting down the list. */
tr.row-today > td { background: rgba(201,154,46,0.10); }
tr.row-today > td:first-child { box-shadow: inset 3px 0 0 var(--warn); }
tr.row-today:hover > td { background: rgba(201,154,46,0.16); }

/* A read-only value that sits in a form where an input used to be, so the row
   still lines up with the fields beside it. */
.pseudo-input {
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px;
  padding: 7px 10px; font-size: 0.9rem; color: var(--text); min-height: 36px;
  display: flex; align-items: center;
}

/* A note exists on this profile — small enough to ignore, present enough to
   find. Only rendered when there is something to read. */
.note-btn {
  background: none; border: 1px solid var(--border-2); border-radius: 6px;
  color: var(--text-2); font-size: 0.78rem; line-height: 1;
  padding: 3px 6px; flex-shrink: 0;
}
.note-btn:hover { color: var(--text); border-color: var(--accent); background: var(--surface-3); }
.note-body {
  white-space: pre-wrap; line-height: 1.55; font-size: 0.9rem;
  background: var(--surface-2); border: 1px solid var(--border-2);
  border-left: 3px solid var(--accent); border-radius: 8px; padding: 10px 12px;
}

/* A tracked campaign matched to a synced one opens in Ads Explorer.
   Underline only on hover so the table doesn't turn into a wall of links. */
.explore-link { color: inherit; text-decoration: none; }
.explore-link:hover { color: var(--accent); text-decoration: underline; }
.explore-link-icon { font-size: 0.9rem; opacity: 0; margin-left: 3px; }
.explore-link:hover .explore-link-icon { opacity: 0.9; }

/* The row you arrived at, so it is findable in a long account. Fades out on its
   own — it marks where you landed, it is not a selection you have to dismiss. */
.focus-row > td { animation: focus-fade 4s ease-out forwards; }
.focus-row > td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
@keyframes focus-fade { 0%, 55% { background: rgba(61,123,232,.16); } 100% { background: transparent; } }

/* A supplier cost line that hasn't been invoiced yet. Kept in the reported
   total — a missing cost reads as profit, which is the worse error — but
   marked, so a month is never read as final while part of it is an estimate. */
.sub.prov { color: var(--warn, #C9922E); font-size: .72rem; }

/* A campaign/ad set/ad that no longer exists in the ad account. It is listed
   only because it spent inside the selected dates — its cost is real and must
   stay in the totals — so it is labelled rather than removed. */
.chip.gone { color: var(--muted); background: rgba(94,107,130,0.14); }

/* A long report is read by scrolling, and a P&L column is meaningless once its
   heading has gone past. The header pins under the topbar — see syncStickyHeads
   in app.js for why the wrapper's overflow has to go and why the offset is
   measured rather than fixed. */
.tbl-wrap.sticky-head { overflow: visible; }
.tbl-wrap.sticky-head table.data thead th {
  position: sticky; top: var(--topbar-h, 105px); z-index: 3;
  background: var(--surface-2);
  box-shadow: inset 0 -1px 0 var(--border-2);
}

/* Tile arranging, and only while Arrange is on. A dashboard read many times a
   day should not be one stray drag away from rearranging itself. */
.tiles.arrangeable .tile { cursor: grab; }
.tiles.arrangeable .tile:active { cursor: grabbing; }
.tiles.arrangeable .tile.dragging { opacity: 0.4; outline: 2px dashed var(--accent); }

/* The profile status is a dropdown where it is read, so the same ten colours
   have to exist for a <select> as for a chip — sharing the palette rather than
   restating it would need a rewrite of both; kept side by side and identical. */
.chip-select.st-nothing { color: #98A3B5; background-color: rgba(152,163,181,0.14); }
.chip-select.st-prw1 { color: #E8D48A; background-color: rgba(232,212,138,0.13); }
.chip-select.st-prw2 { color: #EDC24A; background-color: rgba(237,194,74,0.16); }
.chip-select.st-pgw1 { color: #B79CF5; background-color: rgba(139,111,232,0.20); }
.chip-select.st-pgw2 { color: #A585F2; background-color: rgba(122,92,224,0.26); }
.chip-select.st-boost { color: #C9B2F2; background-color: rgba(180,150,235,0.16); }
.chip-select.st-ppe { color: #7FC4FF; background-color: rgba(110,180,250,0.16); }
.chip-select.st-active { color: #43C98A; background-color: rgba(44,164,118,0.14); }
.chip-select.st-restricted { color: #F0A16A; background-color: rgba(224,145,63,0.16); }
.chip-select.st-banned { color: #FF8A8A; background-color: rgba(190,40,40,0.28); }

/* Hold-to-approve: the only buttons in the panel that spend money on Facebook,
   so a click is not enough. The bar fills over the second you hold. */
.hold-lines { display: flex; flex-direction: column; gap: 6px; margin: 10px 0 4px; }
.hold-line { display: flex; align-items: baseline; gap: 10px; padding: 7px 10px;
  background: rgba(94,107,130,0.10); border-radius: 8px; }
.hold-k { flex: 1; color: var(--muted); font-size: .84rem; }
.hold-v { font-weight: 600; font-variant-numeric: tabular-nums; }
.hold-v.up { color: #43C98A; }
.hold-v.down { color: #E07070; }
.hold-btn { position: relative; overflow: hidden; user-select: none; -webkit-user-select: none;
  touch-action: none; min-width: 150px; }
.hold-fill { position: absolute; inset: 0 auto 0 0; width: 0; background: rgba(255,255,255,0.28);
  pointer-events: none; }
.hold-label { position: relative; }

/* Choosing the scale step. Presets for the two sizes actually used, and a free
   field for the day it is neither. */
.pct-row { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.pct-btn { min-width: 58px; }
.pct-custom { flex: 1; min-width: 96px; margin: 0; }
.pct-custom input { width: 100%; }

/* The budget picker has to work on a phone, which is where it will mostly be
   used. Presets stay on one row, the two inputs sit side by side on a desktop
   and stack when there is no room for both. */
.pct-row { display: flex; gap: 6px; align-items: flex-end; flex-wrap: wrap; }
.pct-btn { flex: 1 1 0; min-width: 62px; }
.pct-custom { flex: 1 1 130px; margin: 0; display: flex; flex-direction: column; gap: 4px; }
.pct-cap { color: var(--muted); font-size: .74rem; }
.pct-custom input { width: 100%; box-sizing: border-box; }
.hold-line { min-height: 34px; }
.hold-k, .hold-v { line-height: 1.35; }
.confirm-modal { max-width: 460px; width: calc(100vw - 32px); }
.modal-foot { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

@media (max-width: 520px) {
  .pct-row { gap: 5px; }
  .pct-btn { flex: 1 1 calc(25% - 5px); min-width: 0; padding-left: 4px; padding-right: 4px; }
  .pct-custom { flex: 1 1 100%; }
  .modal-foot .btn { flex: 1 1 auto; }
  .modal-foot > span { display: none; }
  .hold-btn { min-width: 0; }
}

/* A phone number pad has no minus key. The direction is a button so the full
   keyboard never has to be opened on a field that must only hold digits. */
.pct-signed { display: flex; gap: 6px; align-items: stretch; }
.pct-signed .sign-btn { flex: 0 0 40px; font-weight: 700; padding: 0; }
.pct-signed input { flex: 1; min-width: 0; }

/* Facebook rules dialog. Everything on one grid so the labels and controls line
   up in columns instead of each field finding its own height. */
.fbr-form { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.fbr-f { display: flex; flex-direction: column; gap: 4px; margin: 0; min-width: 0; }
.fbr-f > span { color: var(--muted); font-size: .74rem; line-height: 1.2; }
.fbr-f > input, .fbr-f > select { width: 100%; box-sizing: border-box; height: 38px; }
.fbr-wide { grid-column: 1 / -1; }
.fbr-actions { grid-column: 1 / -1; display: flex; justify-content: flex-end; }

.fbr-rule { display: flex; align-items: flex-start; gap: 10px; padding: 10px 0;
  border-bottom: 1px solid rgba(94,107,130,0.18); }
.fbr-rule:last-of-type { border-bottom: 0; }
.fbr-rule-main { flex: 1; min-width: 0; }
.fbr-rule-name { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.fbr-rule-desc { color: var(--muted); font-size: .78rem; line-height: 1.45; margin-top: 3px; }
.fbr-rule-acts { display: flex; gap: 6px; flex: 0 0 auto; }

@media (max-width: 560px) {
  .fbr-form { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fbr-rule { flex-direction: column; gap: 8px; }
  .fbr-rule-acts { width: 100%; }
  .fbr-rule-acts .btn { flex: 1; }
}

/* The one control on Ads Explorer that says whether anything is acting on the
   account by itself. Deliberately louder than everything around it: a panel that
   can move money while nobody is watching should never let you forget it is
   switched on, and a quiet grey chip in a corner is exactly how you forget. */
.auto-pill {
  display: inline-flex; align-items: center; gap: 9px;
  font-size: .92rem; font-weight: 700; letter-spacing: .01em; line-height: 1;
  padding: 9px 16px; border-radius: 999px; border: 1px solid transparent;
  cursor: pointer; white-space: nowrap; transition: filter .15s ease, transform .15s ease;
}
.auto-pill:hover { filter: brightness(1.14); transform: translateY(-1px); }
.auto-pill .auto-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }

/* Acting: it can change a campaign right now. The loudest state there is. */
.auto-pill.acting {
  color: #8CF0BE; background: rgba(44, 164, 118, .20);
  border-color: rgba(67, 201, 138, .60); box-shadow: 0 0 0 3px rgba(44, 164, 118, .10);
}
.auto-pill.acting .auto-dot {
  background: #43C98A; box-shadow: 0 0 10px #43C98A; animation: auto-pulse 2s ease-in-out infinite;
}

/* Watching: working, and unable to change anything. Still unmissable, still
   plainly not the same thing as acting, because one of them spends money. */
.auto-pill.watching {
  color: #F5BE8B; background: rgba(201, 120, 46, .20);
  border-color: rgba(226, 150, 96, .55); box-shadow: 0 0 0 3px rgba(201, 120, 46, .09);
}
.auto-pill.watching .auto-dot {
  background: #E8A05C; box-shadow: 0 0 10px rgba(232, 160, 92, .85);
  animation: auto-pulse 2.4s ease-in-out infinite;
}

/* Nothing is running. Quiet on purpose: this is the state that needs no attention. */
.auto-pill.idle {
  color: var(--text-2); background: rgba(94, 107, 130, .14); border-color: rgba(94, 107, 130, .34);
}
.auto-pill.idle .auto-dot { background: var(--muted); }

@keyframes auto-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }

@media (max-width: 640px) {
  .auto-pill { font-size: .84rem; padding: 8px 13px; }
}

/* ---------- ad launcher ---------- */
.lx-row { cursor: pointer; }

/* The market and setup filters, one per line. `.seg` is inline-flex, so two of
   them left to themselves sit side by side and read as one long strip of
   unrelated buttons rather than as narrowing down twice. */
.lx-filters { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.lx-filters:not(:empty) { margin-bottom: 14px; }

/* The account being launched on. Worth more than a hover colour: it is the
   answer to "whose account is this campaign about to appear on". */
table.data tr.lx-picked td { background: rgba(61,123,232,0.12); }
table.data tr.lx-picked td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
.field-static { display: flex; flex-direction: column; gap: 4px; font-size: 0.8rem; }

/* Every enhancement visible at once. They are read as a set -- "what is Meta
   allowed to change" -- and a column of them scrolling off the card is how one
   gets left ticked by accident. */
.lx-features { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 8px 18px; }
.lx-check-line { display: flex; align-items: center; gap: 8px; font-size: 0.85rem; color: var(--text-2); }
.lx-check-line input { width: auto; margin: 0; }

.lx-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 10px; min-height: 70px; }
.lx-grid.drop { outline: 2px dashed var(--accent); outline-offset: 6px; border-radius: var(--radius); }
.lx-tile {
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface-2); padding: 10px; display: flex; flex-direction: column; gap: 6px;
}
.lx-tile-head { display: flex; align-items: center; gap: 6px; }
.lx-tile-name { flex: 1; font-size: 0.8rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lx-tile-x { background: none; border: none; color: var(--muted); cursor: pointer; font-size: 0.85rem; padding: 0 2px; }
.lx-tile-x:hover { color: var(--bad); }
.lx-tile textarea, .lx-tile input[type=text] { font-size: 0.78rem; }

.lx-bar { height: 8px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.lx-bar-fill { height: 100%; background: var(--accent); transition: width .3s ease; }

/* The checklist answers "may this go ahead", so a failed line has to be
   readable at a glance rather than another grey sentence among the rest. */
.lx-check { font-size: 0.82rem; line-height: 1.5; }
.lx-check.ok { color: var(--good); }
.lx-check.no { color: var(--bad); }

@media (max-width: 640px) {
  .lx-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
  .lx-features { grid-template-columns: 1fr; }
}

/* ---------- ad review ---------- */
/* A card that needs air under it, for the queue sitting above the main table. */
.mb-card { margin-bottom: 14px; }

/* The placeholder itself, because "cat-2.jpg" tells you nothing about whether
   it is the one that cannot possibly be refused. */
.ph-thumb {
  width: 100%; height: 92px; object-fit: cover;
  border-radius: 8px; background: var(--surface-3);
}

/* ---------- country picker ---------- */
.cty-box { display: flex; flex-direction: column; gap: 6px; position: relative; }
.cty-chips { display: flex; flex-wrap: wrap; gap: 6px; min-height: 26px; align-items: center; }
.cty-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--surface-3); border: 1px solid var(--border-2);
  border-radius: 999px; padding: 3px 6px 3px 11px; font-size: 0.8rem;
}
.cty-x { background: none; border: none; color: var(--muted); cursor: pointer; font-size: 0.75rem; padding: 0 2px; }
.cty-x:hover { color: var(--bad); }
.cty-results {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 20;
  max-height: 230px; overflow-y: auto;
  background: var(--surface-2); border: 1px solid var(--border-2);
  border-radius: 8px; padding: 4px; display: flex; flex-direction: column;
  box-shadow: 0 10px 26px rgba(0,0,0,0.45);
}
.cty-hit {
  background: none; border: none; color: var(--text); text-align: left;
  padding: 7px 10px; border-radius: 6px; font-size: 0.85rem; cursor: pointer;
}
.cty-hit:hover { background: var(--surface-3); }

/* A sentence under a field, when the field alone cannot explain itself. */
.cty-note { font-size: 0.78rem; line-height: 1.45; margin-top: 4px; }
.cty-note.warn { color: #D9B14A; }
.cty-note.bad { color: #E07070; }

/* The ? beside an enhancement. The names hide what these actually do to an ad,
   and "Standard enhancements" sounding milder than "Text on the image" is
   exactly backwards. */
.lx-help {
  display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; margin-left: 5px;
  border-radius: 50%; border: 1px solid var(--border-2);
  color: var(--muted); font-size: 0.62rem; font-weight: 700;
  cursor: help; flex-shrink: 0;
}
.lx-help:hover { color: var(--text); border-color: var(--accent); }

/* A status you can press. "Has issues" is a colour, not a reason, and the
   reason is one click away rather than in Ads Manager. */
.rv-status { background: none; border: none; padding: 0; cursor: pointer; }
.rv-status:hover .chip { filter: brightness(1.25); }
