:root{
  /* Editorial monochrome — white paper, graphite type, a single warm
     accent used with restraint. Elegant like a financial briefing;
     professional without shouting. Every color is quieter than the
     previous palette; nothing carries the visual weight of navy on
     cream. */
  --bg:#ffffff;                        /* pure white page */
  --panel:#ffffff;                     /* cards + rows */
  --panel2:#faf9f6;                    /* barely-off-white — sidebar, subtle bands */
  --panel3:#f2f1ec;                    /* chip backgrounds, code snippets */
  --line:rgba(20,22,28,.08);           /* soft hairline */
  --line-strong:rgba(20,22,28,.16);    /* stronger divider */
  --ink:#141618;                       /* graphite — leads every headline */
  --ink-2:#3d424b;                     /* body strong */
  --muted:#565b64;                     /* labels, meta — lifted from
                                          #6b7280 (~4.9:1 borderline AA)
                                          to ~7:1 AAA in a single token
                                          bump. Sweeps every --muted use
                                          in one shot; individual --muted
                                          → --ink-2 template edits from
                                          iters 298-327 stay as-is (both
                                          are now comfortably AA+). */
  /* Unified brand accent — the "ledger" green used across landing,
     signup, reports shell, and every in-app decorative accent.
     Same #166A54 that landing.html + reports.html reference; putting
     it on --accent means every existing use across styles.css picks
     up the right hue without touching individual selectors. */
  --accent:#166A54;                    /* ledger green — brand accent */
  --accent2:#124a3c;                   /* accent hover / darker ledger */
  --ledger:#166A54;                    /* alias — some inline templates use --ledger directly */
  --ledger-2:rgba(22,106,84,.10);      /* ledger tinted background */
  --ok:#0f7442;                        /* forest — success states */
  --warn:#8a5b1c;                      /* amber */
  --err:#a03027;                       /* earth red */
  --radius:8px;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}

/* Screen-reader-only utility — text is inaudible/invisible to sighted
   users but announced by assistive tech. Used across tables (caption)
   and form hints (aria-describedby). Standard sr-only recipe. */
.visually-hidden{
  position:absolute; width:1px; height:1px;
  padding:0; margin:-1px; overflow:hidden;
  clip:rect(0,0,0,0); white-space:nowrap; border:0;
}
body{
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  background:var(--bg); color:var(--ink); line-height:1.55;
  -webkit-font-smoothing:antialiased;
  font-feature-settings:"tnum" 1, "cv11" 1;
}
a{color:var(--ink); text-decoration:none; border-bottom:1px solid var(--line-strong);}
a:hover{color:var(--ink); border-bottom-color:var(--ink);}
/* Consistent keyboard focus ring across every anchor. Browser defaults
   vary (Chrome shows a blue box, Firefox a dashed line, Safari nothing
   on some element types), so keyboard users saw an inconsistent focus
   indicator depending on their browser. This matches the .btn focus
   ring the rest of the app uses so `Tab` produces the same visible
   halo everywhere. Skip :focus (mouse click also flashes it) — only
   :focus-visible so click users don't see it. */
a:focus-visible{outline:2px solid var(--accent); outline-offset:2px;
                border-radius:2px;}
h1,h2,h3{margin:0 0 .4em; font-weight:550; letter-spacing:-.02em; color:var(--ink);}
h1{font-size:2.25rem; line-height:1.1; letter-spacing:-.03em; font-weight:500;}
h2{font-size:1.35rem; line-height:1.25;}
h3{font-size:1.05rem;}
p{margin:.3em 0}
code,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}

/* ---- app shell ---- */
.shell{display:flex; min-height:100vh}
.sidebar{
  width:236px; background:var(--panel2); border-right:1px solid var(--line);
  display:flex; flex-direction:column; padding:18px 14px; position:sticky;
  top:0; height:100vh;
}
.brand a{font-size:20px; font-weight:750; color:var(--ink); letter-spacing:-.02em}
.brand span{color:var(--accent)}
.tenant-switch{margin:18px 0 8px}
.tenant-switch label{display:block; font-size:11px; text-transform:uppercase;
  letter-spacing:.08em; color:var(--muted); margin-bottom:4px}
.tenant-switch select{width:100%}
.sidebar nav{display:flex; flex-direction:column; gap:2px; margin-top:10px}
.sidebar nav a{
  color:var(--muted); padding:8px 10px; border-radius:8px;
  font-size:14px; font-weight:500;
}
.sidebar nav a:hover{background:rgba(0,0,0,.04); color:var(--ink); text-decoration:none}
.sidebar nav a.active{background:var(--accent); color:#fff}
.nav-sep{font-size:11px; text-transform:uppercase; letter-spacing:.08em;
  color:var(--muted); margin:14px 10px 4px}
.sidebar-user{margin-top:auto; border-top:1px solid var(--line); padding-top:12px}
.sidebar-user .who strong{display:block; font-size:14px}
.sidebar-user .who span{display:block; font-size:12px; color:var(--muted);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.logout-form{margin:0}
button.logout,
.logout{display:inline-block; margin-top:8px; font-size:13px; color:var(--muted);
  background:none; border:0; padding:0; cursor:pointer; font-family:inherit;
  text-align:left}
button.logout:hover{color:var(--ink)}
.content{flex:1; padding:30px 38px; max-width:1400px; margin:0 auto; width:100%;
  display:flex; flex-direction:column;}
.content > .site-foot{margin-top:auto}

/* ---- generic ---- */
.page-head{display:flex; justify-content:space-between; align-items:flex-end;
  margin-bottom:22px; gap:16px; flex-wrap:wrap}
.page-head .sub{color:var(--muted); font-size:.9rem}
.panel{background:var(--panel); border:1px solid var(--line);
  border-radius:var(--radius); padding:20px; margin-bottom:20px}
.panel h2{margin-bottom:14px}
.muted{color:var(--muted)}
.small{font-size:.84rem}
.mono{font-family:ui-monospace,Menlo,Consolas,monospace; font-size:.84rem}

.grid{display:grid; gap:16px}
.grid.cols-2{grid-template-columns:1fr 1fr}
.stats{display:grid; grid-template-columns:repeat(auto-fit,minmax(140px,1fr)); gap:14px}
.stat{background:var(--panel); border:1px solid var(--line); border-radius:var(--radius);
  padding:16px}
.stat .n{font-size:1.8rem; font-weight:700}
.stat .l{color:var(--muted); font-size:.82rem; text-transform:uppercase;
  letter-spacing:.06em}

table{width:100%; border-collapse:collapse; font-size:.9rem}
th,td{text-align:left; padding:9px 10px; border-bottom:1px solid var(--line)}
th{color:var(--muted); font-size:.74rem; text-transform:uppercase;
  letter-spacing:.06em; font-weight:600}
tr:last-child td{border-bottom:none}

.badge{display:inline-block; padding:2px 9px; border-radius:20px; font-size:.74rem;
  font-weight:600; text-transform:uppercase; letter-spacing:.04em}
.badge.queued{background:var(--ledger-2); color:var(--accent)}
.badge.running{background:#f7e3c0; color:var(--warn)}
.badge.done{background:#d5ecde; color:var(--ok)}
.badge.failed{background:#f4d2cd; color:var(--err)}
.badge.skipped{background:#e6e1cf; color:var(--muted)}
.badge.draft{background:#e6e1cf; color:var(--muted)}
.badge.active{background:#d5ecde; color:var(--ok)}
.badge.disabled{background:#f4d2cd; color:var(--err)}

/* ---- forms ---- */
label{font-size:.82rem; color:var(--muted)}
input,select,textarea{
  background:var(--panel); border:1px solid var(--line); color:var(--ink);
  border-radius:8px; padding:9px 11px; font-size:.92rem; font-family:inherit;
  width:100%;
}
input:focus,select:focus,textarea:focus{outline:2px solid var(--accent);
  border-color:var(--accent); outline-offset:0}
textarea{resize:vertical; line-height:1.5}
textarea.code{font-family:ui-monospace,Menlo,Consolas,monospace; font-size:.86rem}
.field{margin-bottom:12px}
.field label{display:block; margin-bottom:4px}
.row{display:flex; gap:12px; flex-wrap:wrap}
.row .field{flex:1; min-width:160px}

.btn{display:inline-block; background:var(--ink); color:#fff; border:1px solid var(--ink);
  border-radius:6px; padding:8px 16px; font-size:.9rem; font-weight:500;
  letter-spacing:-.005em;
  cursor:pointer; font-family:inherit;
  transition:background .15s ease, border-color .15s ease;}
.btn:hover{background:#000; border-color:#000; text-decoration:none; color:#fff;}
.btn:focus-visible{outline:2px solid var(--accent); outline-offset:2px;}
.btn.ghost{background:transparent; border:1px solid var(--line-strong); color:var(--ink);}
.btn.ghost:hover{background:transparent; border-color:var(--ink); color:var(--ink);}
.btn.danger{background:transparent; border:1px solid var(--line-strong); color:var(--ink-2);}
.btn.danger:hover{border-color:var(--err); color:var(--err); background:transparent;}
/* Danger-solid: unmistakably destructive. Filled red at rest so the
   Delete action can't be misread as a plain button. Used inside a
   dedicated .danger-zone block. */
.btn.danger-solid{background:var(--err); border-color:var(--err); color:#fff;}
.btn.danger-solid:hover{background:#8b241d; border-color:#8b241d; color:#fff;}

/* Danger zone — a bordered, red-tinted block reserved for destructive
   actions (delete report, etc). Sits at the bottom of a settings
   section and clearly signals "here be dragons." */
.danger-zone{
  margin-top:24px; padding:0;
  border:1px solid rgba(160,48,39,.28); border-radius:8px;
  background:rgba(160,48,39,.03);}
.danger-zone-head{
  padding:10px 16px;
  background:rgba(160,48,39,.06);
  border-bottom:1px solid rgba(160,48,39,.16);
  border-radius:8px 8px 0 0;
  font-size:11px; font-weight:600;
  text-transform:uppercase; letter-spacing:.14em;
  color:var(--err);}
.danger-zone-body{
  display:flex; gap:16px; align-items:center; justify-content:space-between;
  padding:16px;}
.danger-zone-title{
  font-weight:600; color:var(--ink); margin-bottom:2px;}
.danger-zone-desc{
  color:var(--muted); font-size:13px; line-height:1.5;
  max-width:520px;}
@media (max-width: 640px){
  .danger-zone-body{flex-direction:column; align-items:stretch;}
  .danger-zone-body .btn{width:100%;}
}
.btn.sm{padding:5px 11px; font-size:.8rem}
form.inline{display:inline}

.notice{padding:11px 14px; border-radius:8px; margin-bottom:16px; font-size:.9rem;
  border:1px solid transparent}
.notice.ok{background:#e3f1ea; color:var(--ok); border-color:#bcdfca}
.notice.err{background:#f8e1dd; color:var(--err); border-color:#e7bab2}
.notice.info{background:var(--ledger-2); color:var(--accent2); border-color:rgba(22,106,84,.24)}

.empty{color:var(--muted); padding:26px; text-align:center}

.dot{display:inline-block; width:10px; height:10px; border-radius:50%;
  vertical-align:middle; margin-right:6px}
.dot-green{background:var(--ok); box-shadow:0 0 6px rgba(21,130,74,.35)}
.dot-amber{background:var(--warn); box-shadow:0 0 6px rgba(164,98,26,.35)}
.dot-red{background:var(--err); box-shadow:0 0 6px rgba(176,49,42,.35)}

code{background:var(--panel2); padding:2px 6px; border-radius:4px;
  font-size:.86em; color:#2d3142}

/* ───────────────────────────────────────────────────────────────────────
   Tenant detail page — vitals + cards
   ─────────────────────────────────────────────────────────────────────── */

/* slim crumbtrail above the page title */
.crumb{display:flex; justify-content:space-between; align-items:center;
  margin-bottom:10px; gap:14px}
.crumb .back{font-size:.84rem; color:var(--muted); text-decoration:none}
.crumb .back:hover{color:var(--ink); text-decoration:none}
.page-title{font-size:1.7rem; letter-spacing:-.01em; margin:0}
.page-sub{color:var(--muted); font-size:.88rem; margin:2px 0 22px}

/* ── Vitals strip — the signature element ─────────────────────────────
   Horizontal, hairline-divided, tabular numerals. Reads more like a
   trading terminal or a medical chart than a SaaS stat row.            */
.vitals{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(180px, 1fr));
  background:linear-gradient(180deg, #ffffff 0%, #fbf9f0 100%);
  border:1px solid var(--line); border-radius:14px; overflow:hidden;
  margin-bottom:18px;
}
.vital{
  padding:18px 22px;
  border-right:1px solid var(--line);
  position:relative;
}
.vital:last-child{border-right:none}
.vital-num,.vital-state{
  font-size:1.85rem; font-weight:650; line-height:1; letter-spacing:-.02em;
  color:var(--ink); font-feature-settings:'tnum' 1, 'ss01' 1;
  display:flex; align-items:baseline; gap:6px;
}
.vital-suffix{font-size:.85rem; color:var(--muted); font-weight:500}
.vital-state{font-size:1.5rem; text-transform:uppercase; letter-spacing:.04em;
  font-weight:600}
.vital-state.state-current{color:var(--ok)}
.vital-state.state-past_due{color:var(--warn)}
.vital-state.state-suspended{color:var(--err)}
.vital-label{font-size:.68rem; text-transform:uppercase; letter-spacing:.1em;
  color:var(--muted); margin-top:8px; font-weight:600}
.vital-trail{margin-top:10px; display:flex; align-items:center; gap:6px;
  color:var(--muted); font-size:.78rem; min-height:18px}

/* pulse dot for "needs attention" — subtle, doesn't shout */
.pulse{display:inline-block; width:8px; height:8px; border-radius:50%;
  background:var(--warn); position:relative; box-shadow:0 0 0 0 rgba(164,98,26,.45);
  animation:pulse 2.4s ease-out infinite}
@keyframes pulse{
  0%{box-shadow:0 0 0 0 rgba(164,98,26,.45)}
  70%{box-shadow:0 0 0 10px rgba(164,98,26,0)}
  100%{box-shadow:0 0 0 0 rgba(164,98,26,0)}
}
@media (prefers-reduced-motion: reduce){
  .pulse{animation:none}
}

/* ── Card grid ─────────────────────────────────────────────────────── */
.cards{display:grid; grid-template-columns:repeat(auto-fit, minmax(420px, 1fr));
  gap:14px; align-items:start; margin-bottom:14px}
.cards-headline{grid-template-columns:1fr}      /* full-width row */
.cards-triple{grid-template-columns:repeat(auto-fit, minmax(280px, 1fr))}
.cards-double{grid-template-columns:1fr 1fr; align-items:stretch}
@media (max-width: 880px){
  .cards-double{grid-template-columns:1fr}
}
.card{background:var(--panel); border:1px solid var(--line);
  border-radius:14px;
  /* overflow:hidden was clipping .li-menu (⋯ popup) inside rows. Now
     the popup can escape the card boundary. Rounded corners for
     backgrounded children (header, empty state) are enforced
     individually below. */
  overflow:visible;
  box-shadow:0 1px 2px rgba(0,0,0,.02);
  display:flex; flex-direction:column;}
.card > .card-body{flex:1}
.card > header{
  padding:14px 18px; display:flex; justify-content:space-between;
  align-items:center; gap:10px; border-bottom:1px solid var(--line);
  background:rgba(0,0,0,.015);
  border-radius:14px 14px 0 0;
}
.card > header h2{margin:0; font-size:.95rem; font-weight:600;
  display:flex; align-items:center; gap:8px}
.card-count{font-size:.74rem; font-weight:600; color:var(--muted);
  background:var(--panel2); padding:2px 8px; border-radius:10px;
  letter-spacing:.02em}
.card-body{padding:6px 0}
.card-wide{grid-column:1 / -1}

/* per-card inline form revealed by <details> */
.card-action[open] > summary{background:var(--panel2)}
.card-action > summary{list-style:none; cursor:pointer}
.card-action > summary::-webkit-details-marker{display:none}
.card-form{padding:14px 18px; background:var(--panel2);
  border-top:1px solid var(--line); border-bottom:1px solid var(--line);
  display:block}
.card-action .card-form{margin:0; border-top:none}
.card-inline{padding:0 18px 18px}     /* match the kv horizontal indent + breathing room below */
.card-inline .card-form{margin-top:10px; border-radius:8px; border:1px solid var(--line)}

/* ── Card list rows ────────────────────────────────────────────────── */
.card-list{list-style:none; padding:0; margin:0}
.card-list > li{display:grid;
  grid-template-columns:1fr auto auto;
  align-items:center; gap:14px;
  padding:11px 18px; border-bottom:1px solid var(--line);
  font-size:.92rem;
}
.card-list > li:last-child{border-bottom:none}
.li-main{display:flex; align-items:center; gap:10px; min-width:0}
.li-main a{color:var(--ink); text-decoration:none}
.li-main a:hover{color:var(--accent)}
.li-main strong{font-weight:600}
.li-meta{display:flex; align-items:center; gap:10px; color:var(--muted);
  font-size:.84rem}
.li-meta .mono{color:var(--ink)}
.li-actions details > summary{
  list-style:none; cursor:pointer;
  padding:2px 8px; color:var(--muted); border-radius:6px;
}
.li-actions details > summary::-webkit-details-marker{display:none}
.li-actions details > summary:hover{background:rgba(0,0,0,.04); color:var(--ink)}
.li-actions details[open] > summary{background:rgba(0,0,0,.05); color:var(--ink)}
.li-actions details{position:relative}
.li-menu{position:absolute; right:0; top:calc(100% + 4px); z-index:30;
  background:var(--panel); border:1px solid var(--line); border-radius:8px;
  padding:6px; box-shadow:0 12px 32px rgba(0,0,0,.16); min-width:140px;
  display:flex; flex-direction:column; gap:0}
.li-menu .link{
  background:none; border:none; color:var(--ink); text-align:left;
  padding:7px 10px; font-size:.86rem; cursor:pointer; border-radius:6px;
  text-decoration:none; font-family:inherit;
}
.li-menu .link:hover{background:rgba(0,0,0,.04)}
.li-menu .link.danger{color:var(--err)}

/* expanded inline editor row inside a card-list — beats the grid rule above
   via the compound .card-list > li.li-edit selector */
.card-list > li.li-edit{
  display:block; padding:0; border-bottom:1px solid var(--line);
}
.card-list > li.li-edit[hidden]{display:none}

/* ── Key/value descriptor list ─────────────────────────────────────── */
.kv{display:grid; grid-template-columns:140px 1fr;
  gap:10px 16px; margin:0; padding:14px 18px}
.kv dt{color:var(--muted); font-size:.8rem; font-weight:500}
.kv dd{margin:0; font-size:.9rem; color:var(--ink); word-break:break-word}

/* ── Lined table (denser than the default panel table) ─────────────── */
table.lined{margin:0 18px 14px; width:calc(100% - 36px); border-collapse:collapse}
table.lined th, table.lined td{border-bottom:1px solid var(--line);
  padding:8px 8px; vertical-align:top}
table.lined th{font-size:.7rem; text-transform:uppercase; letter-spacing:.06em;
  color:var(--muted); white-space:nowrap}
table.lined td.num, table.lined th.num{text-align:right;
  font-feature-settings:'tnum' 1}
table.lined tr:last-child td{border-bottom:none}

/* dot column trim */
table.integrations-table td:first-child{width:18px; padding-right:0; vertical-align:middle}
table.integrations-table td:nth-child(2){min-width:240px}
table.integrations-table .badge{font-size:.66rem}

/* per-row pop-out menu shared by integrations & invoices tables */
.row-menu{position:relative; display:inline-block}
.row-menu > summary{
  list-style:none; cursor:pointer; padding:2px 9px;
  color:var(--muted); border-radius:6px;
  background:var(--panel2); border:1px solid var(--line);
  font-size:.86rem; line-height:1.2;
}
.row-menu > summary::-webkit-details-marker{display:none}
.row-menu > summary:hover{color:var(--ink)}
.row-menu[open] > summary{background:var(--panel); color:var(--ink)}

/* the menu pops to the LEFT of its trigger so it doesn't clip outside the table */
.row-menu .li-menu{
  position:absolute; top:calc(100% + 4px); right:0;
  background:var(--panel); border:1px solid var(--line); border-radius:8px;
  padding:6px; box-shadow:0 12px 32px rgba(0,0,0,.18); min-width:170px;
  display:flex; flex-direction:column; z-index:30;
}
.row-menu .li-menu .link, .row-menu .li-menu a{
  background:none; border:none; color:var(--ink); text-align:left;
  padding:7px 10px; font-size:.86rem; cursor:pointer; border-radius:6px;
  text-decoration:none; font-family:inherit; display:block;
}
.row-menu .li-menu .link:hover, .row-menu .li-menu a:hover{background:rgba(0,0,0,.04)}
.row-menu .li-menu .link.danger{color:var(--err)}

/* inline-expand edit row inside a lined table */
table.lined tr.edit-row[hidden]{display:none}
table.lined tr.edit-row > td{padding:0}
table.lined tr.edit-row > td > .card-form{margin:0; border:none;
  border-top:1px solid var(--line); border-bottom:1px solid var(--line);
  background:var(--panel2)}

/* small text utilities */
.micro{font-size:.7rem; margin-top:2px}
.ellipsis{overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:300px}

/* ── Danger zone ───────────────────────────────────────────────────── */
.danger-zone{margin-top:36px; padding:16px 20px;
  border:1px dashed #d6a7a3; border-radius:12px;
  display:flex; justify-content:space-between; align-items:center; gap:18px;
  background:#fbeeeb}
.danger-zone > div p{margin:4px 0 0}
.danger-zone .btn{flex:none}

/* ── Empty / helper text inside cards ─────────────────────────────── */
.card .empty{padding:30px 18px; text-align:center; color:var(--muted);
  font-size:.9rem}

/* ── Mobile ────────────────────────────────────────────────────────── */
@media (max-width: 720px){
  .vitals{grid-template-columns:1fr 1fr}
  .vital{border-right:none; border-bottom:1px solid var(--line)}
  .vital:nth-child(2n){border-right:none}
  .card-list > li{grid-template-columns:1fr auto;
    grid-template-areas:"main actions" "meta meta"; row-gap:6px}
  .li-main{grid-area:main}
  .li-meta{grid-area:meta}
  .li-actions{grid-area:actions}
  .danger-zone{flex-direction:column; align-items:flex-start}
}

/* ───────────────────────────────────────────────────────────────────────
   Tenant billing — "Next payment" hero + unified billable-items table
   ─────────────────────────────────────────────────────────────────────── */
.upcoming{padding:0; overflow:hidden}
.upcoming-head{
  padding:22px 24px;
  display:flex; justify-content:space-between; align-items:flex-start;
  gap:18px; flex-wrap:wrap;
  background:linear-gradient(180deg, #ffffff 0%, #fbf9f0 100%);
  border-bottom:1px solid var(--line);
}
.upcoming-label{font-size:.7rem; text-transform:uppercase; letter-spacing:.1em;
  color:var(--muted); font-weight:600}
.upcoming-amount{
  font-size:2.4rem; font-weight:650; letter-spacing:-.02em;
  color:var(--ink); line-height:1; margin-top:8px;
  font-feature-settings:'tnum' 1, 'ss01' 1;
  display:flex; align-items:baseline; gap:6px;
}
.upcoming-amount .suf{font-size:.9rem; font-weight:500; color:var(--muted)}
.upcoming-date{margin-top:8px; font-size:.92rem; color:var(--muted)}
.upcoming-fine{margin-top:8px; max-width:380px; line-height:1.5}

/* tenant /billing page-head action buttons */
.billing-actions{display:flex; gap:10px; flex-wrap:wrap}
.btn:disabled{opacity:.55; cursor:not-allowed}
.btn:disabled:hover{background:var(--accent)}

/* tenant /billing redesigned panels */
.pay-due, .auto-pay{padding:24px 26px}
.pay-due-head, .auto-pay-head{
  display:flex; justify-content:space-between; align-items:flex-start;
  gap:18px; flex-wrap:wrap;
}
.pay-due-label, .auto-pay-label{
  font-size:.68rem; text-transform:uppercase; letter-spacing:.1em;
  color:var(--muted); font-weight:600; margin-bottom:8px;
}
.pay-due-amount{
  font-size:2.6rem; font-weight:650; letter-spacing:-.02em;
  color:var(--ink); line-height:1; margin-bottom:6px;
  font-feature-settings:'tnum' 1, 'ss01' 1;
}
.auto-pay-state{display:flex; align-items:center; gap:8px;
  font-size:1.05rem; line-height:1; margin-bottom:6px}
.auto-pay-state .dot{width:11px; height:11px}
.auto-pay-state strong{font-weight:650}
.auto-pay-foot{margin-top:16px; padding-top:14px;
  border-top:1px solid var(--line); line-height:1.55}
.auto-pay-foot a{color:var(--accent)}
.auto-pay-cta{display:flex; gap:10px; align-items:center; flex-wrap:wrap}

/* Compact inline date editor used in admin tenant KV rows */
.inline-date{display:inline-flex; gap:8px; align-items:center}
.inline-date input[type=date]{
  margin:0; padding:5px 8px; font-size:.88rem;
  border:1px solid var(--line); border-radius:6px;
  background:var(--panel); color:var(--ink);
  font-family:var(--ui); width:auto; min-width:140px;
}

/* secondary, low-emphasis button — for destructive-but-safe actions like
   "Turn off automated payments" */
.btn.ghost-quiet{
  background:transparent; color:var(--muted);
  border:1px solid var(--line); font-weight:500;
}
.btn.ghost-quiet:hover{
  background:var(--panel-soft); color:var(--ink); border-color:var(--ink-soft);
}

/* Next-payment line shown beneath the $0 "all caught up" state */
.pay-next{
  margin-top:14px; padding-top:14px; border-top:1px solid var(--line);
  display:flex; align-items:baseline; gap:10px; flex-wrap:wrap;
  line-height:1.4;
}
.pay-next-label{
  font-size:.68rem; text-transform:uppercase; letter-spacing:.1em;
  color:var(--muted); font-weight:600;
}
.pay-next-amount{
  font-size:1.15rem; font-weight:650; color:var(--ink);
  font-feature-settings:'tnum' 1;
}

/* Billing contact panel */
.panel.contact{padding:22px 26px}
.contact-head{margin-bottom:14px}
.contact-label{
  font-size:.68rem; text-transform:uppercase; letter-spacing:.1em;
  color:var(--muted); font-weight:600;
}
.contact-row{
  display:flex; gap:14px; align-items:flex-end; flex-wrap:wrap;
}
.contact-row .field{flex:1; min-width:220px}
.contact-row input{
  width:100%; padding:8px 10px; font-size:.95rem;
  border:1px solid var(--line); border-radius:6px;
  background:var(--panel); color:var(--ink); font-family:var(--ui);
}
.contact-row label{
  display:block; font-size:.78rem; color:var(--muted);
  margin-bottom:4px; font-weight:500;
}

/* Active subscriptions panel */
.panel.subs .subs-head{
  display:flex; justify-content:space-between; align-items:baseline;
  margin-bottom:14px; gap:14px;
}
.panel.subs .subs-head h2{margin:0}
.panel.subs .subs-foot{margin-top:14px}
.panel.subs .subs-foot a{color:var(--accent)}

@media (max-width:560px){
  .pay-due-head, .auto-pay-head{flex-direction:column}
}

/* checkbox-with-label inside forms */
label.check{display:flex; align-items:center; gap:8px; color:var(--ink);
  font-size:.92rem; font-weight:500; margin-bottom:4px; cursor:pointer}
label.check input[type=checkbox]{width:auto; margin:0; cursor:pointer}

/* tiny "currently set" hint next to a secret-input label */
.kept{display:inline-block; margin-left:8px; font-size:.7rem; font-weight:600;
  text-transform:uppercase; letter-spacing:.06em; color:var(--ok);
  background:#d5ecde; padding:2px 6px; border-radius:4px}

/* provider-specific block on the email-config card */
.prov-block{border:1px solid var(--line); border-radius:8px;
  padding:12px 14px; margin:14px 0 18px; background:var(--panel2)}
.prov-block legend{padding:0 6px; font-size:.74rem; font-weight:600;
  color:var(--muted); text-transform:uppercase; letter-spacing:.08em}
.prov-block .field:last-child{margin-bottom:0}
.upcoming-fine a{color:var(--accent); text-decoration:none}
.upcoming-fine a:hover{text-decoration:underline}
.upcoming-sub{text-align:right}
.billable-table{margin:0; width:100%}
.billable-table th, .billable-table td{padding:11px 18px}
.billable-table tr:last-child td{border-bottom:none}

.kind-tag{
  display:inline-block; font-size:.66rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.06em;
  padding:3px 9px; border-radius:4px; line-height:1.3;
  border:1px solid var(--line); background:var(--panel2); color:var(--muted);
}
.kind-tag.kind-integration{background:var(--ledger-2); border-color:rgba(22,106,84,.24); color:var(--accent)}
.kind-tag.kind-hourly{background:#f7e3c0; border-color:#e6c887; color:var(--warn)}
.kind-tag.kind-custom{background:#e3edd9; border-color:#c6d6b3; color:#3f6a26}
.kind-tag.kind-recurring{background:#e6e1cf; border-color:#cbc3a5; color:var(--muted)}

@media (max-width: 560px){
  .upcoming-head{flex-direction:column}
  .upcoming-sub{text-align:left}
}

/* ───────────────────────────────────────────────────────────────────────
   Activity panel — 24h × 30d heatmap on the integration detail page.
   Signature graphic: hairline axes, restrained blue ramp, red ring
   only when a cell contains a failed run. Iter 354 removed the legend
   strip below the grid; the ramp reads without a printed key and cell
   tooltips give exact counts on hover.
   ─────────────────────────────────────────────────────────────────────── */
.activity{padding:32px 34px 36px}
.activity .activity-head{display:flex; justify-content:space-between;
  align-items:baseline; gap:16px; margin-bottom:28px}
.activity .activity-head h2{margin:0; font-size:1rem; font-weight:650;
  letter-spacing:-.005em}

/* ── heatmap — figure / row / axis ────────────────────────────────── */
/* single hero graphic on this page; give it room */
.heatmap-fig{margin:0}
.heatmap-row{display:flex; gap:16px; align-items:flex-start}
.heatmap-yaxis{
  position:relative; flex:none; width:26px;
  font-family:ui-monospace,Menlo,Consolas,monospace;
  font-size:.66rem; line-height:1; color:var(--muted);
  letter-spacing:.04em;
}
.heatmap-yaxis span{position:absolute; right:2px; text-align:right}
.heatmap{
  display:block; width:100%; height:auto;
  /* Iter 354: keep the grid crisp at large widths. Cells are 30×18 in
     the SVG's viewBox; xMidYMid meet keeps their aspect ratio so a
     wide panel doesn't stretch them horizontally into bars. */
}
.heatmap rect{transition:opacity .18s ease}
.heatmap rect:hover{opacity:.72; cursor:default}

/* x-axis: sparse date markers positioned by percentage over the SVG
   width. Each <li> gets an inline `left:%` from the template — one
   marker at each ISO-week Monday plus the start/end. Absolute
   positioning lets the labels sit exactly under the day column they
   name instead of being spread evenly by flex justify. */
.heatmap-xaxis{
  list-style:none; padding:0; margin:14px 0 0 42px;
  position:relative; height:1.2em;
  font-family:ui-monospace,Menlo,Consolas,monospace;
  font-size:.7rem; color:var(--muted);
  letter-spacing:.04em;
}
.heatmap-xaxis li{
  position:absolute; transform:translateX(-50%);
  white-space:nowrap;
}

/* Intensity legend — a quiet horizontal strip aligned under the SVG.
   Right-side inline legend would eat into the panel width; below-strip
   keeps the heatmap full-bleed and reads as a caption to the chart. */
.heatmap-legend{
  display:flex; align-items:center; gap:26px;
  margin:20px 0 0 42px;
  font-family:ui-monospace,Menlo,Consolas,monospace;
  font-size:.66rem; letter-spacing:.08em; text-transform:uppercase;
  color:var(--muted);
}
.heatmap-legend .l-key{opacity:.72}
.heatmap-legend .l-scale{
  display:inline-flex; align-items:center; gap:5px;
}
.heatmap-legend .l-scale i{
  display:inline-block; width:16px; height:8px; border-radius:2px;
}
.heatmap-legend .l-scale em{
  font-style:normal; opacity:.72; text-transform:none;
  letter-spacing:.04em; padding:0 4px;
}
.heatmap-legend .l-fail{
  display:inline-flex; align-items:center; gap:7px;
  margin-left:auto;
  text-transform:none; letter-spacing:.04em;
}
.heatmap-legend .l-fail .fail-swatch{
  width:10px; height:10px; border-radius:2px;
  background:transparent;
  box-shadow:inset 0 0 0 1.4px var(--err);
}

@media (max-width: 720px){
  .heatmap-legend{
    margin-left:28px; gap:14px;
    flex-wrap:wrap;
  }
  .heatmap-legend .l-fail{margin-left:0; width:100%}
}

@media (max-width: 720px){
  .activity{padding:22px 18px 26px}
  .heatmap-row{gap:8px; flex-wrap:wrap}
  .heatmap-yaxis{width:20px}
  .heatmap-xaxis{margin-left:28px}
}

/* ── HUD — at-a-glance dashboard strip on the integration page ───── */
.hud{padding:0; overflow:hidden}
.hud-row{display:grid; grid-template-columns:1fr 1fr; gap:0}
.hud-status, .hud-counts{padding:20px 22px}
.hud-status{border-right:1px solid var(--line);
  background:linear-gradient(180deg, #ffffff, #fbf9f0)}
.hud-eyebrow{font-size:.68rem; text-transform:uppercase; letter-spacing:.1em;
  color:var(--muted); font-weight:600; margin-bottom:10px}
.hud-state-line{display:flex; align-items:center; gap:10px; margin-bottom:8px}
.hud-state-line .dot{width:12px; height:12px}
.hud-diag{color:var(--ink); line-height:1.5; max-width:380px}
.hud-count-row{display:flex; align-items:baseline; gap:24px; margin-bottom:10px}
.hud-c{display:flex; flex-direction:column; align-items:baseline; line-height:1}
.hud-c .n{font-size:1.75rem; font-weight:650; color:var(--ink);
  font-feature-settings:'tnum' 1, 'ss01' 1; letter-spacing:-.02em}
.hud-c .l{font-size:.66rem; text-transform:uppercase; letter-spacing:.08em;
  color:var(--muted); margin-top:4px; font-weight:600}
.hud-c-fail .n{color:var(--err)}
.hud-c-skip .n{color:var(--muted)}
.hud-last{color:var(--muted); font-size:.86rem}
.hud-last time{color:var(--ink); font-feature-settings:'tnum' 1}

@media (max-width: 640px){
  .hud-row{grid-template-columns:1fr}
  .hud-status{border-right:none; border-bottom:1px solid var(--line)}
  .hud-count-row{gap:18px}
}

/* ── super-only collapsible panel ─────────────────────────────────── */
.super-only{padding:18px 22px}
.super-only summary{cursor:pointer; list-style:none}
.super-only summary::-webkit-details-marker{display:none}
.super-only summary:focus-visible{
  outline:2px solid var(--ledger,#166A54); outline-offset:2px;
  border-radius:4px}
.super-only summary::before{content:'▸ '; color:var(--muted)}
.super-only[open] summary::before{content:'▾ '}

/* ---- secret-flash panel: one-shot credentials reveal ---- */
.secret-flash{border:1px solid var(--ok); background:#e3f1ea}
.copyrow{margin-top:14px}
.copyrow > label{display:block; font-size:.82rem; color:var(--muted);
  margin-bottom:4px}
.copybox{position:relative; display:flex; align-items:stretch; gap:0}
.copybox input,.copybox pre{flex:1; margin:0; min-width:0;
  font-family:ui-monospace,Menlo,Consolas,monospace; font-size:.86rem;
  border-radius:8px 0 0 8px; padding:10px 12px; line-height:1.45;
  white-space:pre; overflow-x:auto}
.copybox input{height:42px; background:#fff}
.copybox pre{background:#fff; border:1px solid var(--line);
  border-right:none}
.copy-btn{display:inline-flex; align-items:center; gap:6px;
  background:var(--panel2); color:var(--ink); border:1px solid var(--line);
  border-left:none; border-radius:0 8px 8px 0; padding:0 14px; cursor:pointer;
  font-family:inherit; font-size:.84rem; font-weight:600;
  transition:background .15s}
.copy-btn:hover{background:var(--accent); border-color:var(--accent);
  color:#fff}
.copy-btn:focus-visible{outline:2px solid var(--accent); outline-offset:2px;
  outline-style:solid}
.copy-btn svg{width:14px; height:14px}
.copy-btn.copied{background:var(--ok); border-color:var(--ok); color:#fff}

pre.payload{background:#fff; border:1px solid var(--line);
  border-radius:8px; padding:14px; overflow:auto; font-size:.82rem; max-height:420px}

/* ---- landing / login ---- */
.bare{background:radial-gradient(900px 500px at 70% -10%,#e1e7f7,transparent),
  var(--bg); min-height:100vh}
.lp-nav{display:flex; justify-content:space-between; align-items:center;
  max-width:1080px; margin:0 auto; padding:22px 24px}
.lp-nav .brand a{font-size:1.4rem}
.hero{max-width:1080px; margin:0 auto; padding:60px 24px 40px; text-align:center}
.hero h1{font-size:2.9rem; line-height:1.1; margin-bottom:.3em}
.hero .lead{font-size:1.15rem; color:var(--muted); max-width:620px;
  margin:0 auto 28px}
.hero .cta{display:flex; gap:14px; justify-content:center; flex-wrap:wrap}
.features{max-width:1080px; margin:0 auto; padding:20px 24px 60px;
  display:grid; grid-template-columns:repeat(auto-fit,minmax(240px,1fr)); gap:18px}
.feature{background:var(--panel); border:1px solid var(--line);
  border-radius:var(--radius); padding:22px}
.feature h3{color:var(--accent)}
.lp-foot{border-top:1px solid var(--line); text-align:center; padding:26px;
  color:var(--muted); font-size:.9rem}

.impersonate-banner{
  background:#fdf3df; border-bottom:1px solid #e6c887; color:#7a4a14;
  padding:9px 18px; display:flex; align-items:center; justify-content:space-between;
  font-size:.92rem; gap:14px;
}
.impersonate-banner .btn{background:#a4621a; border:0; color:#fff}
.impersonate-banner .btn:hover{background:#7a4a14; color:#fff}

/* ---- platforms section: editorial capability list ---------------------
   A two-column dl (category | platforms) typeset like a magazine credits
   page. Inverts the usual 'BIG HEADER / small content' rhythm — content
   carries the visual weight, eyebrow categories quietly anchor it.       */
.platforms-v2{
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
  padding:64px 24px;
  background:linear-gradient(180deg, var(--bg) 0%, #fbf9f0 100%);
}
.pl-inner{max-width:980px; margin:0 auto}
.pl-head{
  display:flex; justify-content:space-between; align-items:baseline;
  gap:48px; margin-bottom:28px; flex-wrap:wrap;
}
.pl-head h2{
  margin:0; font-size:1.7rem; letter-spacing:-.02em; font-weight:650;
  color:var(--ink);
}
.pl-sub{
  margin:0; max-width:340px; color:var(--muted);
  font-size:.95rem; line-height:1.55; text-align:right; font-style:italic;
}
.pl-grid{
  margin:0; padding:24px 0;
  display:grid; grid-template-columns:140px 1fr;
  column-gap:36px; row-gap:18px;
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
  align-items:baseline;
}
.pl-grid dt{
  font-size:.7rem; text-transform:uppercase; letter-spacing:.14em;
  font-weight:700; color:var(--muted); margin:0;
}
.pl-grid dd{
  margin:0; color:var(--ink); font-size:.96rem; line-height:1.7;
  font-feature-settings:'kern' 1;
}
.pl-foot{
  margin:22px 0 0; color:var(--muted); font-size:.92rem;
}
.pl-foot a{color:var(--accent); font-weight:500}

@media (max-width: 640px){
  .platforms-v2{padding:44px 20px}
  .pl-head{flex-direction:column; align-items:flex-start; gap:10px}
  .pl-sub{text-align:left; max-width:none}
  .pl-grid{grid-template-columns:1fr; row-gap:4px; padding:18px 0}
  .pl-grid dt{margin-top:14px}
  .pl-grid dt:first-of-type{margin-top:0}
}
.auth-card{max-width:400px; margin:9vh auto; background:var(--panel);
  border:1px solid var(--line); border-radius:14px; padding:38px; text-align:center;
  box-shadow:0 2px 8px rgba(0,0,0,.04)}
.auth-card h1{font-size:1.6rem}
.gbtn{display:inline-flex; align-items:center; gap:10px; background:#fff;
  color:#3c4043; border:1px solid var(--line);
  border-radius:8px; padding:11px 20px; font-weight:600;
  font-size:.95rem; margin-top:18px}
.gbtn:hover{text-decoration:none; box-shadow:0 2px 10px rgba(0,0,0,.08)}
.gbtn:focus-visible{outline:3px solid var(--accent); outline-offset:3px;
  text-decoration:none;}
.gbtn svg{width:18px; height:18px}
.code-list{list-style:none; padding:0; margin:0}
.code-list li{padding:7px 0; border-bottom:1px solid var(--line); font-size:.88rem}
.code-list li:last-child{border:none}

/* ─────────────────────────────────────────────────────────────────────────
   Reports feature — tabs, iframe view, range picker, paywall, token mask
   ───────────────────────────────────────────────────────────────────────── */
.paywall{padding:28px 32px}
.paywall h2{font-size:1.25rem; letter-spacing:-.01em}
.paywall .price{font-size:1.6rem; font-weight:700; letter-spacing:-.02em;
  color:var(--ink); margin:14px 0 6px; font-variant-numeric:tabular-nums}
.paywall .price small{color:var(--muted); font-size:.9rem; font-weight:500;
  margin-left:4px}
.paywall .features{list-style:none; padding:0; margin:12px 0 20px;
  color:var(--muted)}
.paywall .features li{padding:5px 0 5px 22px; position:relative}
.paywall .features li::before{
  content:""; position:absolute; left:0; top:11px; width:12px; height:2px;
  background:var(--accent); border-radius:1px;
}
.paywall .fine{color:var(--muted); font-size:.82rem; margin-top:12px}

/* Source tabs — pill-strip that sits above the source detail panel */
.tabs.report-tabs{
  display:flex; gap:4px; margin-bottom:22px;
  border-bottom:1px solid var(--line);
}
.report-tab{
  display:inline-flex; align-items:center; padding:9px 16px 10px;
  border:1px solid var(--line); border-bottom:none;
  border-radius:8px 8px 0 0; margin-bottom:-1px;
  background:var(--panel2); color:var(--muted);
  font-weight:600; font-size:.9rem; text-decoration:none;
  transition:background .15s ease, color .15s ease;
}
.report-tab:hover{background:#efe6ce; color:var(--ink); text-decoration:none}
.report-tab.active{
  background:var(--panel); color:var(--ink);
  border-bottom:1px solid var(--panel);
  position:relative;
}
.report-tab.active::before{
  content:""; position:absolute; left:14px; right:14px; top:0;
  height:2px; background:var(--accent); border-radius:2px;
}
.report-tab.new{
  border-style:dashed; background:transparent; color:var(--muted);
  font-weight:500;
}
.report-tab.new:hover{background:rgba(37,72,199,.05); color:var(--accent)}

/* Source detail block: two-column with metadata on the left, action on right */
.source-detail{
  display:grid; grid-template-columns:1fr auto;
  gap:24px; align-items:start; margin-bottom:22px;
}
.source-detail .field-label{
  font-size:.72rem; text-transform:uppercase; letter-spacing:.06em;
  color:var(--muted); font-weight:600; margin-bottom:2px;
}
.source-detail .field-row{margin-bottom:10px}
.source-detail .field-row:last-child{margin-bottom:0}
.mask-token{font-family:ui-monospace,Menlo,Consolas,monospace;
  font-size:.86rem; color:var(--ink); letter-spacing:.02em}

/* Generate form — range picker with radio choices */
.gen-form{
  border:1px solid var(--line); background:var(--panel2);
  border-radius:var(--radius); padding:16px 18px; margin-bottom:22px;
}
.gen-form h3{margin:0 0 10px; font-size:.9rem;
  text-transform:uppercase; letter-spacing:.06em;
  color:var(--muted); font-weight:600}
.range-choices{display:grid; gap:8px; margin:0 0 14px}
.range-choice{
  display:flex; align-items:center; gap:10px; padding:8px 10px;
  border:1px solid transparent; border-radius:8px; cursor:pointer;
  transition:background .12s ease, border-color .12s ease;
  font-weight:400;
}
.range-choice:hover{background:rgba(37,72,199,.04)}
.range-choice input[type=radio]{
  accent-color:var(--accent); width:16px; height:16px; margin:0;
}
.range-choice input[type=radio]:checked ~ span,
.range-choice:has(input[type=radio]:checked){
  border-color:var(--line); background:var(--panel);
}
.range-choice input[type=number]{
  width:72px; padding:3px 6px; font-size:.85rem;
  border:1px solid var(--line); border-radius:6px;
  font-family:ui-monospace,Menlo,monospace;
}
.range-choice select{
  padding:3px 8px; font-size:.85rem;
  border:1px solid var(--line); border-radius:6px;
  background:var(--panel);
}
.gen-actions{display:flex; align-items:center; gap:12px; flex-wrap:wrap}
.gen-actions .fine{color:var(--muted); font-size:.82rem}
.ad-spend{display:flex; align-items:center; gap:10px; margin-right:4px}
.ad-spend-label{color:var(--muted); font-size:.85rem}
.ad-spend-input{position:relative; display:inline-flex; align-items:center}
.ad-spend-prefix{position:absolute; left:10px; color:var(--muted); font-size:.9rem; pointer-events:none}
.ad-spend-input input{width:130px; padding:6px 8px 6px 22px; border:1px solid var(--border); border-radius:4px; background:var(--panel); font-family:inherit; font-size:.9rem}

/* Wrapped report iframe: fills the tenant chrome content area */
.report-frame-panel{padding:0; overflow:hidden}
.report-frame{
  width:100%; border:0; display:block;
  height:calc(100vh - 220px); min-height:900px;
}

/* Actions column: right-align small button clusters in table rows */
.actions-cell{text-align:right; white-space:nowrap}
.actions-cell .btn.sm + .btn.sm,
.actions-cell form + form,
.actions-cell form + .btn,
.actions-cell .btn + form{margin-left:6px}

/* Table row hover — subtle affordance across every list-style table */
table tbody tr{transition:background .1s ease}
table tbody tr:hover{background:rgba(37,72,199,.03)}

/* Flash animation — one gentle fade-in on notices so a redirect->page
   doesn't blast the message in cold. */
.notice{animation:notice-in .28s ease both}
@keyframes notice-in{
  from{opacity:0; transform:translateY(-4px)}
  to{opacity:1; transform:translateY(0)}
}
/* Respect prefers-reduced-motion: the translateY jolt on every
   flash notice can trigger vestibular symptoms for motion-sensitive
   users. Notice content is functional; the animation isn't — safe
   to disable. Matches the .pulse guard at line 261 (same file).*/
@media (prefers-reduced-motion: reduce){
  .notice{animation:none}
}

/* Kbd-style muted callouts inside notices/notes */
.notice code{background:rgba(0,0,0,.06); padding:1px 5px; border-radius:4px;
  font-size:.85em; color:var(--ink)}

/* Compact price input pattern: "$ [num] /month" */
.price-input{display:inline-flex; align-items:center; gap:6px}
.price-input input[type=number]{width:120px}

/* ─────────────────────────────────────────────────────────────
   Reports redesign (2026-07-09) — unified sources panel, inline
   latest report, campaign chips, collapsible generate/past. */

/* Latest report card — inline HTML sits inside .latest-report-body
   which is CSS-isolated via the .report-scope wrapper the server
   emits. Header has actions on the right, meta line under title. */
.latest-report{padding:0}
.latest-report-head{
  display:flex; align-items:flex-start; justify-content:space-between;
  gap:16px; padding:20px 22px 16px 22px;
  border-bottom:1px solid var(--line);}
.latest-report-head .actions-cell{
  display:flex; gap:8px; flex-shrink:0;}
.latest-report-body{padding:0 22px 22px 22px; overflow-x:auto;}
/* Scope the embedded report so its own styles don't leak. The
   report file's <style> blocks target these general selectors and
   we don't want them re-hitting the outer chrome. */
.latest-report-body .report-scope{
  max-width:100%; overflow-x:auto;}
.latest-report-body .report-scope table{
  max-width:100%;}

/* Generate panel — collapsible details/summary block. */
.gen-panel details{padding:0}
.gen-panel summary{
  cursor:pointer; padding:16px 20px; list-style:none;
  display:flex; align-items:center; justify-content:space-between;
  border-radius:8px; user-select:none;}
.gen-panel summary::-webkit-details-marker{display:none}
.gen-panel summary::before{
  content:"›"; font-size:20px; margin-right:10px; color:var(--muted);
  transform:rotate(0deg); transition:transform 120ms ease;}
.gen-panel details[open] summary::before{transform:rotate(90deg);}
.gen-panel summary:hover{background:var(--card-hover, #f8fafc);}
.gen-panel .gen-summary-inner{flex:1; display:flex; gap:10px; align-items:baseline;}
.gen-panel form{padding:8px 20px 20px 20px;}
.gen-panel .range-choices{margin-bottom:12px}

/* Data sources panel */
.sources-panel{padding:0}
.sources-head{padding:20px 22px 12px 22px; border-bottom:1px solid var(--line);}
.sources-list{display:flex; flex-direction:column;}
.source-row{
  display:flex; gap:14px; align-items:flex-start;
  padding:16px 22px; border-bottom:1px solid var(--line);}
.source-row:last-child{border-bottom:none;}
.source-icon{
  flex-shrink:0; width:44px; height:44px; border-radius:8px;
  display:flex; align-items:center; justify-content:center;
  font-weight:700; font-size:11px; letter-spacing:.02em;
  background:var(--card-hover,#f8fafc); color:var(--muted);
  border:1px solid var(--line);}
.source-ghl .source-icon{background:#f0fdfa; color:#0d9488; border-color:#99f6e4;}
.source-meta .source-icon{background:#eff6ff; color:#2563eb; border-color:#bfdbfe;}
.source-body{flex:1; min-width:0;}
.source-title{
  display:flex; gap:8px; align-items:center; flex-wrap:wrap;
  margin-bottom:4px; color:var(--ink);}
.source-title strong{color:var(--ink);}
.source-meta{margin-top:4px;}

/* Chip — used for "included campaigns" tags on Meta source rows */
.chip{
  display:inline-block; padding:2px 8px; margin:2px 4px 2px 0;
  font-size:12px; border-radius:12px;
  background:var(--card-hover,#f8fafc); color:var(--ink);
  border:1px solid var(--line);}

/* Add-source collapsible row */
.add-source{
  border-top:1px dashed var(--line); background:var(--card-hover,#f8fafc);}
.add-source summary{
  cursor:pointer; padding:16px 22px; list-style:none;
  display:flex; gap:14px; align-items:center; user-select:none;}
.add-source summary::-webkit-details-marker{display:none}
.add-source summary::before{
  content:"›"; font-size:20px; color:var(--muted);
  transform:rotate(0deg); transition:transform 120ms ease;
  order:-1; margin-right:-6px;}
.add-source[open] summary::before{transform:rotate(90deg);}
.add-source .add-icon{
  background:#fff; color:var(--muted); border:1px dashed var(--line);
  font-size:22px; font-weight:400;}
.add-source-body{
  padding:6px 22px 22px 22px;
  display:grid; grid-template-columns:1fr 1fr; gap:24px;}
.add-source-provider h4{margin:0 0 4px 0;}
@media (max-width: 720px){
  .add-source-body{grid-template-columns:1fr;}
}

/* Past reports panel */
.past-panel details{padding:0}
.past-panel summary{
  cursor:pointer; padding:14px 22px; list-style:none;
  display:flex; gap:8px; align-items:baseline; user-select:none;}
.past-panel summary::-webkit-details-marker{display:none}
.past-panel summary::before{
  content:"›"; font-size:20px; color:var(--muted);
  transform:rotate(0deg); transition:transform 120ms ease;
  margin-right:6px;}
.past-panel details[open] summary::before{transform:rotate(90deg);}
.past-panel table{margin:0 22px 22px 22px; width:calc(100% - 44px);}

/* Meta at-a-glance panel */
.meta-overview{padding:0;}
.meta-overview-head{
  padding:20px 22px 8px 22px; border-bottom:1px solid var(--line);
  display:flex; align-items:baseline; gap:12px; flex-wrap:wrap;}
.meta-overview-body{padding:14px 22px 20px 22px;}
.meta-overview-loading{padding:10px 0;}
.meta-tile-grid{
  display:grid; grid-template-columns:repeat(6, 1fr);
  gap:10px;}
@media (max-width: 900px){
  .meta-tile-grid{grid-template-columns:repeat(3, 1fr);}
}
@media (max-width: 520px){
  .meta-tile-grid{grid-template-columns:repeat(2, 1fr);}
}
.meta-tile{
  background:var(--card-hover,#f8fafc); border:1px solid var(--line);
  border-radius:8px; padding:12px 14px;}
.meta-tile-label{
  font-size:11px; letter-spacing:.03em; text-transform:uppercase;
  color:var(--muted); margin-bottom:6px;}
.meta-tile-value{
  font-size:22px; font-weight:700; color:var(--ink); font-variant-numeric:tabular-nums;
  line-height:1.1;}
.meta-tile-sub{font-size:12px; font-weight:400; margin-left:4px;}

/* Top campaigns list under the tile grid */
.top-campaigns{margin-top:18px;}
.top-campaigns h3{
  font-size:13px; font-weight:600; color:var(--muted);
  text-transform:uppercase; letter-spacing:.03em; margin:0 0 8px 0;}
.top-campaigns ol{padding-left:20px; margin:0;}
.top-campaigns li{margin-bottom:8px;}
.top-campaigns .tc-name{font-weight:600; color:var(--ink);}
.top-campaigns .tc-meta{margin-top:2px;}

/* Meta campaign picker — checkbox variant of .range-choice.
   Fixes: checkbox sitting in the vertical middle of tall multi-line
   labels was pushing the campaign details away from the left edge.
   Now checkbox is top-aligned, campaign span takes flex:1 to fill. */
.range-choice input[type=checkbox]{
  accent-color:var(--accent); width:16px; height:16px;
  margin:3px 0 0 0; flex-shrink:0;
}
.range-choice:has(input[type=checkbox]){
  align-items:flex-start;
}
.range-choice:has(input[type=checkbox]) > span{
  flex:1; min-width:0; word-wrap:break-word;
}
.range-choice:has(input[type=checkbox]:checked){
  border-color:var(--line); background:var(--panel);
}

/* Meta at-a-glance range tabs */
.meta-overview-head{
  justify-content:space-between; align-items:center;}
.meta-overview-ranges{
  display:flex; gap:4px; align-items:center; flex-wrap:wrap;}
.meta-overview-ranges .range-tab{
  padding:5px 10px; font-size:12px; font-weight:600;
  border:1px solid var(--line); background:var(--panel);
  border-radius:6px; cursor:pointer; color:var(--muted);
  font-family:inherit; line-height:1;
  transition:all .12s ease;}
.meta-overview-ranges .range-tab:hover{color:var(--ink);}
.meta-overview-ranges .range-tab.active{
  background:var(--accent, #2548c7); color:#fff; border-color:transparent;}
.meta-overview-ranges .range-tab-custom{
  display:flex; align-items:center; gap:4px; padding:2px 8px;}
.meta-overview-ranges .range-tab-custom input{
  width:48px; padding:3px 6px; font-size:12px; text-align:center;
  border:1px solid var(--line); border-radius:4px;
  font-family:ui-monospace,Menlo,monospace;}
.meta-overview-ranges .range-tab-custom span{
  font-size:11px; color:var(--muted);}

/* Latest-report quick refresh form — compact dropdowns + button row */
.latest-report-refresh{
  display:flex; gap:6px; align-items:center; flex-wrap:wrap;}
.latest-report-refresh .lr-select,
.latest-report-refresh .lr-custom-days{
  padding:5px 8px; font-size:12px;
  border:1px solid var(--line); border-radius:6px;
  background:var(--panel); color:var(--ink);
  font-family:inherit; line-height:1;}
.latest-report-refresh .lr-custom-days{
  width:56px; font-family:ui-monospace,Menlo,monospace; text-align:center;}
@media (max-width: 640px){
  .latest-report-refresh{width:100%; margin-top:8px;}
}

/* Report tab strip — each tab is one bundled report configuration */
.report-tabs{
  display:flex; align-items:flex-end; gap:2px;
  margin:0 0 -1px 0; padding:0 4px;
  border-bottom:1px solid var(--line);
  flex-wrap:wrap;}
.report-tabs .report-tab{
  padding:9px 16px; font-size:13px; font-weight:600;
  color:var(--muted); text-decoration:none;
  background:transparent; border:1px solid transparent;
  border-bottom:none; border-radius:8px 8px 0 0;
  transition:all .12s ease; cursor:pointer;}
.report-tabs .report-tab:hover{color:var(--ink); background:var(--card-hover,#f8fafc);}
.report-tabs .report-tab.active{
  color:var(--ink); background:var(--panel);
  border-color:var(--line);
  position:relative; z-index:1;}
.report-tabs .new-report-tab{
  position:relative; padding:0; margin-left:auto;
  border:none; background:transparent;}
.report-tabs .new-report-tab summary{
  list-style:none; cursor:pointer;
  padding:9px 16px; font-size:13px; font-weight:600;
  color:var(--muted); background:transparent;
  border:1px dashed var(--line);
  border-radius:8px 8px 0 0; border-bottom:none;}
.report-tabs .new-report-tab summary::-webkit-details-marker{display:none}
.report-tabs .new-report-tab summary:hover{color:var(--ink); background:var(--card-hover,#f8fafc);}
.report-tabs .new-report-form{
  position:absolute; top:100%; right:0;
  display:flex; gap:6px; align-items:center; padding:10px;
  background:var(--panel); border:1px solid var(--line);
  border-radius:8px; margin-top:4px;
  box-shadow:0 4px 12px rgba(0,0,0,.08); z-index:10;
  min-width:260px;}
.report-tabs .new-report-form input{
  flex:1; padding:6px 10px; font-size:13px;
  border:1px solid var(--line); border-radius:6px;}

/* Report options collapsible panel */
.report-options{margin-top:0;}
.report-options summary{
  cursor:pointer; padding:14px 22px; list-style:none;
  display:flex; gap:8px; align-items:baseline;}
.report-options summary::-webkit-details-marker{display:none}
.report-options summary::before{
  content:"›"; font-size:20px; color:var(--muted);
  transform:rotate(0deg); transition:transform 120ms ease;
  margin-right:6px;}
.report-options details[open] summary::before{transform:rotate(90deg);}
.report-options-body{
  padding:0 22px 22px 22px;
  display:flex; flex-direction:column; gap:20px;}
.report-options-form label{
  display:block; font-weight:600; margin-bottom:8px; color:var(--ink);}
.report-options-form input[type=text],
.report-options-form input:not([type]){
  padding:6px 10px; font-size:13px;
  border:1px solid var(--line); border-radius:6px;}

/* Google Ads source icon — red-ish tint matching Google Ads branding */
.source-google-ads .source-icon{
  background:#fef2f2; color:#dc2626; border-color:#fecaca;
  font-size:10px;}

/* ─────────────────────────────────────────────────────────────
   Tenant dashboard — 5 clickable tiles in a responsive grid */
.td-grid{
  display:grid; gap:16px;
  grid-template-columns:repeat(4, 1fr);
  margin-top:6px;}
@media (max-width: 1100px){
  .td-grid{grid-template-columns:repeat(2, 1fr);}
}
@media (max-width: 520px){
  .td-grid{grid-template-columns:1fr;}
}
.td-tile{
  display:block;
  background:var(--panel); border:1px solid var(--line);
  border-radius:var(--radius); padding:20px 22px;
  color:var(--ink); text-decoration:none;
  transition:transform .12s ease, box-shadow .12s ease,
             border-color .12s ease;}
.td-tile:hover{
  border-color:var(--accent);
  box-shadow:0 4px 14px rgba(37,72,199,.10);
  transform:translateY(-1px);
  text-decoration:none;}
.td-tile-label{
  font-size:.72rem; text-transform:uppercase;
  letter-spacing:.06em; color:var(--muted);
  margin-bottom:8px; font-weight:600;}
.td-tile-main{
  display:flex; align-items:baseline; gap:8px;
  margin-bottom:6px;}
.td-tile-num{
  font-size:2rem; font-weight:700;
  color:var(--ink); line-height:1;
  font-variant-numeric:tabular-nums;
  letter-spacing:-.01em;}
.td-tile-num-muted{color:var(--muted);}
.td-tile-frac{
  font-size:.88rem; color:var(--muted);
  font-weight:500;}
.td-tile-sub{
  font-size:.85rem; color:var(--muted);
  line-height:1.4;}
.td-tile:hover .td-tile-sub{color:var(--ink);}
/* Attention state — outstanding balance or overdue */
.td-tile-attn{
  background:linear-gradient(0deg, #fef4f2 0%, var(--panel) 100%);
  border-color:#f4d2cd;}
.td-tile-attn .td-tile-num{color:var(--err);}
.td-tile-attn:hover{
  border-color:var(--err);
  box-shadow:0 4px 14px rgba(176,49,42,.15);}
/* Good state — all paid up */
.td-tile-good .td-tile-num{color:var(--ok);}

/* Tenant dashboard hero row — Total due + Automatic payments.
   Separated from the tile grid below by a slightly larger gap, but
   tiles themselves are IDENTICAL in size, padding, and typography
   to the ones in the grid. Same visual weight, just semantically
   grouped as billing-related. */
.td-hero{
  display:grid; gap:16px;
  grid-template-columns:1fr 1fr;
  margin-bottom:24px;}     /* gap between hero row and tile grid */
@media (max-width: 900px){
  .td-hero{grid-template-columns:1fr;}
}
/* .td-hero-tile now inherits everything from .td-tile — no overrides.
   .td-hero-num and .td-hero-num-status just reuse the same font size
   as .td-tile-num for harmonized alignment. */
.td-hero-num{
  font-size:2rem; font-weight:700;
  color:var(--ink); line-height:1;
  font-variant-numeric:tabular-nums;
  letter-spacing:-.01em;}
.td-hero-num-status{font-size:2rem;}
.td-hero-num-muted{color:var(--muted);}

/* 3-column grid variant when 3 tiles below the hero row.
   Override the default td-grid (which is set to 4-col above). */
.td-grid-3{grid-template-columns:repeat(3, 1fr);}
@media (max-width: 900px){
  .td-grid-3{grid-template-columns:repeat(2, 1fr);}
}
@media (max-width: 520px){
  .td-grid-3{grid-template-columns:1fr;}
}

/* ═══════════════════════════════════════════════════════════════════════
   DESIGN REFRESH — Jul 2026
   Cross-cutting rhythm + mobile shell + /reports rewrite.
   Signature: section rules with baked-in uppercase labels ("chapter heads")
   plus editorial numbers. Cream palette + navy accent preserved verbatim.
   ═══════════════════════════════════════════════════════════════════════ */

:root{
  /* Rule that has enough presence to read as a chapter break — a
     darker warm-ink derivative, not the softer .line variable which
     stays for card borders where hairlines shouldn't shout. */
  --rule:rgba(28,30,34,.28);            /* bumped from .16 — read as chapter break */
  --rule-strong:rgba(28,30,34,.55);     /* NEW: the accent bar in section-head::before */
  --rule-soft:rgba(28,30,34,.08);
  /* Rhythm tokens for consistent vertical spacing site-wide */
  --stack-lg:56px;                       /* bumped from 40px — space between chapters */
  --stack-md:24px;
  --stack-sm:12px;
}

/* ── Content width: narrower for readability. Reports especially benefits
   from a document-width column (~900px) rather than dashboard-width. */
.content{max-width:900px;}
/* Pages that legitimately need the wider dashboard viewport
   (admin tenant list, integrations table) opt in with .content-wide */
.content-wide{max-width:1400px;}

/* ── Base type refinement — one step more editorial without swapping faces */
body{font-size:15px;}
h1{font-size:1.75rem; font-weight:650; letter-spacing:-.02em;}
h2{font-size:1.05rem; font-weight:650;}
.eyebrow{
  display:block;
  font-size:11px; font-weight:600; text-transform:uppercase;
  letter-spacing:.09em; color:var(--muted);
  margin:0 0 6px 0;}

/* ── Mobile shell — fixed top bar + off-canvas drawer for the sidebar ── */
.mobile-top{display:none;}          /* revealed at <900px only */
.drawer-scrim{display:none;}
@media (max-width: 900px){
  html,body{overflow-x:hidden;}
  .shell{flex-direction:column;}
  .sidebar{
    position:fixed; top:0; left:0; z-index:60;
    height:100vh; height:100dvh; width:min(280px, 84vw);
    transform:translateX(-100%);
    transition:transform 220ms cubic-bezier(.2,.7,.2,1);
    padding-top:64px;
    box-shadow:0 0 24px rgba(0,0,0,.06);}
  body.drawer-open .sidebar{transform:translateX(0);}
  body.drawer-open .drawer-scrim{
    display:block; position:fixed; inset:0; z-index:50;
    background:rgba(0,0,0,.28); backdrop-filter:blur(1.5px);}
  .content{padding:76px 22px 40px 22px;}
  .content-wide{padding:76px 16px 40px 16px;}
  .mobile-top{
    display:flex; align-items:center; justify-content:space-between;
    position:fixed; top:0; left:0; right:0; z-index:55;
    height:56px; padding:0 14px;
    background:rgba(245,243,236,.94);
    backdrop-filter:saturate(1.4) blur(10px);
    -webkit-backdrop-filter:saturate(1.4) blur(10px);
    border-bottom:1px solid var(--line);}
  .mobile-top .brand a{font-size:1.15rem;}
  .mobile-top-actions{display:flex; gap:8px; align-items:center;}
  .hamburger{
    width:40px; height:40px; display:flex; align-items:center;
    justify-content:center; border:1px solid var(--line);
    background:var(--panel); border-radius:8px; cursor:pointer;
    color:var(--ink);}
  .hamburger:focus-visible{outline:2px solid var(--accent); outline-offset:2px;}
  .hamburger svg{display:block;}
  .impersonate-banner{margin-top:56px;}
}

/* ── Page top bar — used on /reports for eyebrow / title / primary action.
   On desktop it sits at the top of the content. On mobile it's absorbed
   into the fixed .mobile-top. */
.page-top{
  display:flex; align-items:flex-end; justify-content:space-between;
  gap:16px; flex-wrap:wrap;
  margin:0 0 var(--stack-md);
  padding-bottom:0;}
.page-top-title h1{margin:0; line-height:1.15;}
.page-top-title .eyebrow{margin-bottom:6px;}
.page-top-meta{
  display:flex; gap:10px; align-items:center; flex-wrap:wrap;
  color:var(--muted); font-size:.9rem;
  margin-top:4px;}
.page-top-actions{
  display:flex; gap:8px; align-items:center; flex-wrap:wrap;}
@media (max-width: 640px){
  .page-top{gap:12px;}
  .page-top-actions{width:100%;}
}

/* ── SECTION RULE — the signature.
   Horizontal hairline with an inline uppercase label at the left,
   optional actions floating right. The rule visually crosses the label,
   creating the print "chapter break" feel. */
.section{
  /* Hairline break — a single subtle rule. The heavy 3px slab was
     the primary source of the "colors look heavy" feedback. Chapters
     are still legible via the label + generous top padding, but the
     visual weight is airy now. */
  margin:var(--stack-lg) 0 0 0;
  padding-top:var(--stack-md);
  border-top:1px solid var(--line);}
.section:first-of-type{
  margin-top:var(--stack-md);
  border-top:none; padding-top:0;}
.section-head{
  display:flex; align-items:baseline; gap:14px;
  padding-bottom:14px;
  border-bottom:1px solid var(--line);
  margin-bottom:24px;
  position:relative;}
.section-head::before{
  /* No accent bar — the label alone marks the chapter. Cleaner. */
  content:none;}
.section-head-label{
  flex:1;
  font-size:11px; font-weight:600;
  text-transform:uppercase; letter-spacing:.16em;
  color:var(--ink);}
.section-head-meta{
  font-size:12px; letter-spacing:.02em; color:var(--muted);
  font-weight:400; text-transform:none;
  margin-left:8px;}
.section-head-actions{
  display:flex; gap:10px; align-items:center; flex-wrap:wrap;
  font-size:13px;}
.section-head-actions a{
  color:var(--muted); font-weight:500;}
.section-head-actions a:hover{color:var(--ink); text-decoration:none;}
/* Filled buttons in a section head keep their #fff text — without these
   overrides the ".section-head-actions a" rule above cascades muted
   gray onto navy-fill .btn links (what made "Download PDF" unreadable). */
.section-head-actions a.btn,
.section-head-actions a.btn:link,
.section-head-actions a.btn:visited{color:#fff;}
.section-head-actions a.btn:hover{color:#fff;}
.section-head-actions a.btn.ghost,
.section-head-actions a.btn.ghost:link,
.section-head-actions a.btn.ghost:visited{color:var(--ink);}
.section-head-actions .btn{font-size:.82rem; padding:6px 12px;}
@media (max-width: 640px){
  .section{margin-top:32px;}
  .section-head{flex-wrap:wrap; gap:8px;}
  .section-head-actions{width:100%; padding-top:4px;}
}

/* ── STACK — vertical list of items with hairline dividers.
   The default row unit for sources, past reports, campaigns. */
.stack{list-style:none; margin:0; padding:0;}
.stack > li,
.stack > .item{
  display:flex; align-items:flex-start; justify-content:space-between;
  gap:16px; padding:14px 0;
  border-bottom:1px solid var(--rule-soft);}
.stack > li:last-child,
.stack > .item:last-child{border-bottom:none;}
.item-body{flex:1; min-width:0;}
.item-title{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  color:var(--ink); font-weight:600; line-height:1.35;}
.item-meta{
  color:var(--muted); font-size:.86rem; margin-top:3px;
  line-height:1.5;}
.item-actions{
  display:flex; gap:6px; align-items:center; flex-wrap:wrap;
  flex-shrink:0;}
@media (max-width: 640px){
  .stack > li, .stack > .item{
    flex-wrap:wrap;}
  .item-actions{width:100%; padding-top:2px;}
}

/* Source marker — a small colored square before the title.
   Encodes provider identity without an icon library. */
.marker{
  display:inline-flex; align-items:center; justify-content:center;
  width:24px; height:24px; border-radius:5px;
  font-size:9px; font-weight:700; letter-spacing:.02em;
  color:var(--ink);
  background:var(--panel2); border:1px solid var(--line);
  flex-shrink:0;
  text-transform:uppercase;}
.marker.ghl{background:#e6f4ef; color:#0d7a52; border-color:#c4e6d6;}
.marker.meta{background:#eaf0ff; color:#1e40af; border-color:#c8d5f5;}
.marker.google{background:#fef2ec; color:#b6431a; border-color:#f5d0bd;}
/* Logo marker — larger square that hosts a full-color provider SVG.
   Replaces the text badge in Connections rows so the eye reads the
   provider by brand mark, not by a 3-letter abbreviation. */
.marker.marker-logo{
  width:34px; height:34px; border-radius:8px;
  background:var(--panel); border:1px solid var(--line);
  padding:4px;}
.marker.marker-logo svg{display:block; width:100%; height:100%;}

/* ── HERO — a single "top of the report" module.
   Big numbers with editorial labels. Sits below the page-top and above
   the first section. On mobile, wraps to a stack. */
.rep-hero{
  display:grid;
  grid-template-columns:auto 1fr auto;
  gap:32px; align-items:end;
  padding:12px 0 26px 0;
  border-bottom:1px solid var(--rule);
  margin-bottom:0;}
.rep-hero-period{
  font-size:15px; color:var(--ink); font-weight:600;}
.rep-hero-period-note{
  color:var(--muted); font-size:12px;
  text-transform:uppercase; letter-spacing:.08em; font-weight:600;
  margin-bottom:4px;}
.rep-hero-num{
  font-size:44px; font-weight:700; line-height:1;
  letter-spacing:-.02em; color:var(--ink);
  font-variant-numeric:tabular-nums;}
.rep-hero-num-label{
  font-size:11px; text-transform:uppercase; letter-spacing:.09em;
  color:var(--muted); font-weight:600; margin-top:8px;}
@media (max-width: 640px){
  .rep-hero{
    grid-template-columns:1fr; gap:16px;
    padding:8px 0 20px 0;}
  .rep-hero-num{font-size:32px;}
}

/* ── EMBEDDED report — the rendered HTML dropped into the page.
   Fits the page naturally: NO independent horizontal scroll (was
   overflow-x:auto — that gave the report its own scrollbar which
   read as "a widget inside the page" rather than "part of the
   page"). Wide internal blocks (tables, campaign breakdowns) fit
   themselves via .report-scope + @media rules below. */
.rep-embed{
  margin:18px 0 0 0;}
.rep-embed .report-scope{max-width:100%;}
/* Report tables/grids stay inside their column. Any wide table gets
   its OWN local scroll shell so the outer report doesn't horizontal
   scroll — only that specific table scrolls when the data won't fit. */
.rep-embed .report-scope table{
  max-width:100%;
  display:block; overflow-x:auto;
  -webkit-overflow-scrolling:touch;}
.rep-embed .report-scope > *:not(table){max-width:100%;}
@media (max-width: 640px){
  .rep-embed{margin-left:-6px; margin-right:-6px;}
}

/* ── CHANNEL glance strip — Meta / Google at-a-glance.
   Small labels + big numbers, laid horizontally. Compact, honest. */
.glance{
  display:grid;
  grid-template-columns:repeat(6, minmax(0, 1fr));
  gap:20px 24px;
  padding:6px 0 4px 0;}
.glance-cell-label{
  font-size:11px; text-transform:uppercase; letter-spacing:.08em;
  color:var(--muted); font-weight:600;
  margin-bottom:4px;}
.glance-cell-value{
  font-size:22px; font-weight:700; line-height:1.1;
  color:var(--ink); font-variant-numeric:tabular-nums;
  letter-spacing:-.01em;}
.glance-cell-sub{
  display:block; font-size:11px; color:var(--muted);
  font-weight:500; letter-spacing:0; text-transform:none;
  margin-top:2px;}
@media (max-width: 900px){
  .glance{grid-template-columns:repeat(3, minmax(0, 1fr));}
}
@media (max-width: 440px){
  .glance{grid-template-columns:repeat(2, minmax(0, 1fr));}
}
.glance-top{
  margin-top:18px; padding-top:14px; border-top:1px solid var(--rule-soft);}
.glance-top h4{
  margin:0 0 8px 0;
  font-size:11px; text-transform:uppercase; letter-spacing:.09em;
  color:var(--muted); font-weight:600;}
.glance-top ol{
  list-style:none; margin:0; padding:0;
  display:flex; flex-direction:column; gap:6px;}
.glance-top li{
  display:flex; justify-content:space-between; gap:12px;
  align-items:baseline;
  font-size:14px;}
.glance-top li .tc-name{
  color:var(--ink); font-weight:500;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  min-width:0; flex:1;}
.glance-top li .tc-meta{
  color:var(--muted); font-size:12px;
  font-variant-numeric:tabular-nums; flex-shrink:0;
  white-space:nowrap;}

/* Range pill selector for the glance strip. Compact + inline. */
.range-pills{
  display:inline-flex; gap:4px; align-items:center;
  padding:2px; background:var(--panel2); border-radius:8px;
  border:1px solid var(--line);}
.range-pills button,
.range-pills .range-pill{
  border:none; background:transparent; color:var(--muted);
  padding:4px 10px; font-size:12px; font-weight:600;
  border-radius:6px; cursor:pointer; font-family:inherit;
  letter-spacing:.02em; line-height:1;}
.range-pills button:hover{color:var(--ink);}
.range-pills button.active{background:var(--ink); color:var(--panel);}
.range-pills input[type=number]{
  width:44px; padding:4px 6px; font-size:12px;
  border:1px solid var(--line); border-radius:6px;
  background:var(--panel); text-align:center;
  font-family:ui-monospace,Menlo,monospace;}
.range-pills-label{
  font-size:11px; color:var(--muted); letter-spacing:.02em;}

/* Empty / loading states used inside sections (no card frame) */
.section-empty{
  padding:14px 0 4px 0; color:var(--muted); font-size:14px;}
.section-loading{
  padding:14px 0 4px 0; color:var(--muted); font-size:13px;
  letter-spacing:.02em;}

/* ── REPORT SELECTOR (top-of-page). A small dropdown chip that shows the
   active report name; clicking opens a menu with all reports + "New". */
.rep-selector{position:relative;}
.rep-selector summary{
  cursor:pointer; list-style:none;
  display:inline-flex; align-items:center; gap:6px;
  padding:6px 12px 6px 14px;
  background:var(--panel); border:1px solid var(--line);
  border-radius:100px; font-size:13px; font-weight:600;
  color:var(--ink);}
.rep-selector summary::-webkit-details-marker{display:none;}
.rep-selector summary::after{
  content:"▾"; font-size:10px; color:var(--muted); margin-left:2px;}
.rep-selector summary:hover{border-color:var(--ink);}
.rep-selector[open] summary{border-color:var(--accent);
  background:var(--panel2);}
.rep-selector-menu{
  position:absolute; top:calc(100% + 6px); left:0; z-index:20;
  min-width:240px; padding:6px;
  background:var(--panel); border:1px solid var(--line);
  border-radius:10px;
  box-shadow:0 6px 24px rgba(0,0,0,.10);}
.rep-selector-menu a,
.rep-selector-menu button{
  display:block; width:100%; text-align:left;
  padding:8px 10px; border-radius:6px;
  color:var(--ink); text-decoration:none;
  background:none; border:none; cursor:pointer;
  font-family:inherit; font-size:14px;}
.rep-selector-menu a:hover,
.rep-selector-menu button:hover{background:var(--panel2);}
.rep-selector-menu a.current{background:var(--panel2); font-weight:600;}
.rep-selector-menu form{
  padding:6px; border-top:1px solid var(--line); margin-top:4px;}
.rep-selector-menu form input{margin-bottom:6px;}

/* ── GENERATE modal — replaces the collapsible generate form.
   Opens over a scrim; keyboard-friendly. */
.gen-modal{
  display:none;
  position:fixed; inset:0; z-index:80;
  background:rgba(28,30,34,.42);
  align-items:flex-start; justify-content:center;
  padding:60px 16px;
  overflow-y:auto;}
.gen-modal.open{display:flex;}
.gen-modal-inner{
  width:100%; max-width:560px;
  background:var(--panel); border-radius:12px;
  border:1px solid var(--line);
  padding:24px 26px; position:relative;}
.gen-modal-close{
  position:absolute; top:14px; right:14px;
  width:32px; height:32px;
  background:transparent; border:none;
  font-size:20px; line-height:1; color:var(--muted);
  cursor:pointer; border-radius:6px;}
.gen-modal-close:hover{background:var(--panel2); color:var(--ink);}
/* Reserve room on the right so the close X never overlaps the h3/h2
   titles even at their longest ("Regenerate report" / "Pick a window & run it"). */
.gen-modal h3{
  margin:0 0 6px 0; padding-right:40px;
  font-size:12px; text-transform:uppercase; letter-spacing:.10em;
  color:var(--muted); font-weight:700;}
.gen-modal h2{margin:0 0 20px 0; padding-right:40px; font-size:22px; line-height:1.25;}
@media (max-width: 640px){
  .gen-modal{padding:12px;}
  .gen-modal-inner{padding:20px 18px;}
}

/* ── SETTINGS modal — unified replacement for the old bottom drawer
   + the transient Options modal. Sections stack vertically with a
   hairline between; each has an eyebrow label, its own form, and its
   own Save button. The modal grows tall as needed and scrolls
   internally on short viewports. */
.settings-modal{max-width:600px;}
.settings-section{
  margin:24px 0 0 0;
  padding:22px 0 0 0;
  border-top:1px solid var(--rule);}
.settings-section:first-of-type{
  margin-top:12px; padding-top:6px; border-top:none;}
.settings-section-head{
  display:flex; flex-direction:column; gap:2px;
  margin-bottom:16px;}
.settings-eyebrow{
  font-size:11px; font-weight:700;
  text-transform:uppercase; letter-spacing:.10em;
  color:var(--ink);}
.settings-hint{
  color:var(--muted); font-size:12.5px; letter-spacing:.01em;}
.settings-label{
  display:block; margin-bottom:8px;
  font-size:11px; text-transform:uppercase; letter-spacing:.08em;
  color:var(--muted); font-weight:600;}
.settings-label-note{
  display:block; margin-top:4px;
  text-transform:none; letter-spacing:0; font-weight:400;
  color:var(--muted); font-size:12px;}
.settings-actions{
  display:flex; justify-content:flex-end; align-items:center;
  gap:10px; margin-top:20px;}
.settings-section-identity{border-top:1px solid var(--rule);}

/* Old bottom drawer — no longer rendered but keep the class in case
   external links still reference it. Kept minimal so it doesn't fight
   the modal's styling. */
.rep-settings{margin-top:var(--stack-lg);}
.rep-settings summary{
  cursor:pointer; list-style:none;
  display:inline-flex; align-items:center; gap:6px;
  font-size:12px; text-transform:uppercase; letter-spacing:.08em;
  color:var(--muted); font-weight:600;
  padding:8px 0;}
.rep-settings summary::-webkit-details-marker{display:none;}
.rep-settings summary::before{
  content:"› "; color:var(--muted);
  transition:transform .12s ease; display:inline-block;}
.rep-settings[open] summary::before{transform:rotate(90deg);}
.rep-settings summary:hover{color:var(--ink);}
.rep-settings-body{padding:16px 0 8px 0;}
.rep-settings-body .field label{
  font-size:11px; text-transform:uppercase; letter-spacing:.08em;
  color:var(--muted); font-weight:600;}

/* ── ADD SOURCE — inline, no more card-wrapping. */
.add-source-inline{margin-top:16px; padding-top:16px;
  border-top:1px dashed var(--rule-soft);}
.add-source-inline > summary{
  cursor:pointer; list-style:none;
  display:inline-flex; align-items:center; gap:8px;
  color:var(--muted); font-size:13px; font-weight:600;
  padding:4px 0;}
.add-source-inline > summary::-webkit-details-marker{display:none;}
.add-source-inline > summary::before{content:"+"; font-size:18px;
  line-height:1; margin-right:2px; font-weight:400;}
.add-source-inline > summary:hover{color:var(--ink);}
.add-source-inline[open] > summary::before{content:"−";}
.add-source-inline-body{
  padding-top:14px;
  display:grid; gap:22px;
  grid-template-columns:1fr 1fr;}
@media (max-width: 720px){
  .add-source-inline-body{grid-template-columns:1fr;}
}
.add-source-inline-body h4{
  font-size:13px; margin:0 0 4px 0;
  text-transform:uppercase; letter-spacing:.06em;
  color:var(--muted); font-weight:700;}
.add-source-inline-body p{margin:0 0 10px 0; color:var(--muted);
  font-size:13px; line-height:1.5;}

/* ── PAST reports — a compact list, not a card */
.past-list{list-style:none; margin:0; padding:0;}
.past-list li{
  display:grid;
  grid-template-columns:1fr auto;
  gap:12px 20px; align-items:baseline;
  padding:12px 0;
  border-bottom:1px solid var(--rule-soft);}
.past-list li:last-child{border-bottom:none;}
.past-list-when{
  font-size:14px; color:var(--ink); font-weight:600;
  font-variant-numeric:tabular-nums;}
.past-list-meta{
  color:var(--muted); font-size:12px; margin-top:2px;
  letter-spacing:.02em;}
.past-list-actions{
  display:flex; gap:12px; align-items:center;
  font-size:13px;}
.past-list-actions a{color:var(--muted); font-weight:500;}
.past-list-actions a:hover{color:var(--ink); text-decoration:none;}
.past-list-actions a.danger:hover{color:var(--err);}
@media (max-width: 640px){
  .past-list li{grid-template-columns:1fr;}
  .past-list-actions{padding-top:2px;}
}

/* Icon-only action buttons — 30×30 squares that fit tightly in .item-actions
   without wrapping. Ghost by default; danger variant shows red on hover.
   Native <button> and <a> both share the same look. */
.icon-btn{
  display:inline-flex; align-items:center; justify-content:center;
  width:30px; height:30px; padding:0;
  background:transparent; color:var(--muted);
  border:1px solid var(--line); border-radius:7px;
  cursor:pointer; font-family:inherit; line-height:1;
  transition:background .12s ease, color .12s ease, border-color .12s ease;
  text-decoration:none; flex-shrink:0;}
.icon-btn:hover{
  background:var(--panel2); color:var(--ink);
  border-color:var(--rule); text-decoration:none;}
.icon-btn:focus-visible{
  outline:2px solid var(--accent); outline-offset:2px;}
.icon-btn svg{display:block;}
/* Danger variant — red on hover only, so the row doesn't look alarmed
   at rest. */
.icon-btn.danger:hover{
  color:var(--err); border-color:#d6a7a3; background:#fbeeeb;}
/* Bump the tap target to 36×36 on touch-primary viewports so it clears
   Apple's HIG minimum. Two triggers: narrow viewports (phones held
   portrait) AND any device that reports coarse pointer as primary
   (tablets, Chromebook touchscreens, hybrid laptops in tablet mode).
   The coarse-pointer variant catches iPad landscape + touchscreen
   laptops that don't hit the 640px width breakpoint but still need
   larger targets under WCAG 2.5.5 / Apple HIG. */
@media (max-width: 640px), (pointer: coarse){
  .icon-btn{width:34px; height:34px;}
}

/* Also ensure item-actions gap is comfortable when icon-only. */
.item-actions{gap:6px;}

/* Landing footer — legal links row. Compact, quiet, below the site copy. */
.lp-foot-legal{
  display:flex; gap:22px; flex-wrap:wrap;
  margin:14px 0 6px 0;
  font-size:13px;}
.lp-foot-legal a{
  color:var(--muted); text-decoration:none;
  transition:color .12s ease;}
.lp-foot-legal a:hover{color:var(--ink); text-decoration:none;}
@media (max-width: 640px){
  .lp-foot-legal{gap:16px 20px;}
}

/* ── Embedded report content — make its own blocks reflow on narrow.
   The report engine's HTML uses tables + grids that were sized for
   Letter-paper output. When the .report-scope wrapper is narrower than
   ~640px, force those internal blocks to stack instead of shrinking
   further or overflowing horizontally. */
@media (max-width: 720px){
  .rep-embed .report-scope table{font-size:12px;}
  .rep-embed .report-scope .roi-grid,
  .rep-embed .report-scope .kpi-grid,
  .rep-embed .report-scope .cadence-grid{
    grid-template-columns:1fr !important;}
  /* Two-column blocks in the report (e.g. hourly + weekday) become
     stacked. */
  .rep-embed .report-scope div[style*="display:grid"]{
    grid-template-columns:1fr !important;}
  .rep-embed .report-scope div[style*="display: grid"]{
    grid-template-columns:1fr !important;}
  /* Long campaign name in a table cell wraps rather than clipping. */
  .rep-embed .report-scope td,
  .rep-embed .report-scope th{
    word-break:break-word;}
}

/* ── AD-BREAK — the hard visual divider between the core monthly
   report and the "Meta ad campaigns" / "Google ad campaigns" tables.
   Duplicated here (also lives in monthly_report.html.j2) so it renders
   on old saved reports whose original <style> block predates the
   divider — the /reports embed layer injects the div at read time. */
.rep-embed .ad-break{
  margin:52px 0 26px 0;
  padding:22px 20px 20px 20px;
  border-top:3px solid var(--ink);
  border-bottom:1px solid var(--rule);
  background:var(--panel2);
  display:flex; align-items:baseline; gap:14px;
  flex-wrap:wrap;
  break-before:page; page-break-before:always;}
.rep-embed .ad-break-label{
  font-size:13px; font-weight:700;
  letter-spacing:.14em; text-transform:uppercase;
  color:var(--ink);}
.rep-embed .ad-break-sub{
  font-size:12px; color:var(--muted);
  letter-spacing:.02em;}
.rep-embed .ad-break + h2{margin-top:8px !important;}

/* ── Global site footer inside .content — legal links + copyright. */
.site-foot{
  margin-top:60px; padding:20px 0 8px 0;
  border-top:1px solid var(--rule-soft);
  display:flex; justify-content:space-between; align-items:center;
  gap:14px; flex-wrap:wrap;
  /* Iter 298: --ink-2 (#3d424b) instead of --muted (#6b7280) at
     12.5px so footer meets WCAG AA. --muted on white gives ~4.9:1
     which barely passes small-text AA (4.5); --ink-2 gives ~9:1
     and clears AAA too. WAIM flagged the prior shade as low
     contrast. */
  color:var(--ink-2); font-size:12.5px;}
.site-foot nav{
  display:flex; align-items:center; gap:12px; flex-wrap:wrap;}
.site-foot nav a{
  /* Same darkening as the container — link color needs to pass AA
     at the same 12.5px size. */
  color:var(--ink-2); text-decoration:none;
  transition:color .12s ease;}
.site-foot nav a:hover{color:var(--ink); text-decoration:none;}
/* Separator between legal links. Rendered as a CSS pseudo-element
   instead of an aria-hidden <span> so it never enters the a11y tree
   at all — WAIM was flagging the a11y-tree pattern
   [link, aria-hidden, link] as suspicious. Pseudo-elements are
   invisible to screen readers by default; no aria attributes needed. */
.site-foot nav a + a::before{
  content:"·"; margin-right:12px; color:var(--rule); }
@media (max-width: 640px){
  .site-foot{flex-direction:column; align-items:flex-start; gap:8px;}
}

/* ── Public (anonymous) shell — used by legal pages, 404, and any other
   page that needs a slim top nav + centered content + footer when the
   viewer isn't signed in. Landing / login override {% block bare %}
   directly and bypass this. */
.public-shell{
  display:flex; flex-direction:column;
  min-height:100vh; min-height:100dvh;}
.public-top{
  display:flex; align-items:center; justify-content:space-between;
  padding:16px 26px;
  border-bottom:1px solid var(--rule-soft);
  background:var(--bg);}
.public-top .brand a{font-size:20px; font-weight:750;
  color:var(--ink); letter-spacing:-.02em; text-decoration:none;}
.public-top .brand span{color:var(--accent);}
.public-top-nav{
  display:flex; gap:22px; align-items:center;
  font-size:14px;}
.public-top-nav a{
  color:var(--muted); text-decoration:none;}
.public-top-nav a:hover{color:var(--ink); text-decoration:none;}
.public-top-nav a.btn{color:#fff;}
.public-top-nav a.btn:hover{color:#fff;}
.public-content{
  flex:1;
  max-width:800px; width:100%;
  margin:0 auto; padding:40px 26px 60px 26px;}
.public-foot{
  border-top:1px solid var(--rule-soft);
  padding:20px 26px 30px 26px;
  margin-top:0; max-width:none; width:100%;
  border-radius:0; background:transparent;}
@media (max-width: 640px){
  .public-top{padding:12px 18px; gap:12px;}
  .public-top-nav{gap:14px; font-size:13px;}
  .public-content{padding:28px 18px 40px 18px;}
  .public-foot{padding:18px 18px 24px 18px;}
}

/* Provider logo — a small colored mark inside connect card <h4> headings
   and next to labels. Keeps brand recognition without being loud. */
.provider-logo{
  display:inline-block; vertical-align:-4px; margin-right:8px;
  flex-shrink:0;}
.add-source-inline-body h4{
  display:flex; align-items:center; gap:0;
  color:var(--ink); font-weight:700;}
.add-source-inline-body h4 .provider-logo{margin-right:8px;}
.add-source-inline-body h4 .badge{margin-left:8px;}

/* Connect button — logo left, text right, filled navy with white content */
.connect-btn{
  display:inline-flex; align-items:center; gap:8px;
  padding-left:12px; padding-right:14px;}
.connect-btn svg{display:block;}

/* Section spacing on /reports: bump the between-chapter gap so the new
   3px top rules land with air rather than a stripe abutting the prior
   content. */
.rep-embed + .section,
.glance + .section,
.section .section{margin-top:56px;}

/* ── Channels band — the "here ends the report" divider.
   A short accent-blue horizontal bar with an inline label breaking
   into it. Rests between the main-report section and the first
   channel glance. Reads as a hard transition: main content ends,
   supplementary channel dashboards begin. */
.channels-band{
  display:flex; align-items:center; gap:14px;
  margin:80px 0 32px 0;
  padding:0;}
.channels-band::before,
.channels-band::after{
  content:""; height:1px; background:var(--ink); flex:1;}
.channels-band::before{max-width:64px;}
.channels-band-label{
  flex-shrink:0;
  font-size:11px; font-weight:700;
  text-transform:uppercase; letter-spacing:.14em;
  color:var(--ink);}
@media (max-width: 640px){
  .channels-band{margin:56px 0 24px 0;}
}
/* Cancel the section top-rule for the first channel section since the
   band already provides the visual break — otherwise they'd stack. */
.channels-band + .section{
  margin-top:0; border-top:none; padding-top:0;}

/* Link button — a plain-text button styled to match the anchor links
   in section-head-actions. Used for the Refresh action; behaves as
   a form submit without looking like a hard CTA. */
.section-head-actions .link-btn,
.link-btn{
  background:none; border:none; padding:0;
  color:var(--muted); font:inherit; font-weight:500; font-size:13px;
  cursor:pointer; display:inline-flex; align-items:center;
  font-family:inherit;}
.section-head-actions .link-btn:hover,
.link-btn:hover{color:var(--ink); text-decoration:none;}

/* Main-report section — inherits .section:first-of-type's no-top-rule
   treatment. The page-top ABOVE this section IS its head; a "Latest
   report" section-head would just be redundant framing.
   `.no-head` variant used when we want a section chapter with no head
   at all — cancels the padding that the section-head would have
   provided, so the content flows in tight to the page-top. */
.section.main-report{padding-top:0;}
.section.no-head{padding-top:0;}
.section.main-report .rep-embed,
.section.no-head .rep-embed{margin-top:0;}

/* ── AUDIT — filters + table for /admin/audit. Row layout with a
   compact grid of filter inputs, and a wide table below. */
.audit-filters{
  display:grid; gap:12px 16px;
  grid-template-columns:repeat(3, minmax(0, 1fr));
  align-items:end;}
.audit-filters .field{margin:0;}
.audit-filters .field label{
  display:block; margin-bottom:4px;
  font-size:11px; text-transform:uppercase; letter-spacing:.08em;
  color:var(--muted); font-weight:600;}
.audit-filters .field input,
.audit-filters .field select{width:100%;}
.audit-filter-actions{
  display:flex; gap:8px; align-items:end;
  grid-column:span 3; padding-top:8px;
  border-top:1px solid var(--rule-soft);}
.audit-table{
  width:100%; border-collapse:collapse;
  font-size:12.5px;}
.audit-table th{
  text-align:left; padding:8px 10px;
  font-size:11px; text-transform:uppercase; letter-spacing:.08em;
  color:var(--muted); font-weight:600;
  border-bottom:1px solid var(--rule);}
.audit-table td{
  padding:8px 10px; vertical-align:top;
  border-bottom:1px solid var(--rule-soft);}
.audit-table td.nowrap{white-space:nowrap;}
.audit-table pre{
  font-family:ui-monospace,Menlo,monospace;
  font-size:11px; color:var(--ink);}
@media (max-width: 900px){
  .audit-filters{grid-template-columns:1fr 1fr;}
  .audit-filter-actions{grid-column:span 2;}
}
@media (max-width: 640px){
  .audit-filters{grid-template-columns:1fr;}
  .audit-filter-actions{grid-column:span 1;}
}

/* ── PLATFORM NAV — quick jump strip at the top of /admin/platform.
   Anchors to each section so a super admin can skip long scrolls. */
.platform-nav{
  display:flex; flex-wrap:wrap; gap:2px;
  margin:0 0 24px 0;
  padding:0;
  border-bottom:1px solid var(--line);}
.platform-nav a{
  padding:10px 14px;
  border:0;
  border-bottom:2px solid transparent;
  margin-bottom:-1px;
  color:var(--muted); font-size:13px; font-weight:500;
  letter-spacing:-.005em;
  text-decoration:none;
  transition:color .12s ease, border-color .12s ease;}
.platform-nav a:hover{
  color:var(--ink);
  border-bottom-color:var(--line-strong);}
/* Make anchor targets land nicely below the top nav. */
#billing, #email, #ads, #reports, #tenant-defaults, #notifications{
  scroll-margin-top:20px;}

/* ── PICKER TOOLBAR — Select all / Clear all + running count.
   Used by all three source pickers (GHL calendars, Meta campaigns,
   Google Ads campaigns). Sits between the intro paragraph and the
   checkbox list. */
.picker-toolbar{
  display:flex; gap:8px; align-items:center;
  padding:0 0 16px 0;
  margin-bottom:4px;
  border-bottom:1px solid var(--line);
  flex-wrap:wrap;}
.picker-count{
  font-size:12px; color:var(--muted);
  letter-spacing:.02em; font-variant-numeric:tabular-nums;
  margin-left:auto;}
@media (max-width: 640px){
  .picker-count{margin-left:0; width:100%; padding-top:4px;}
}

/* ── REPORT-EMPTY — the same-shape empty state that replaces the
   report body when there's no data yet. Same width, same rhythm as
   a rendered report so the tab-to-tab jump feels consistent. */
.section.report-empty{
  padding-top:0; border-top:0;}
.report-empty-inner{
  padding:56px 0 44px 0;
  max-width:640px;}
.report-empty-inner h2{
  font-size:1.75rem; font-weight:500; letter-spacing:-.025em;
  line-height:1.2;}
@media (max-width: 640px){
  .report-empty-inner{padding:40px 0 32px 0;}
  .report-empty-inner h2{font-size:1.4rem;}
}

/* ── KPI MANAGE — the "add custom KPI" panel on /reports/{id}.
   Compact list of existing tiles + "Add" button in the section head.
   Not the builder itself — links out to that. */
.kpi-manage-empty{
  color:var(--muted); font-size:14px;
  line-height:1.6; max-width:640px;
  margin:0 0 4px 0;}
.kpi-manage-list{
  list-style:none; margin:0; padding:0;
  display:flex; flex-direction:column; gap:0;}
.kpi-manage-list li{
  display:flex; align-items:baseline; justify-content:space-between;
  padding:12px 0;
  border-bottom:1px solid var(--rule);
  gap:12px;}
.kpi-manage-list li:last-child{border-bottom:0;}
.kpi-manage-list li a{
  color:var(--ink); border-bottom:0;
  font-weight:500; font-size:15px;
  letter-spacing:-.01em;}
.kpi-manage-list li a:hover{
  text-decoration:underline; text-underline-offset:3px;
  text-decoration-color:var(--line-strong);}
.kpi-manage-type{
  font-size:11px; text-transform:uppercase; letter-spacing:.14em;
  color:var(--muted); font-weight:600;}

/* ── KPI EXPRESSION BUILDER — text-first formula editor. Textarea for
   the raw expression + a horizontal chip row of ops + a collapsible
   metric reference below. Live preview shows the parsed AST as it's
   typed; parse errors surface inline. */
.kpi-expr-input{
  width:100%;
  padding:12px 14px;
  font-family:ui-monospace,Menlo,Consolas,monospace;
  font-size:14px; line-height:1.55;
  border:1px solid var(--line-strong); border-radius:6px;
  background:var(--panel); color:var(--ink);
  resize:vertical; min-height:72px;
  transition:border-color .12s ease;}
.kpi-expr-input:focus{
  outline:none; border-color:var(--ink);}
.kpi-expr-input:focus-visible{
  box-shadow:0 0 0 3px rgba(22,106,84,.22);
  border-color:var(--ledger,#166A54);}
.kpi-hint-toolbar{
  display:flex; gap:6px; flex-wrap:wrap;
  margin-top:8px;}
.kpi-op-chip{
  padding:6px 12px; min-width:36px;
  border:1px solid var(--line-strong); border-radius:6px;
  background:var(--panel); color:var(--ink);
  cursor:pointer; font-family:ui-monospace,Menlo,monospace;
  font-size:14px; font-weight:600;
  transition:border-color .12s ease, background .12s ease;}
.kpi-op-chip:hover{border-color:var(--ink);}
.kpi-preview-label{
  font-size:11px; text-transform:uppercase; letter-spacing:.14em;
  color:var(--muted); font-weight:600; margin-right:8px;}
.kpi-preview code.kpi-preview-error{
  color:var(--err); background:transparent;}
.kpi-metrics-ref summary{
  cursor:pointer; padding:6px 0;
  font-size:11px; text-transform:uppercase; letter-spacing:.14em;
  color:var(--muted); font-weight:600;
  list-style:none;}
.kpi-metrics-ref summary::-webkit-details-marker{display:none;}
.kpi-metrics-ref summary::before{content:"› "; color:var(--muted);}
.kpi-metrics-ref[open] summary::before{content:"▾ ";}
.kpi-metrics-ref-grid{
  display:grid; gap:6px;
  grid-template-columns:repeat(auto-fill, minmax(220px, 1fr));
  margin-top:12px; padding:14px;
  background:var(--panel2);
  border:1px solid var(--line); border-radius:6px;}
.kpi-metric-chip{
  display:flex; flex-direction:column; align-items:flex-start;
  padding:8px 10px; gap:2px;
  border:1px solid var(--line); border-radius:6px;
  background:var(--panel); color:var(--ink);
  cursor:pointer; text-align:left;
  font-family:inherit;
  transition:border-color .12s ease;}
.kpi-metric-chip:hover{border-color:var(--ink);}
.kpi-metric-label{
  font-size:12px; font-weight:500; color:var(--ink);}
.kpi-metric-key{
  font-size:11px; font-family:ui-monospace,Menlo,monospace;
  color:var(--muted); letter-spacing:0;}

/* Starter formulas — pre-built KPI templates the tenant can click to
   fill the formula field, removing the "how do I write formulas?"
   friction that stops most tenants at KPI creation. Grid of cards,
   each card is a full button. */
.kpi-starters-grid{
  display:grid; gap:8px;
  grid-template-columns:repeat(auto-fit, minmax(280px, 1fr));
  margin-top:12px; padding:14px;
  background:var(--panel2);
  border:1px solid var(--line); border-radius:6px;}
.kpi-starter-card{
  display:flex; flex-direction:column; align-items:flex-start;
  padding:10px 12px; gap:4px;
  border:1px solid var(--line); border-radius:6px;
  background:var(--panel); color:var(--ink);
  cursor:pointer; text-align:left;
  font-family:inherit;
  transition:border-color .12s ease, background .12s ease;}
.kpi-starter-card:hover{
  border-color:var(--ledger, #166A54);
  background:rgba(22,106,84,.04);}
.kpi-starter-card:focus-visible{
  outline:2px solid var(--ledger, #166A54); outline-offset:2px;
  border-color:var(--ledger);}
.kpi-starter-name{
  font-size:13px; font-weight:500; color:var(--ink);}
.kpi-starter-formula{
  font-size:11px; font-family:ui-monospace,Menlo,monospace;
  color:var(--ink-2, var(--muted)); background:rgba(0,0,0,.03);
  padding:2px 6px; border-radius:3px; letter-spacing:0;}
.kpi-starter-desc{
  font-size:11px; color:var(--muted); line-height:1.4;}

/* ── KPI BUILDER — the visual formula editor on the custom KPI form.
   Metric | operator | metric-or-const row of pills, plus an advanced
   JSON textarea underneath. */
.kpi-builder{
  display:flex; gap:8px; flex-wrap:wrap; align-items:center;
  padding:14px 16px; background:var(--panel2);
  border:1px solid var(--line); border-radius:12px;}
.kpi-builder select,
.kpi-builder input[type=number]{
  padding:8px 12px; border:1px solid var(--line);
  border-radius:8px; background:var(--panel);
  font-size:13px; font-weight:600; font-family:inherit;
  color:var(--ink); min-width:60px;}
.kpi-builder .kpi-metric{min-width:180px;}
.kpi-builder .kpi-op{min-width:70px;}
.kpi-builder .kpi-const{width:100px;}
.kpi-advanced summary{
  cursor:pointer; padding:4px 0;
  font-size:12px; color:var(--muted); font-weight:600;
  letter-spacing:.06em; text-transform:uppercase;
  list-style:none;}
.kpi-advanced summary::-webkit-details-marker{display:none;}
.kpi-advanced summary::before{content:"› "; color:var(--muted);}
.kpi-advanced[open] summary::before{content:"▾ ";}
.kpi-preview{
  padding:12px 14px; background:var(--panel2);
  border:1px solid var(--line); border-radius:10px;
  font-size:13px; color:var(--muted);}
.kpi-preview code{
  color:var(--ink); background:var(--panel);
  padding:2px 8px; border-radius:6px;
  font-family:ui-monospace,Menlo,monospace; font-size:12px;}
@media (max-width: 640px){
  .kpi-builder{padding:12px; gap:6px;}
  .kpi-builder .kpi-metric{min-width:100%;}
}

/* ── WIZARD steps — the 4-step indicator at the top of every
   /reports/new step. Reads as a horizontal breadcrumb: Basics →
   Sources → Campaigns → Review. Active step is filled; done steps
   are marked with a subtle check. */
/* ── WIZARD steps — quiet horizontal breadcrumb. No filled boxes,
   no colored accents. The active step reads via weight + underline,
   done steps get a subtle tick. Reads as "chapter of your setup"
   rather than "colored progress widget." */
.wizard-steps{
  display:flex; gap:0; flex-wrap:nowrap;
  margin:0 0 40px 0; padding:0;
  background:transparent;
  border:0;
  border-bottom:1px solid var(--line);}
.wizard-step{
  flex:1; min-width:0;
  padding:14px 6px 12px 6px;
  border:0;
  background:transparent;
  border-bottom:2px solid transparent;
  margin-bottom:-1px;
  font-size:11px; font-weight:600;
  letter-spacing:.14em; text-transform:uppercase;
  color:var(--muted);
  text-align:left;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  border-radius:0;}
.wizard-step.active{
  color:var(--ink);
  border-bottom-color:var(--ink);}
.wizard-step.done{
  color:var(--ink);}
.wizard-step.done::before{
  content:"✓ "; color:var(--ink);}
.wizard-actions{
  display:flex; justify-content:space-between; align-items:center;
  gap:12px; margin:32px 0 0 0;
  padding-top:24px; border-top:1px solid var(--line);}
@media (max-width: 640px){
  .wizard-steps{gap:8px;}
  .wizard-step{font-size:10px; letter-spacing:.10em;}
  .wizard-actions{flex-direction:column-reverse; align-items:stretch;}
  .wizard-actions .btn{width:100%;}
}

/* ── REPORT TABS — a horizontal tab bar replacing the "Switch report"
   dropdown. One tab per report + a plus tab for creating another.
   Reads as workspace tabs, not chrome. Tabs sit on a hairline; the
   active tab overlays the hairline with a solid rule underneath. */
.report-tabs{
  display:flex; gap:2px; flex-wrap:wrap;
  margin:8px 0 32px 0;
  padding:0;
  border-bottom:1px solid var(--line);}
.report-tab{
  padding:12px 16px 10px 16px;
  border:0;
  background:transparent;
  border-bottom:2px solid transparent;
  margin-bottom:-1px;
  color:var(--muted); font-weight:500; font-size:14px;
  letter-spacing:-.005em;
  border-radius:0;
  transition:color .15s ease, border-color .15s ease;}
.report-tab:hover{
  color:var(--ink);
  border-bottom-color:var(--line-strong);
  text-decoration:none;}
.report-tab.active{
  color:var(--ink);
  border-bottom-color:var(--ink);
  font-weight:500;}
.report-tab-new{
  color:var(--muted);
  font-weight:400;
  margin-left:auto;}
@media (max-width: 640px){
  .report-tab{padding:10px 12px 8px 12px; font-size:13px;}
  .report-tab-new{margin-left:0;}
}

/* ── REGEN BAR — the inline range picker + Regenerate button that
   sits directly above the report body. This is the daily-use control:
   pick a window, click Regenerate. Was the Settings modal's Range
   section; now visible on the page. Radio-styled pills so a click
   both selects the range AND stays visually locked in until submit. */
.regen-bar{
  /* Airy white bar. No filled background — just a hairline top and
     bottom, generous vertical padding. The pills are text-first, not
     boxy chips; the active state is an underline, not a fill. */
  margin:0 0 32px 0;
  padding:14px 0;
  background:transparent;
  border:0;
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
  display:flex; flex-wrap:wrap; gap:12px;
  align-items:center; justify-content:space-between;}
.regen-bar-pills{
  display:flex; flex-wrap:wrap; gap:4px; align-items:center;
  flex:1; min-width:0;}
.regen-pill{
  display:inline-flex; align-items:center; gap:6px;
  padding:6px 12px;
  border:0; border-radius:0;
  background:transparent; color:var(--muted);
  font-size:13px; font-weight:500;
  letter-spacing:-.005em;
  cursor:pointer; user-select:none;
  transition:color .12s ease;
  min-height:32px;
  position:relative;}
.regen-pill:hover{color:var(--ink);}
.regen-pill input[type=radio]{
  position:absolute; opacity:0; pointer-events:none; width:0; height:0;}
.regen-pill:has(input[type=radio]:checked){
  color:var(--ink); font-weight:600;}
.regen-pill:has(input[type=radio]:checked)::after{
  content:""; position:absolute;
  left:12px; right:12px; bottom:-1px; height:2px;
  background:var(--ink);}
.regen-pill input[type=number]{
  width:52px; padding:3px 6px; font-size:12px; font-weight:500;
  border:1px solid var(--line); border-radius:4px;
  text-align:center; margin:0 2px;
  font-family:ui-monospace,Menlo,monospace;
  background:transparent;}
.regen-pill select{
  padding:3px 6px; font-size:12px; font-weight:500;
  border:1px solid var(--line); border-radius:4px;
  margin-left:4px; font-family:inherit;
  background:transparent;}
.regen-bar-btn{
  flex-shrink:0;
  padding:8px 20px;
  display:inline-flex; align-items:center;}
@media (max-width: 640px){
  .regen-bar{padding:10px 0; gap:8px;}
  .regen-pill{font-size:12px; padding:5px 10px;}
  .regen-bar-btn{width:100%;}
}

/* ── JUMP STRIP — control-panel nav row that sits under the page-top
   actions. Compact provider-marked chips, each anchoring to a section
   below. Lets a returning tenant skip straight to Meta or Add source
   without scrolling. Quiet visually — it's navigation, not a CTA. */
.jump-strip{
  display:flex; flex-wrap:wrap; align-items:center;
  gap:8px; padding:14px 16px;
  margin:8px 0 12px 0;
  background:var(--panel2); border:1px solid var(--line);
  border-radius:10px;
  font-size:13px;}
.jump-strip-label{
  font-size:11px; font-weight:700;
  text-transform:uppercase; letter-spacing:.09em;
  color:var(--muted);
  margin-right:4px;}
.jump-chip{
  display:inline-flex; align-items:center; gap:6px;
  padding:6px 12px; border-radius:100px;
  background:var(--panel); color:var(--ink);
  border:1px solid var(--line);
  font-weight:600; font-size:12.5px; letter-spacing:.01em;
  text-decoration:none;
  transition:border-color .12s ease, background .12s ease;}
.jump-chip:hover{
  border-color:var(--ink); background:var(--panel);
  text-decoration:none; color:var(--ink);}
.jump-chip svg{display:block; flex-shrink:0;}
.jump-chip-add{
  background:var(--ink); color:var(--panel); border-color:var(--ink);}
.jump-chip-add:hover{
  background:var(--accent); border-color:var(--accent);
  color:#fff;}
@media (max-width: 640px){
  .jump-strip{padding:12px; gap:6px;}
  .jump-chip{padding:5px 10px; font-size:12px;}
}
/* Smooth-scroll for the anchor jumps, and account for the mobile
   fixed top bar so anchor targets don't hide under it. */
html{scroll-behavior:smooth;}
@media (max-width: 900px){
  #meta-panel, #google-ads-panel, #connections,
  #add-source, #history{scroll-margin-top:68px;}
}

/* ── LIVE CHANNELS — one section, N provider sub-panels beneath a
   shared range control. Sub-panels are separated by hairline; each
   opens with a small pill-shaped mark carrying the provider color. */
.channels-section .channel-sub{
  padding:22px 0 4px 0;
  border-top:1px solid var(--rule-soft);}
.channels-section .channel-sub:first-of-type{
  border-top:none; padding-top:0;}
.channel-sub-head{
  display:flex; align-items:center; gap:10px;
  margin-bottom:14px;}
.channel-sub-mark{
  display:inline-flex; align-items:center;
  padding:3px 10px; border-radius:100px;
  font-size:11px; font-weight:700; letter-spacing:.06em;
  text-transform:uppercase;
  border:1px solid var(--line);}
.channel-sub-mark.meta{
  background:#eaf0ff; color:#1e40af; border-color:#c8d5f5;}
.channel-sub-mark.google{
  background:#fef2ec; color:#b6431a; border-color:#f5d0bd;}
.channel-sub-body{min-height:24px;}
@media (max-width: 640px){
  .channels-section .section-head-actions{width:auto;}
  .channels-section .channel-sub{padding-top:18px;}
}
