/* ===========================================================================
   {{APP_NAME}} — application styles
   Every colour, size, radius and timing below is a var() from tokens.css.
   A hex literal in this file is a bug: see DESIGN.md.
   =========================================================================== */

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

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text-primary);
  background: var(--bg-base);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { max-width: 100%; height: auto; display: block; }
a { color: var(--accent); text-decoration: none; transition: opacity var(--t-base); }
a:hover { opacity: .85; }

h1, h2, h3 { color: var(--text-primary); margin: 0 0 var(--sp-4); }
h1 { font-size: var(--fs-h1); font-weight: var(--fw-h1); line-height: var(--lh-h1); letter-spacing: var(--ls-h1); }
h2 { font-size: var(--fs-h2); font-weight: var(--fw-h2); line-height: var(--lh-h2); letter-spacing: var(--ls-h2); }
h3 { font-size: var(--fs-h3); font-weight: var(--fw-h3); line-height: var(--lh-h3); }
p  { color: var(--text-secondary); margin: 0 0 var(--sp-4); }

:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--radius-sm); }

/* ---------------------------------------------------------------- nav --- */
.nav {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--bg-base) 88%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
}
.nav-inner {
  max-width: var(--container); margin: 0 auto;
  padding: var(--sp-3) var(--gutter);
  display: flex; align-items: center; gap: var(--sp-5);
}
.wordmark { color: var(--text-primary); font-weight: 700; letter-spacing: -.3px; font-size: 17px; }
.nav-links { display: flex; gap: var(--sp-5); margin-left: auto; }
.nav-links a { color: var(--text-secondary); font-size: 15px; }
.nav-links a:hover { color: var(--text-primary); opacity: 1; }
.nav .btn { margin-left: var(--sp-4); }
@media (max-width: 768px) {
  .nav-links { display: none; }
  .nav .btn { margin-left: auto; }
}

/* ------------------------------------------------------------ buttons --- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: var(--control-h);
  padding: var(--sp-3) var(--sp-5);
  border: 1px solid transparent; border-radius: var(--radius-md);
  font-family: var(--font); font-size: 15px; font-weight: 600;
  cursor: pointer; white-space: nowrap;
  transition: transform var(--t-base), filter var(--t-base), background var(--t-base), border-color var(--t-base);
}
/*
 * "Small" means smaller TYPE and PADDING, never a smaller hit area. The
 * design system sets a 44px minimum touch target and there is no exception
 * for secondary buttons — a revoke button in a table row is exactly the kind
 * of control that gets mis-tapped on a phone. A real-browser test at four
 * widths enforces this; an earlier 36px value failed it on all four.
 */
.btn-sm { min-height: var(--control-h); padding: var(--sp-2) var(--sp-4); font-size: 14px; }
.btn-block { width: 100%; }
.btn-primary { background: var(--accent); color: var(--text-on-accent); box-shadow: var(--shadow-accent); }
.btn-primary:hover { filter: brightness(1.15); transform: translateY(-1px); opacity: 1; }
.btn-ghost { background: transparent; color: var(--text-primary); border-color: var(--border-strong); }
.btn-ghost:hover { background: var(--bg-elevated); opacity: 1; }
.btn-danger { background: transparent; color: var(--red); border-color: var(--red); }
.btn-danger:hover { background: color-mix(in srgb, var(--red) 12%, transparent); opacity: 1; }
.btn:disabled { opacity: .5; cursor: not-allowed; transform: none; }

/* --------------------------------------------------------------- auth --- */
.auth-main { display: flex; justify-content: center; padding: var(--sp-8) var(--gutter); }
.auth-card {
  width: 100%; max-width: 420px;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-soft);
  padding: var(--sp-6);
}
.auth-card h1 { font-size: 28px; letter-spacing: -.5px; margin-bottom: var(--sp-2); }
.auth-card .lede { font-size: 15px; margin-bottom: var(--sp-5); }
.auth-form { display: flex; flex-direction: column; gap: var(--sp-2); }
.auth-form label { font-size: 13px; font-weight: 600; color: var(--text-secondary); margin-top: var(--sp-3); }
.auth-form label .opt { font-weight: 400; color: var(--text-muted); }
.auth-form input[type="text"],
.auth-form input[type="email"],
.auth-form input[type="password"] {
  min-height: var(--control-h);
  padding: var(--sp-3);
  background: var(--bg-base);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  font-family: var(--font); font-size: 15px;
}
.auth-form input:focus { outline: none; border-color: var(--accent); box-shadow: var(--focus-ring); }
.auth-form .btn { margin-top: var(--sp-5); }
.auth-alt { margin: var(--sp-5) 0 0; font-size: 14px; color: var(--text-secondary); text-align: center; }
.dot { color: var(--text-muted); margin: 0 var(--sp-2); }

.pill {
  display: inline-block; margin-bottom: var(--sp-3);
  padding: var(--sp-1) var(--sp-3);
  background: var(--accent-soft); color: var(--accent);
  border-radius: var(--radius-xl);
  font-size: var(--fs-small); font-weight: 600;
}

/* ------------------------------------------------------------- alerts --- */
.alert {
  padding: var(--sp-3) var(--sp-4); border-radius: var(--radius-md);
  font-size: 14px; line-height: 1.6; margin-bottom: var(--sp-4);
  border: 1px solid var(--border-strong);
}
.alert-error  { background: color-mix(in srgb, var(--red) 12%, transparent);    border-color: var(--red);    color: var(--text-primary); }
.alert-notice { background: color-mix(in srgb, var(--green) 12%, transparent);  border-color: var(--green);  color: var(--text-primary); }
.alert-info   { background: var(--accent-soft);                                 border-color: var(--accent); color: var(--text-secondary); }

/* ------------------------------------------------- google button + hp --- */
.auth-divider {
  display: flex; align-items: center; gap: var(--sp-3);
  margin: var(--sp-5) 0; color: var(--text-muted); font-size: var(--fs-small);
}
.auth-divider::before, .auth-divider::after {
  content: ""; flex: 1; height: 1px; background: var(--border);
}
.gsi-btn {
  display: flex; align-items: center; justify-content: center; gap: var(--sp-3);
  min-height: var(--control-h); width: 100%;
  background: var(--bg-elevated); color: var(--text-primary);
  border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  font-size: 15px; font-weight: 600;
  transition: background var(--t-base);
}
.gsi-btn:hover { background: var(--bg-card); opacity: 1; }
.gsi-mark { flex: none; }

/*
 * Honeypot. clip-path, NOT display:none — many bots skip hidden inputs but
 * happily fill a field that is technically in the layout.
 */
.hp-wrap {
  position: absolute;
  clip-path: inset(50%);
  width: 1px; height: 1px;
  overflow: hidden; white-space: nowrap;
}

/* ------------------------------------------------------------- footer --- */
.footer-slim {
  max-width: var(--container); margin: 0 auto;
  padding: var(--sp-6) var(--gutter);
  color: var(--text-muted); font-size: var(--fs-small);
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2);
  border-top: 1px solid var(--border);
}

/* ---------------------------------------------------------- app shell --- */
.app-shell { display: flex; min-height: 100vh; }
.sidebar {
  width: 232px; flex: none;
  background: var(--bg-card); border-right: 1px solid var(--border);
  padding: var(--sp-5) var(--sp-3);
  display: flex; flex-direction: column; gap: var(--sp-1);
}
.sidebar .wordmark { padding: 0 var(--sp-3) var(--sp-5); display: block; }
.sidebar a {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3); border-radius: var(--radius-md);
  color: var(--text-secondary); font-size: 15px; font-weight: 500;
}
.sidebar a:hover { background: var(--bg-elevated); color: var(--text-primary); opacity: 1; }
.sidebar a.active { background: var(--accent-soft); color: var(--accent); }
.app-main { flex: 1; min-width: 0; padding: var(--sp-6) var(--sp-6) var(--sp-8); }
@media (max-width: 768px) {
  .app-shell { flex-direction: column; }
  .sidebar { width: auto; flex-direction: row; overflow-x: auto; border-right: 0; border-bottom: 1px solid var(--border); }
  .sidebar .wordmark { display: none; }
  .app-main { padding: var(--sp-5) var(--gutter); }
}

/* --------------------------------------------------------------- cards -- */
.card {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-soft);
  padding: var(--sp-5); margin-bottom: var(--sp-5);
}
.card h2 { font-size: 20px; letter-spacing: 0; margin-bottom: var(--sp-3); }
.section-label {
  display: inline-block; font-size: var(--fs-label); font-weight: 600;
  letter-spacing: var(--ls-label); text-transform: uppercase;
  color: var(--accent); margin-bottom: var(--sp-3);
}
.muted { color: var(--text-muted); font-size: 14px; }
.mono { font-family: var(--font-mono); font-size: 13px; }

/* --------------------------------------------------------------- steps -- */
.step { display: flex; gap: var(--sp-4); padding: var(--sp-5) 0; border-bottom: 1px solid var(--border); }
.step:last-child { border-bottom: 0; }
.step-num {
  flex: none; width: 32px; height: 32px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent); font-weight: 700; font-size: 14px;
}
.step.done .step-num { background: color-mix(in srgb, var(--green) 20%, transparent); color: var(--green); }
.step-body { flex: 1; min-width: 0; }

/* ------------------------------------------------------------- codebox -- */
.codebox {
  position: relative;
  background: var(--bg-base); border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  padding: var(--sp-4); padding-right: 96px;
  font-family: var(--font-mono); font-size: 13px; line-height: 1.6;
  color: var(--text-primary);
  overflow-x: auto; white-space: pre;
}
.codebox .copy {
  position: absolute; top: var(--sp-1); right: var(--sp-1);
  min-height: var(--control-h);   /* 44px: the copy button IS the CTA here */
  padding: var(--sp-1) var(--sp-3);
  background: var(--bg-elevated); color: var(--text-secondary);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  font-family: var(--font); font-size: 12px; font-weight: 600; cursor: pointer;
}
.codebox .copy:hover { color: var(--text-primary); }

/* --------------------------------------------------------------- tabs --- */
.tabs { display: flex; gap: var(--sp-1); margin-bottom: var(--sp-4); border-bottom: 1px solid var(--border); }
.tabs button {
  background: none; border: 0; border-bottom: 2px solid transparent;
  min-height: var(--control-h);   /* 44px hit area, same rule as every button */
  padding: var(--sp-3) var(--sp-4); cursor: pointer;
  color: var(--text-secondary); font-family: var(--font); font-size: 14px; font-weight: 600;
}
.tabs button[aria-selected="true"] { color: var(--accent); border-bottom-color: var(--accent); }

/* -------------------------------------------------------------- table --- */
.table { width: 100%; border-collapse: collapse; font-size: 14px; }
.table th, .table td { text-align: left; padding: var(--sp-3); border-bottom: 1px solid var(--border); }
.table th { color: var(--text-muted); font-size: var(--fs-label); text-transform: uppercase; letter-spacing: 1px; font-weight: 600; }
.table td { color: var(--text-secondary); }
.table tbody tr:hover td { background: var(--bg-elevated); }
.table-wrap { overflow-x: auto; }

.badge {
  display: inline-block; padding: 2px var(--sp-2); border-radius: var(--radius-sm);
  font-size: 12px; font-weight: 600;
  background: var(--accent-soft); color: var(--accent);
}
.badge-warn { background: color-mix(in srgb, var(--yellow) 16%, transparent); color: var(--yellow); }
.badge-ok   { background: color-mix(in srgb, var(--green) 16%, transparent);  color: var(--green); }

/* -------------------------------------------------------- empty state --- */
.empty { text-align: center; padding: var(--sp-8) var(--sp-5); }
.empty svg { margin: 0 auto var(--sp-4); display: block; color: var(--text-muted); }
.empty h3 { margin-bottom: var(--sp-2); }
.empty p { max-width: 420px; margin: 0 auto var(--sp-5); }

@media (max-width: 480px) {
  .auth-card { padding: var(--sp-5) var(--sp-4); }
  .auth-card h1 { font-size: 24px; }
}

/* ===========================================================================
   DASHBOARD
   =========================================================================== */

.page-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--sp-4); margin-bottom: var(--sp-5); flex-wrap: wrap;
}
.page-head h1 { font-size: 32px; letter-spacing: -.8px; margin: 0; }
@media (max-width: 768px) { .page-head h1 { font-size: 24px; } }

/* ---------------------------------------------------------- filter bar --- */
.filterbar {
  display: flex; flex-wrap: wrap; gap: var(--sp-3);
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: var(--sp-4);
  margin-bottom: var(--sp-5);
}
.fb-field { display: flex; flex-direction: column; gap: var(--sp-1); min-width: 0; flex: 1 1 160px; }
.fb-field > span {
  font-size: var(--fs-label); font-weight: 600; letter-spacing: 1px;
  text-transform: uppercase; color: var(--text-muted);
}
.fb-field select {
  min-height: var(--control-h);
  padding: var(--sp-2) var(--sp-3);
  background: var(--bg-base); color: var(--text-primary);
  border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  font-family: var(--font); font-size: 14px;
  max-width: 100%;                 /* long project paths must not widen the row */
  text-overflow: ellipsis;
}
.fb-field select:focus { outline: none; border-color: var(--accent); box-shadow: var(--focus-ring); }

/* ---------------------------------------------------------------- KPIs --- */
.kpis {
  display: grid; gap: var(--sp-4); margin-bottom: var(--sp-5);
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
@media (max-width: 1024px) { .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 480px)  { .kpis { grid-template-columns: minmax(0, 1fr); } }
.kpi {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: var(--sp-5);
}
.kpi-label {
  font-size: var(--fs-label); font-weight: 600; letter-spacing: 1px;
  text-transform: uppercase; color: var(--text-muted); margin-bottom: var(--sp-2);
}
.kpi-value { font-size: 30px; font-weight: 700; letter-spacing: -1px; line-height: 1.1; }
.kpi-sub { font-size: 13px; color: var(--text-muted); margin-top: var(--sp-1); }
/* A placeholder cost is drawn as provisional, never as money. */
.kpi-untrusted { border-style: dashed; }
.kpi-untrusted .kpi-value { color: var(--text-secondary); }

/* -------------------------------------------------------------- grids --- */
.grid-2 { display: grid; gap: var(--sp-4); grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { display: grid; gap: var(--sp-4); grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 1024px) { .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 768px)  { .grid-2, .grid-3 { grid-template-columns: minmax(0, 1fr); } }

/* ------------------------------------------------------------- charts --- */
/* A fixed height box means the canvas cannot grow without bound on reflow,
   which is the classic Chart.js responsive-resize runaway. */
.chart-wrap { position: relative; height: 300px; width: 100%; }
.chart-sm { height: 240px; }
@media (max-width: 480px) { .chart-wrap { height: 240px; } .chart-sm { height: 200px; } }

/* -------------------------------------------------------------- table --- */
.table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.table-compact th, .table-compact td { padding: var(--sp-2) var(--sp-3); }
.table-nested { background: var(--bg-base); border-radius: var(--radius-md); margin: var(--sp-2) 0; }
.table-nested th, .table-nested td { border-bottom-color: var(--border); }
.subrow > td { padding-top: 0 !important; }
.ellipsis { max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
tr.clickable { cursor: pointer; }

/* An ESTIMATE never shares a visual column with a billed figure unlabelled. */
.est { color: var(--text-secondary); }
.est-mark {
  color: var(--estimate-stroke); font-weight: 700;
  margin-left: 2px; cursor: help;
}
.methodology { border-left: 3px solid var(--accent); }

/* ------------------------------------------------------------- pager ---- */
.pager {
  display: flex; align-items: center; justify-content: center;
  gap: var(--sp-4); padding: var(--sp-4) 0;
}

/*
 * Below 768px a wide data table becomes a stack of cards. Each cell carries
 * its own header via data-label, so the table never forces a sideways scroll
 * on a phone. Tables deliberately kept scrollable (charts, code) opt out with
 * .table-wrap, which has its own overflow.
 */
@media (max-width: 768px) {
  .table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .table, .table tbody, .table tr, .table td { display: block; width: 100%; }
  .table tr {
    border: 1px solid var(--border); border-radius: var(--radius-md);
    margin-bottom: var(--sp-3); padding: var(--sp-2);
  }
  .table td {
    border-bottom: 0; display: flex; justify-content: space-between;
    gap: var(--sp-4); padding: var(--sp-2);
  }
  .table td::before {
    content: attr(data-label);
    color: var(--text-muted); font-size: var(--fs-label);
    text-transform: uppercase; letter-spacing: 1px; font-weight: 600;
  }
  .table .num { text-align: right; }
  .ellipsis { max-width: none; }
  .subrow > td { display: block; }
  .table-nested tr { border: 0; margin: 0; }
}

/* ===========================================================================
   UTILITIES
   ---------------------------------------------------------------------------
   These exist because the CSP is `style-src 'self' 'nonce-...'` with no
   unsafe-inline, and a nonce does NOT apply to a style="" ATTRIBUTE — only to
   a <style> element. Every inline style in a template is therefore silently
   dropped by the browser. A real browser test caught ten of them.
   =========================================================================== */
.mt-auto  { margin-top: auto; }
.mt-2     { margin-top: var(--sp-2); }
.mt-3     { margin-top: var(--sp-3); }
.mt-4     { margin-top: var(--sp-4); }
.mb-0     { margin-bottom: 0; }
.h1-page  { font-size: 32px; letter-spacing: -.8px; }
.h1-mono  { font-size: 20px; letter-spacing: 0; }
.fs-small { font-size: 12px; }
.note-est { font-size: 12px; margin: var(--sp-2) 0 0; }
@media (max-width: 768px) { .h1-page { font-size: 24px; } }

/* ===========================================================================
   SIDEBAR ICONS
   The sprite is defined once per page and hidden; <use> pulls each symbol.
   =========================================================================== */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.ico { width: 18px; height: 18px; flex: none; }

/*
 * Below 1024px the sidebar collapses to ICONS ONLY, which is what keeps a
 * seven-item nav from eating a phone screen. The label stays in the DOM as a
 * title attribute so it is still announced and still shows on hover.
 */
@media (max-width: 1024px) and (min-width: 769px) {
  .sidebar { width: 68px; }
  .sidebar .nav-text { display: none; }
  .sidebar a { justify-content: center; }
  .sidebar .wordmark { font-size: 0; }
  .sidebar .wordmark::after { content: "PC"; font-size: 15px; }
  .sidebar .btn { font-size: 0; padding-inline: var(--sp-2); }
  .sidebar .btn::after { content: "\2192"; font-size: 15px; }
}
@media (max-width: 768px) {
  .sidebar a { flex-direction: column; gap: 2px; padding: var(--sp-2) var(--sp-3); min-width: 64px; }
  .sidebar .nav-text { font-size: 11px; white-space: nowrap; }
  .sidebar .mt-auto { margin-top: 0; display: flex; align-items: center; gap: var(--sp-2); }
  .sidebar .mt-auto form { margin: 0; }
  .sidebar .mt-auto .btn { margin-top: 0 !important; width: auto; }
}

/* --------------------------------------------------------- alert rules --- */
.rule-form {
  display: grid; gap: var(--sp-3);
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
@media (max-width: 1024px) { .rule-form { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px)  { .rule-form { grid-template-columns: minmax(0, 1fr); } }
.rule-form input[type="text"],
.rule-form input[type="number"] {
  min-height: var(--control-h);
  padding: var(--sp-2) var(--sp-3);
  background: var(--bg-base); color: var(--text-primary);
  border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  font-family: var(--font); font-size: 14px; width: 100%;
}
.rule-form input:focus { outline: none; border-color: var(--accent); box-shadow: var(--focus-ring); }
.row-actions { display: flex; gap: var(--sp-2); }
.row-actions form { margin: 0; }
@media (max-width: 768px) { .row-actions { justify-content: flex-end; } }

/* ---------------------------------------------------------------------------
   WIDE TABLES
   A table with many columns shrinks to fit its container instead of
   overflowing, which squeezes the first column until the text wraps one word
   per line and pushes the action buttons out of sight. Giving the table a
   minimum width makes .table-wrap scroll instead — the columns keep sane
   widths and every action stays reachable.

   Page-level overflow tests cannot see this: the page itself never scrolls,
   because .table-wrap absorbs it. It took a screenshot to notice.
   --------------------------------------------------------------------------- */
@media (min-width: 769px) {
  .table-wrap > .table { min-width: 720px; }
  .table-wrap > .table td:first-child,
  .table-wrap > .table th:first-child { min-width: 150px; }
  /* The action column must never be the one that gets squeezed. */
  .table-wrap > .table td:last-child:has(.row-actions) { width: 1%; white-space: nowrap; }
}

/*
 * The actions column sticks to the right edge of a scrolling table, so Pause
 * and Delete are reachable without side-scrolling to find them. Without this
 * the buttons sit past the fold of .table-wrap and look missing.
 */
@media (min-width: 769px) {
  .table-wrap { position: relative; }
  .table-wrap > .table td:last-child:has(.row-actions) {
    position: sticky; right: 0; z-index: 1;
    background: var(--bg-card);
    box-shadow: -8px 0 12px -8px rgba(0, 0, 0, .8);
  }
  .table-wrap > .table tbody tr:hover td:last-child:has(.row-actions) { background: var(--bg-elevated); }
}

/* ===========================================================================
   ADMIN
   =========================================================================== */
.admin-bar {
  display: flex; align-items: center; gap: var(--sp-4); flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-5);
  background: var(--bg-card); border-bottom: 2px solid var(--accent);
  position: sticky; top: 0; z-index: 50;
}
.admin-bar strong {
  font-size: var(--fs-label); letter-spacing: var(--ls-label);
  color: var(--accent); font-weight: 700;
}
.admin-bar a { color: var(--text-secondary); font-size: 14px; font-weight: 500; }
.admin-bar a:hover { color: var(--text-primary); opacity: 1; }
.admin-bar a.active { color: var(--accent); }
.admin-bar .admin-exit { margin-left: auto; }
body.admin .app-main { padding: var(--sp-6) var(--sp-6) var(--sp-8); }
@media (max-width: 768px) { body.admin .app-main { padding: var(--sp-5) var(--gutter); } }

/*
 * The impersonation banner. Deliberately the loudest thing on the page and not
 * dismissible: an admin who forgets they are inside someone else's account
 * will eventually act on their behalf without meaning to.
 */
.imp-banner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4); flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-5);
  background: var(--yellow); color: var(--bg-base);
  font-size: 14px; font-weight: 600;
}
.imp-banner form { margin: 0; }
.imp-banner .btn {
  background: var(--bg-base); color: var(--yellow);
  border-color: var(--bg-base);
}
.imp-banner .btn:hover { filter: brightness(1.4); }

.fs-kpi-sm { font-size: 20px !important; letter-spacing: 0 !important; }
.fb-check .check { display: flex; align-items: center; gap: var(--sp-2); font-weight: 400; margin-top: 0; }
.fb-check input[type="checkbox"] { width: 18px; height: 18px; accent-color: var(--accent); }
.filterbar input[type="search"] {
  min-height: var(--control-h); padding: var(--sp-2) var(--sp-3);
  background: var(--bg-base); color: var(--text-primary);
  border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  font-family: var(--font); font-size: 14px; width: 100%;
}

/* A wider filter field, e.g. a search box. A class, not an inline style: the
   CSP blocks style attributes and this exact mistake was made twice. */
.fb-wide { flex: 1 1 320px; }

/* ===========================================================================
   BILLING
   =========================================================================== */
.plan-card { display: flex; flex-direction: column; }
.plan-card.plan-current { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent-soft); }
.plan-price { font-size: 34px; font-weight: 700; letter-spacing: -1px; line-height: 1.1; margin-bottom: var(--sp-2); }
.plan-per { font-size: 15px; font-weight: 400; color: var(--text-muted); letter-spacing: 0; }
.plan-list { list-style: none; margin: var(--sp-4) 0; padding: 0; flex: 1; }
.plan-list li {
  position: relative; padding: var(--sp-2) 0 var(--sp-2) var(--sp-5);
  color: var(--text-secondary); font-size: 14px;
  border-bottom: 1px solid var(--border);
}
.plan-list li:last-child { border-bottom: 0; }
.plan-list li::before {
  content: "✓"; position: absolute; left: 0;
  color: var(--green); font-weight: 700;
}
.plan-list li.plan-no { color: var(--text-muted); }
.plan-list li.plan-no::before { content: "·"; color: var(--text-muted); }

/* A destructive section is visually separated, so "delete everything" never
   sits in the same visual weight as "save your name". */
.card-danger { border-color: var(--red); }
.card-danger h2 { color: var(--red); }
