/* admin.css — Factory Admin components, authored to the dreamapp.io
 * standard. Layered ON TOP of styles.css (the verbatim factory-pages
 * stylesheet, which supplies the paper/ink/terracotta palette vars, the
 * font stacks, and the base grain). This file owns everything specific
 * to the admin console: the shell grid, sidebar + nav groups, masthead,
 * the login/denied card, and the editorial data primitives (eyebrow,
 * lede, fleet stat row, hairline table, underline tabs, chips) that the
 * Jinja macros + later phases consume.
 *
 * Source of truth for the look: the approved mock at
 * .agent/tasks/admin-editorial-redesign/reference_mock.html — its inline
 * component rules are lifted here so the admin renders identically while
 * keeping styles.css untouched.
 *
 * Palette tokens (--paper, --ink, --rule, --accent, --highlight, …) and
 * the --serif/--body/--mono families come from styles.css :root (light +
 * dark). The mock declared --ok/--warn/--info/--danger inline; styles.css
 * does not, so we define those status accents here (with dark-mode
 * variants) without re-declaring the shared tokens.
 */

:root {
  --serif: 'Fraunces', Georgia, serif;
  /* Body/data/nav text: a system sans for legibility on dense admin content.
   * Headings keep --serif (Fraunces); labels keep --mono. (admin-only token;
   * styles.css uses literal font strings, so the public site is unaffected.) */
  --body: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', Roboto, system-ui, sans-serif;
  --mono: 'JetBrains Mono', 'SF Mono', Menlo, monospace;
  --ok: #4f7a4d;
  --warn: #9a7320;
  --info: #5c7390;
  --danger: #a23d33;
  /* Soft status tints + amber ink — focus/status tags (admin-only). */
  --ok-soft: #e4ecdf;
  --warn-soft: #f3e8cf;
  --warn-ink: #8a6a25;
  --danger-soft: #f0ddd7;
  /* Data-viz chart palette — source of truth (mirrored as literals in the chart
     <script>, since <canvas> can't read CSS vars). green/slate/red reuse --ok/--info/--danger. */
  --chart-mint: #9FE1CB;
  --chart-gold: #C49A4B;
  --chart-violet: #7E6BA8;
  --chart-teal: #3E8E8E;
  --chart-amber: #B5762F;
}

@media (prefers-color-scheme: dark) {
  :root {
    --ok: #7faa72;
    --warn: #c2a04e;
    --info: #8aa0bb;
    --danger: #cf6a5c;
  }
}

/* The admin runs a fixed app-shell layout, not dreamapp.io's centered
 * editorial column — neutralize the base body's serif body metrics that
 * styles.css sets, but keep its background + grain. */
body.admin {
  font-family: var(--body);
  font-size: 14px;
  line-height: 1.43;
  /* ── RevenueCat-inspired re-skin (2026-06-20, admin-only; scoped to body.admin so
     styles.css / the public dreamapp.io site stay untouched). Clean light SaaS: Inter,
     near-black ink, indigo accent, light-grey surfaces, flat (no grain). These token
     overrides re-theme the whole admin (it's token-driven). Always light (RC is light). ── */
  --body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, system-ui, sans-serif;
  --serif: 'Inter', Georgia, serif;              /* headings now Inter, not Fraunces */
  --mono: 'Inter', 'SF Mono', Menlo, monospace;  /* labels/figures → Inter (RC) */
  --paper: #f6f6f6;          /* page background (RC) */
  --paper-soft: #efefef;
  --paper-card: #ffffff;     /* cards / panels white */
  --ink: #09090d;            /* primary text (near-black, RC) */
  --ink-soft: #525252;       /* secondary text (AA) */
  --ink-muted: #6b6b6b;      /* muted text (AA on both backgrounds) */
  --rule: #e0e0e0;           /* borders (RC) */
  --rule-soft: #ededed;
  --accent: #576cdb;         /* RC indigo */
  --accent-soft: #7c8ae6;
  --highlight: #eef0fb;      /* light-indigo tint (hover / active) */
  /* Status — RC-flavoured but kept AA-readable. */
  --ok: #0e9f6e; --warn: #c2780f; --info: #576cdb; --danger: #e5484d;
  --ok-soft: #d7f3e7; --warn-soft: #fbeccd; --warn-ink: #8a5a0f; --danger-soft: #fbdcdd;
  /* Data-viz palette = RC chart colours. */
  --chart-teal: #11d483; --chart-mint: #51c6e0; --chart-violet: #a987d1;
  --chart-gold: #e79462; --chart-amber: #99bb37;
}

/* RC is flat — drop the inherited paper grain on the admin. */
body.admin::before { display: none; }

@media (prefers-color-scheme: dark) {
  /* The RC theme is light; keep the admin light even when the OS is dark. The
     unconditional body.admin tokens above already win for the palette; re-assert
     the text tokens so the old dark-lift can't darken them. */
  body.admin::before { display: none; }
  body.admin {
    --paper: #f6f6f6; --paper-soft: #efefef; --paper-card: #ffffff;
    --ink: #09090d; --ink-soft: #525252; --ink-muted: #6b6b6b;
    --rule: #e0e0e0; --rule-soft: #ededed;
  }
}

.app {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: 248px 1fr;
  min-height: 100vh;
  transition: grid-template-columns 0.18s ease;
}

/* Collapsed icons-only rail (admin-nav-density-v1). */
html.rail-collapsed .app,
.app.rail-collapsed {
  grid-template-columns: 64px 1fr;
}

/* ───────────────────────────────────────────── sidebar */

.side {
  border-right: 1px solid var(--rule);
  padding: 32px 26px;
  display: flex;
  flex-direction: column;
  gap: 40px;
  min-width: 0;
}

.brand {
  font-family: var(--serif);
  font-variation-settings: 'opsz' 144, 'SOFT' 50, 'wght' 400;
  font-size: 25px;
  letter-spacing: -0.01em;
  line-height: 1;
}

.brand b { font-weight: 500; }
.brand .dot { color: var(--accent); }

.brand small {
  display: block;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.28em;
  color: var(--ink-muted);
  text-transform: none;
  margin-top: 9px;
}

.navgroup { display: flex; flex-direction: column; gap: 3px; }

.navgroup .glabel {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: none;
  color: var(--ink-muted);
  margin: 0 0 10px 2px;
}

.nav {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 8px 11px;
  border-radius: 9px;
  color: var(--ink-soft);
  text-decoration: none;
  font-family: var(--body);
  font-size: 16px;
  transition: background 0.15s, color 0.15s;
}

.nav svg {
  width: 16px;
  height: 16px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.6;
  flex: none;
}

.nav:hover { background: var(--rule-soft); color: var(--ink); }
.nav.on { background: var(--highlight); color: var(--accent); font-weight: 500; }
.nav.soon { color: var(--ink-muted); cursor: default; }

/* Indented sub-nav item (e.g. Events under Product analytics). */
.nav.nav-sub { margin-left: 18px; font-size: 14px; padding-top: 6px; padding-bottom: 6px; }
.nav.nav-sub svg { width: 14px; height: 14px; }
.nav-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.nav.soon .pill {
  margin-left: auto;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: none;
  color: var(--ink-muted);
  border: 1px solid var(--rule);
  border-radius: 999px;
  padding: 1px 7px;
}

.acct {
  margin-top: auto;
  display: flex;
  align-items: center;
  gap: 10px;
  border-top: 1px solid var(--rule);
  padding-top: 18px;
  flex-wrap: wrap;
}

.rail-toggle {
  margin-left: auto;
  width: 30px;
  height: 30px;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: var(--paper, #fff);
  color: var(--ink-soft);
  display: grid;
  place-items: center;
  cursor: pointer;
  padding: 0;
}
.rail-toggle svg {
  width: 14px;
  height: 14px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.8;
  transition: transform 0.18s ease;
}
.rail-toggle:hover { background: var(--rule-soft); color: var(--ink); }

html.rail-collapsed .side,
.app.rail-collapsed .side {
  padding: 18px 10px;
  gap: 22px;
  align-items: stretch;
}
html.rail-collapsed .brand b,
html.rail-collapsed .brand .dot,
html.rail-collapsed .brand small,
.app.rail-collapsed .brand b,
.app.rail-collapsed .brand .dot,
.app.rail-collapsed .brand small {
  display: none;
}
html.rail-collapsed .brand,
.app.rail-collapsed .brand {
  height: 28px;
  background: var(--highlight);
  border-radius: 8px;
}
html.rail-collapsed .glabel,
.app.rail-collapsed .glabel { display: none; }
html.rail-collapsed .nav,
.app.rail-collapsed .nav {
  justify-content: center;
  padding: 10px 0;
  gap: 0;
  margin-left: 0;
}
html.rail-collapsed .nav-label,
html.rail-collapsed .nav .pill,
.app.rail-collapsed .nav-label,
.app.rail-collapsed .nav .pill { display: none; }
html.rail-collapsed .nav.nav-sub,
.app.rail-collapsed .nav.nav-sub { margin-left: 0; }
html.rail-collapsed .acct,
.app.rail-collapsed .acct {
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding-top: 12px;
}
html.rail-collapsed .acct .who,
.app.rail-collapsed .acct .who { display: none; }
html.rail-collapsed .rail-toggle,
.app.rail-collapsed .rail-toggle { margin-left: 0; }
html.rail-collapsed .rail-toggle svg,
.app.rail-collapsed .rail-toggle svg { transform: rotate(180deg); }

.acct .av {
  width: 30px;
  height: 30px;
  border-radius: 999px;
  background: var(--highlight);
  color: var(--accent);
  font-family: var(--serif);
  font-weight: 500;
  display: grid;
  place-items: center;
  font-size: 13px;
}

.acct .who { font-size: 14px; color: var(--ink-soft); line-height: 1.25; }

.acct .who a {
  display: block;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
  text-decoration: none;
  text-transform: none;
  margin-top: 2px;
}

.acct .who a:hover { color: var(--accent); }

/* ───────────────────────────────────────────── main + masthead */

.main { padding: 30px 46px 64px; max-width: 1180px; }

.top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--rule);
}

.crumb {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: none;
  color: var(--ink-muted);
}

.crumb b { color: var(--ink); font-weight: 500; }

.topact { display: flex; align-items: center; gap: 18px; }

.kbd {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-muted);
  border: 1px solid var(--rule);
  border-radius: 7px;
  padding: 4px 9px;
}

.btn {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: none;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--ink);
  border-radius: 999px;
  padding: 8px 16px;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}

.btn:hover { background: var(--ink); color: var(--paper); }

/* ───────────────────────────────────────────── editorial primitives */

.eyebrow {
  display: flex;
  align-items: center;
  gap: 14px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.2em;
  text-transform: none;
  color: var(--accent);
  margin: 40px 0 0;
}

.eyebrow::before { content: ""; width: 26px; height: 1px; background: var(--accent); }

.lede {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 42px;
  letter-spacing: -0.02em;
  line-height: 1.02;
  margin: 14px 0 0;
}

.lede em { font-style: italic; color: var(--accent); }

.sub {
  font-size: 19px;
  color: var(--ink-soft);
  margin: 14px 0 0;
  max-width: 54ch;
  line-height: 1.5;
}

/* fleet stats — editorial numerals on a hairline grid */
.fleet {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  margin: 26px 0 0;
  border-top: 1px solid var(--rule);
}

.stat { padding: 14px 18px 14px 0; border-right: 1px solid var(--rule-soft); }
.stat:last-child { border-right: 0; }

.stat .n {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 28px;
  line-height: 0.95;
  letter-spacing: -0.02em;
}

.stat.ok .n { color: var(--ok); }
.stat.warn .n { color: var(--warn); }
.stat.info .n { color: var(--info); }
.stat.other .n { color: var(--accent); }

.stat .l {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: none;
  color: var(--ink-muted);
  margin-top: 12px;
}

/* chips (macro chip()) */
.chip {
  display: inline-flex;
  align-items: center;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: none;
  border: 1px solid var(--rule);
  border-radius: 999px;
  padding: 2px 9px;
  color: var(--ink-muted);
}

.chip--ok { color: var(--ok); border-color: var(--ok); }
.chip--warn { color: var(--warn); border-color: var(--warn); }
.chip--info { color: var(--info); border-color: var(--info); }
.chip--accent { color: var(--accent); border-color: var(--accent); }

/* table — editorial, hairline rows */
.tbl { width: 100%; border-collapse: collapse; margin-top: 30px; }

.tbl thead th {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: none;
  color: var(--ink-muted);
  text-align: left;
  font-weight: 400;
  padding: 0 16px 12px 0;
  border-bottom: 1px solid var(--rule);
}

.tbl thead th.r { text-align: right; }

.tbl tbody td {
  padding: 16px 16px 16px 0;
  border-bottom: 1px solid var(--rule-soft);
  vertical-align: middle;
}

.tbl tbody tr { transition: background 0.12s; cursor: pointer; }
.tbl tbody tr:hover { background: var(--paper-card); }

.nm {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 19px;
  letter-spacing: -0.01em;
  line-height: 1.1;
}

.bid { font-family: var(--mono); font-size: 11px; color: var(--ink-muted); margin-top: 3px; }

/* ───────────────────────────────────────────── app icons
 * Each app's real iOS icon, shown wherever an app is referenced (fleet table,
 * per-app masthead + Status header, cross-app Activity rows) so the operator
 * recognises apps visually. Source: the per-app `/apps/{bundle}/icon` endpoint
 * (real icon thumb, or a monogram-SVG fallback). All sizing/rounding lives here
 * — the <img>s carry no inline style (design-system / CSS-integrity guard). */
.appicon {
  width: 24px;
  height: 24px;
  flex: none;
  border-radius: 6px;
  object-fit: cover;
  vertical-align: middle;
  background: var(--highlight);              /* tint while the icon loads */
  box-shadow: inset 0 0 0 1px var(--rule);   /* hairline, no layout shift */
}
.appicon--xs { width: 18px; height: 18px; border-radius: 5px; margin-right: 6px; }

/* Fleet table App cell: icon | (name / bundle) text column. */
.appcell { display: flex; align-items: center; gap: 12px; }
.appcell--inline { gap: 10px; }
.appcell--inline .appicon { width: 24px; height: 24px; }
.appcell--inline .nm { font-weight: 500; font-size: 14px; line-height: 1.2; }
.appcell--inline .bid { margin-top: 2px; }
.apptext { min-width: 0; }

.crumb-icon--fleet {
  display: inline-grid;
  place-items: center;
  font-size: 12px;
  color: var(--accent);
  background: var(--highlight);
}

.sc-back-sep { margin: 0 8px; color: var(--ink-muted); }

/* Masthead breadcrumb icon (per-app pages only). */
.crumb-icon {
  width: 22px;
  height: 22px;
  flex: none;
  border-radius: 6px;
  object-fit: cover;
  background: var(--highlight);
  box-shadow: inset 0 0 0 1px var(--rule);
}

/* Breadcrumb app switcher (per-app pages only). */
.app-switcher { position: relative; }

.app-switcher__trigger {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: none;
  color: var(--ink-muted);
  background: transparent;
  border: none;
  padding: 0;
  cursor: pointer;
}

.app-switcher__trigger b { color: var(--ink); font-weight: 500; }

.app-switcher__caret {
  font-size: 10px;
  color: var(--ink-muted);
  margin-left: 2px;
}

.app-switcher__popover {
  position: absolute;
  top: calc(100% + 10px);
  left: 0;
  z-index: 20;
  width: 280px;
  max-height: 340px;
  display: flex;
  flex-direction: column;
  background: var(--paper-card);
  border: 1px solid var(--rule);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
  overflow: hidden;
}

.app-switcher__popover[hidden] { display: none; }

.app-switcher__filter {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink);
  background: var(--paper);
  border: none;
  border-bottom: 1px solid var(--rule);
  padding: 10px 12px;
  outline: none;
}

.app-switcher__filter:focus-visible { border-bottom-color: var(--accent); }

.app-switcher__list {
  list-style: none;
  margin: 0;
  padding: 6px;
  overflow-y: auto;
}

.app-switcher__list li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 8px;
  border-radius: 7px;
  cursor: pointer;
  font-size: 13px;
  color: var(--ink);
}

.app-switcher__list li:hover,
.app-switcher__list li[data-active] {
  background: var(--paper-soft);
}

.app-switcher__list li:focus-visible { background: var(--paper-soft); }

.app-switcher__list li[hidden] { display: none; }

/* Status header card — fills the 56px avatar tile. */
.apphdr__iconimg {
  width: 100%;
  height: 100%;
  display: block;
  border-radius: 14px;
  object-fit: cover;
}

/* table cells — editorial tinted text + state dot, mono data
 * (reference_mock.html lines 80-94). The Overview apps table is unstyled
 * without these; added in P2 alongside the table template. */
.state { font-family: var(--mono); font-size: 11px; letter-spacing: 0.04em; }
.state.ok { color: var(--ok); }
.state.warn { color: var(--warn); }
.state.info { color: var(--info); }
.state.none { color: var(--ink-muted); }

.dotmark {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 999px;
  margin-right: 8px;
  vertical-align: middle;
}

.dotmark.ok { background: var(--ok); }
.dotmark.warn { background: var(--warn); }
.dotmark.info { background: var(--info); }
.dotmark.none { background: var(--rule); }

.build { font-family: var(--mono); font-size: 12px; color: var(--ink-soft); }
.build .bad { color: var(--danger); }

.avail { font-family: var(--mono); font-size: 11px; }
.avail.set { color: var(--ok); }
.avail.unset { color: var(--warn); }

.stars { letter-spacing: 1px; color: var(--accent-soft); font-size: 13px; }
.stars .off { color: var(--rule); }

.rate { font-family: var(--mono); font-size: 12px; color: var(--ink-soft); margin-left: 6px; }

.rev { font-family: var(--mono); font-size: 13px; text-align: right; font-weight: 500; }
.ago { font-family: var(--mono); font-size: 11px; color: var(--ink-muted); text-align: right; }
.em { color: var(--ink-muted); }

.foot {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--ink-muted);
  margin-top: 24px;
}

/* legacy reveal toggle + search box — P2 chrome (not in the mock, which
 * is a static snapshot). Styled in the editorial mono idiom. */
.legacy-toggle { margin: 18px 0 0; }

.legacy-toggle a {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: none;
  color: var(--accent);
  text-decoration: none;
}

.legacy-toggle a:hover { color: var(--ink); }

.fleet-search { margin: 26px 0 0; }

.fleet-search input {
  width: 100%;
  max-width: 360px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 9px;
  padding: 9px 13px;
}

.fleet-search input::placeholder { color: var(--ink-muted); }
.fleet-search input:focus { outline: none; border-color: var(--accent); }

/* underline tabs (macro tab_bar()) */
.tabs { display: flex; gap: 30px; border-bottom: 1px solid var(--rule); }

.tab {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: none;
  color: var(--ink-muted);
  text-decoration: none;
  padding: 0 0 14px;
  position: relative;
}

.tab.on { color: var(--ink); }
.tab.on::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: var(--accent);
}

/* ───────────────────────────────────────────── login / denied card */

body.login-body { display: grid; place-items: center; min-height: 100vh; }

.login-wrap { position: relative; z-index: 2; width: 100%; max-width: 420px; padding: 24px; }

.login-card {
  border: 1px solid var(--rule);
  border-radius: 16px;
  background: var(--paper-card);
  padding: 44px 40px 36px;
  text-align: center;
}

.login-brand {
  font-family: var(--serif);
  font-variation-settings: 'opsz' 144, 'SOFT' 50, 'wght' 400;
  font-size: 30px;
  letter-spacing: -0.01em;
  line-height: 1;
}

.login-brand b { font-weight: 500; }
.login-brand .dot { color: var(--accent); }

.login-brand small {
  display: block;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.28em;
  color: var(--ink-muted);
  text-transform: none;
  margin-top: 10px;
}

.login-tagline {
  font-family: var(--body);
  font-size: 16px;
  color: var(--ink-soft);
  margin: 18px 0 28px;
}

.login-denied {
  font-family: var(--body);
  font-size: 16px;
  color: var(--danger);
  margin: 18px 0 28px;
  line-height: 1.5;
}

.login-btn {
  display: inline-block;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: none;
  color: var(--paper);
  background: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 999px;
  padding: 12px 26px;
  text-decoration: none;
  transition: background 0.15s, color 0.15s;
}

.login-btn:hover { background: var(--accent); border-color: var(--accent); color: var(--paper); }

.login-foot {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: none;
  color: var(--ink-muted);
  margin: 28px 0 0;
}

/* ═══════════════════════════════════════════════════════════════════════
 * Per-app surfaces (P3) — Status / Subscriptions & Tiers / Activity.
 * Same editorial idiom as the Overview primitives above (paper/ink/terracotta
 * tokens from styles.css; the --ok/--warn/--info/--danger status accents from
 * the top of this file). The webadmin class namespace (.apphdr/.appcols/…),
 * NOT the Streamlit .factory-* one. The two-column grid collapses to one
 * column under the existing 720px breakpoint (rule added in the @media block).
 * ═══════════════════════════════════════════════════════════════════════ */

/* ── header card ── */
.apphdr {
  display: flex;
  align-items: flex-start;
  gap: 18px;
  margin: 36px 0 0;
}

.apphdr__avatar {
  width: 56px;
  height: 56px;
  flex: none;
  border-radius: 14px;
  background: var(--highlight);
  color: var(--accent);
  font-family: var(--serif);
  font-weight: 500;
  font-size: 26px;
  display: grid;
  place-items: center;
}

.apphdr__body { flex: 1; min-width: 0; }

.apphdr__name {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 30px;
  letter-spacing: -0.02em;
  line-height: 1.05;
}

.apphdr__bundle { font-family: var(--mono); font-size: 12px; color: var(--ink-muted); margin-top: 5px; }

.apphdr__meta {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
  margin-top: 6px;
}

.apphdr__state { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; flex: none; }

.apphdr__pulled {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: none;
  color: var(--ink-muted);
}

/* The per-app tab bar (macro app_tab_bar) sits below the header. */
.apphdr + .tabs { margin-top: 26px; }

/* ── note / empty / placeholder ── */
.appnote {
  border: 1px solid var(--rule);
  border-radius: 12px;
  background: var(--paper-card);
  padding: 18px 20px;
  margin: 26px 0 0;
  font-size: 16px;
  color: var(--ink-soft);
  line-height: 1.5;
}

.appnote code {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--accent);
  background: var(--highlight);
  border-radius: 5px;
  padding: 1px 6px;
}

.appempty {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--ink-muted);
  padding: 18px 0;
}

.appnf-back { margin: 28px 0 0; }

.appnf-back a {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: none;
  color: var(--accent);
  text-decoration: none;
}

.appnf-back a:hover { color: var(--ink); }

/* ── two-column grid (App Store | TestFlight) ── */
.appcols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  margin: 30px 0 0;
  border-top: 1px solid var(--rule);
}

.appcol { padding: 26px 30px 26px 0; border-right: 1px solid var(--rule-soft); }
.appcol:last-child { border-right: 0; padding-right: 0; padding-left: 30px; }

.appcol__head {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: none;
  color: var(--ink-muted);
  margin: 0 0 18px;
  font-weight: 400;
}

/* ── stat rows (label / value) ── */
.statgrid { display: flex; flex-direction: column; gap: 12px; }

.statrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--rule-soft);
}

.statrow:last-child { border-bottom: 0; padding-bottom: 0; }

.statrow__k {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: none;
  color: var(--ink-muted);
}

.statrow__v { display: inline-flex; align-items: center; gap: 8px; font-size: 15px; color: var(--ink); }

/* ── pending banner ── */
.pendbar {
  margin: 18px 0 0;
  border: 1px solid var(--info);
  border-radius: 9px;
  padding: 8px 12px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: none;
  color: var(--info);
}

/* ── reviews ── */
.revs { margin-top: 24px; }

.revs__head {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: none;
  color: var(--ink-muted);
  margin: 0 0 14px;
  font-weight: 400;
}

.revcard {
  border: 1px solid var(--rule-soft);
  border-radius: 11px;
  background: var(--paper-card);
  padding: 14px 16px;
  margin-bottom: 12px;
}

.revcard:last-child { margin-bottom: 0; }
.revcard__stars { letter-spacing: 1px; color: var(--accent-soft); font-size: 13px; }
.revcard__stars .off { color: var(--rule); }

.revcard__title {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 17px;
  letter-spacing: -0.01em;
  margin-top: 6px;
}

.revcard__body { font-size: 15px; color: var(--ink-soft); line-height: 1.5; margin-top: 6px; }

.revcard__foot {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
  margin-top: 9px;
}

/* ── TestFlight build cards ── */
.tflist { display: flex; flex-direction: column; gap: 12px; }

.tfcard {
  border: 1px solid var(--rule-soft);
  border-radius: 11px;
  background: var(--paper-card);
  padding: 13px 16px;
}

.tfcard__row { display: flex; align-items: center; gap: 10px; }

.tfcard__num {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 999px;
  padding: 2px 9px;
}

.tfcard__meta {
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-muted);
  margin-top: 9px;
}

.tfcard__sep { color: var(--rule); }

/* ── action bar ── */
.actbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  margin: 34px 0 0;
  padding-top: 24px;
  border-top: 1px solid var(--rule);
}

.actbtn {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: none;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--ink);
  border-radius: 999px;
  padding: 9px 16px;
  text-decoration: none;
  transition: background 0.15s, color 0.15s;
}

.actbtn:hover { background: var(--ink); color: var(--paper); }

.actbtn--brand { color: var(--accent); border-color: var(--accent); }
.actbtn--brand:hover { background: var(--accent); border-color: var(--accent); color: var(--paper); }

.actbtn--off {
  color: var(--ink-muted);
  border-color: var(--rule);
  cursor: default;
}

.actbtn--off:hover { background: transparent; color: var(--ink-muted); }

.actbar__cli { display: inline-flex; align-items: center; gap: 9px; }

.actbar__cli-k {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: none;
  color: var(--ink-muted);
}

.actbar__cmd {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-soft);
  background: var(--rule-soft);
  border-radius: 6px;
  padding: 4px 9px;
}

/* ── Subscriptions & Tiers ── */
.subshd { display: flex; flex-wrap: wrap; align-items: baseline; gap: 18px; margin: 30px 0 0; }

.subshd__title {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 26px;
  letter-spacing: -0.02em;
  margin: 0;
}

.geotier { display: inline-flex; align-items: center; gap: 12px; }

.geotier__cap { font-size: 14px; color: var(--ink-soft); }

.subcards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 16px;
  margin: 28px 0 0;
}

.subcard {
  border: 1px solid var(--rule);
  border-radius: 14px;
  background: var(--paper-card);
  padding: 20px 22px;
}

.subcard__head { display: flex; flex-direction: column; gap: 7px; }

.subcard__id {
  align-self: flex-start;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-muted);
  background: var(--rule-soft);
  border-radius: 6px;
  padding: 3px 8px;
}

.subcard__name {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 19px;
  letter-spacing: -0.01em;
}

.subcard__chips { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 14px; }

.subcard__share { font-family: var(--mono); font-size: 13px; color: var(--ink-soft); margin-left: 2px; }

.subloc { margin-top: 16px; }

.subloc > summary {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--accent);
  cursor: pointer;
}

.subloc__row {
  display: grid;
  grid-template-columns: 64px 1fr;
  gap: 4px 12px;
  padding: 9px 0;
  border-bottom: 1px solid var(--rule-soft);
}

.subloc__code { font-family: var(--mono); font-size: 11px; color: var(--ink-muted); }
.subloc__name { font-size: 14px; color: var(--ink); }
.subloc__desc { grid-column: 2; font-size: 13px; color: var(--ink-soft); }

.subprices {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 14px;
  padding: 10px 12px;
  border: 1px dashed var(--rule);
  border-radius: 9px;
}

.subprices__k {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: none;
  color: var(--ink-muted);
}

.subprices__v { font-family: var(--mono); font-size: 12px; color: var(--ink-soft); }

.subcard__note { font-size: 14px; color: var(--ink-muted); line-height: 1.55; margin-top: 14px; }

/* ── Activity (per-app feed) ── */
.actfeed { margin: 30px 0 0; border-top: 1px solid var(--rule); }

.actrow {
  display: grid;
  grid-template-columns: 120px 1fr auto;
  gap: 0 22px;
  padding: 18px 0;
  border-bottom: 1px solid var(--rule-soft);
}

.actrow__time {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-muted);
  white-space: nowrap;
}

.actrow__top { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }

.actrow__summary {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 17px;
  letter-spacing: -0.01em;
}

.actrow__reason { font-size: 14px; color: var(--ink-soft); margin-top: 6px; line-height: 1.5; }

.actrow__actor { font-family: var(--mono); font-size: 11px; color: var(--ink-muted); text-align: right; white-space: nowrap; }

.actdiff { margin-top: 10px; }

.actdiff > summary {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: none;
  color: var(--accent);
  cursor: pointer;
}

.actdiff__pre {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-soft);
  background: var(--rule-soft);
  border-radius: 9px;
  padding: 12px 14px;
  margin: 10px 0 0;
  overflow-x: auto;
  white-space: pre;
}

/* ═══════════════════════════════════════════════════════════════════════
 * Per-app WRITE editors (P4) — Review Mode / Feature Flags / Wordmark forms.
 * Same editorial idiom as the P3 surfaces (paper/ink/terracotta + the
 * --ok/--warn/--info/--danger accents). The webadmin class namespace
 * (.edform/.edsec/.edtoggle/.edcard/.wmgrid/.flash), NOT the Streamlit
 * .factory-* one. Forms reuse the .actbtn / .actbtn--brand pill from the
 * action bar for the publish/choose button.
 * ═══════════════════════════════════════════════════════════════════════ */

/* ── one-shot flash banner (D3) ── */
.flash {
  margin: 26px 0 0;
  border: 1px solid var(--rule);
  border-radius: 11px;
  padding: 13px 16px;
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-soft);
}

.flash--success { border-color: var(--ok); color: var(--ok); background: var(--paper-card); }
.flash--error { border-color: var(--danger); color: var(--danger); background: var(--paper-card); }
.flash--warn { border-color: var(--warn); color: var(--warn); background: var(--paper-card); }

/* ── editor header + form shell ── */
.edhd { margin: 30px 0 0; }

.edhd__title {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 26px;
  letter-spacing: -0.02em;
  margin: 0;
}

.edhd__sub {
  font-size: 16px;
  color: var(--ink-soft);
  line-height: 1.55;
  margin: 10px 0 0;
  max-width: 64ch;
}

/* The "last published <when> · by <email> — reason" provenance line under a
 * write-tab heading (latest AdminAudit row; omitted when never published). */
.lastpub {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-muted);
  line-height: 1.6;
  margin: 8px 0 0;
  max-width: 78ch;
  overflow-wrap: anywhere;
}

.edhd__sub code,
.edsec__hint code,
.edcard__effect code {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--accent);
  background: var(--highlight);
  border-radius: 5px;
  padding: 1px 6px;
}

/* Long App Store identifiers / shell snippets must break, not push the narrow
 * phone column wider than the viewport (keeps the mobile shell scroll-free). */
.edcard__key,
.appempty code,
.edhd__sub code,
.edsec__hint code,
.edcard__effect code { overflow-wrap: anywhere; }

.edform { margin: 28px 0 0; }

.edsec {
  padding: 24px 0;
  border-top: 1px solid var(--rule);
}

.edsec__head {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: none;
  color: var(--ink-muted);
  margin: 0;
  font-weight: 400;
}

.edsec__hint {
  font-size: 14px;
  color: var(--ink-soft);
  line-height: 1.5;
  margin: 10px 0 16px;
  max-width: 64ch;
}

/* ── textarea (list editors) ── */
.edtext {
  width: 100%;
  max-width: 560px;
  display: block;
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.6;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 10px;
  padding: 11px 13px;
  resize: vertical;
}

.edtext::placeholder { color: var(--ink-muted); }
.edtext:focus { outline: none; border-color: var(--accent); }

/* ── toggle switches (bool flags) ── */
.edtoggles { display: flex; flex-direction: column; gap: 12px; }

.edtoggle {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  font-size: 15px;
  color: var(--ink);
}

.edtoggle input { position: absolute; opacity: 0; width: 0; height: 0; }

.edtoggle__track {
  flex: none;
  width: 38px;
  height: 22px;
  border-radius: 999px;
  background: var(--rule);
  border: 1px solid var(--rule);
  position: relative;
  transition: background 0.15s, border-color 0.15s;
}

.edtoggle__thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 999px;
  background: var(--paper);
  transition: transform 0.15s;
}

.edtoggle input:checked + .edtoggle__track { background: var(--accent); border-color: var(--accent); }
.edtoggle input:checked + .edtoggle__track .edtoggle__thumb { transform: translateX(16px); }
.edtoggle input:focus-visible + .edtoggle__track { outline: 2px solid var(--accent); outline-offset: 2px; }

.edtoggle__label { line-height: 1.3; }
.edtoggle--inline { gap: 10px; }
.edtoggle--inline .edtoggle__label {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: none;
  color: var(--ink-muted);
}

/* ── feature/system cards ── */
.edcards { display: flex; flex-direction: column; gap: 14px; }

.edcard {
  border: 1px solid var(--rule);
  border-radius: 13px;
  background: var(--paper-card);
  padding: 18px 20px;
}

.edcard__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px; }

.edcard__key {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--accent);
  background: var(--highlight);
  border-radius: 6px;
  padding: 2px 8px;
}

.edcard__label {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 17px;
  letter-spacing: -0.01em;
}

.edcard__controls {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 20px;
  margin-top: 14px;
}

.edcard__effect {
  font-size: 14px;
  color: var(--ink-muted);
  margin: 14px 0 0;
}

/* ── labelled control (select / number) ── */
.edctl { display: inline-flex; flex-direction: column; gap: 6px; }

.edctl__k {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: none;
  color: var(--ink-muted);
}

.edctl__select,
.edctl__num {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 8px;
  padding: 7px 10px;
}

.edctl__num { width: 110px; }
.edctl__select:focus,
.edctl__num:focus { outline: none; border-color: var(--accent); }
.edctl__num:disabled { color: var(--ink-muted); border-style: dashed; }

/* ── publish bar (required reason + button) ── */
.edpublish {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 18px;
  margin: 30px 0 0;
  padding-top: 24px;
  border-top: 1px solid var(--rule);
}

/* Dirty-state UX (admin.js, form[data-dirty-track]): the "N unsaved changes"
 * chip sits beside the publish button; the button is inert until something
 * changed AND a reason is present. */
.dirtychip { align-self: center; white-space: nowrap; }

/* Live `N/200` reason counter (admin.js, input[data-char-count]). */
.edfield__hint { margin: 0; }
.charcount { font-family: var(--mono); font-size: 12px; color: var(--ink-muted); }

/* Cap-input sanity warning (admin.js, form[data-cap-sanity]): an edsec__hint
 * in the warn tone, appended per affected Usage Limits card. Never blocks. */
.capwarn { color: var(--warn); margin: 10px 0 0; }

.actbtn:disabled,
.actbtn:disabled:hover {
  background: transparent;
  color: var(--ink-muted);
  border-color: var(--rule);
  cursor: not-allowed;
  opacity: 0.7;
}

.edfield { display: flex; flex-direction: column; gap: 7px; flex: 1; min-width: 260px; }

.edfield__label {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: none;
  color: var(--ink-muted);
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.edreq {
  font-size: 9px;
  letter-spacing: 0.08em;
  color: var(--danger);
  border: 1px solid var(--danger);
  border-radius: 999px;
  padding: 1px 7px;
}

.edfield__input {
  width: 100%;
  font-family: var(--body);
  font-size: 15px;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 10px;
  padding: 10px 13px;
}

.edfield__input::placeholder { color: var(--ink-muted); }
.edfield__input:focus { outline: none; border-color: var(--accent); }

/* ── wordmark grid ── */
.wmchosen {
  display: flex;
  align-items: center;
  gap: 20px;
  margin: 26px 0 0;
  padding: 18px 20px;
  border: 1px solid var(--rule);
  border-radius: 14px;
  background: var(--paper-card);
}

.wmchosen__img { width: 200px; height: auto; flex: none; }

.wmchosen__k {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: none;
  color: var(--ink-muted);
}

.wmchosen__v { margin-top: 5px; }

.wmchosen__v code {
  font-family: var(--mono);
  font-size: 14px;
  color: var(--accent);
}

.wmchosen__sub { font-family: var(--mono); font-size: 11px; color: var(--ink-muted); margin-top: 7px; }

.wmgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 18px;
  margin: 28px 0 0;
}

.wmcard {
  border: 1px solid var(--rule);
  border-radius: 14px;
  background: var(--paper-card);
  padding: 16px;
}

.wmcard--on { border-color: var(--accent); }

.wmcard__frame {
  border: 1px solid var(--rule-soft);
  border-radius: 9px;
  padding: 14px;
  display: grid;
  place-items: center;
}

.wmcard__img { width: 100%; height: auto; display: block; }

.wmcard__row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 12px; }

.wmcard__stem { font-family: var(--mono); font-size: 12px; color: var(--ink-soft); }

.wmcard__form { display: flex; flex-direction: column; gap: 10px; margin-top: 12px; }

.wmcard__reason {
  width: 100%;
  font-family: var(--body);
  font-size: 13px;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 8px;
  padding: 8px 11px;
}

.wmcard__reason::placeholder { color: var(--ink-muted); }
.wmcard__reason:focus { outline: none; border-color: var(--accent); }

/* ═══════════════════════════════════════════════════════════════════════
 * Cross-app Activity log (P5) — `GET /activity`. Reuses the per-app feed/row
 * primitives (.actfeed / .actrow / .actrow__time / .actdiff above) and adds
 * the filter bar (.actfilter), the >500 cap banner (.actcap), and the App
 * cell (.actrow__app) that the cross-app variant inserts between time + body.
 * Same editorial idiom (paper/ink/terracotta + --ok/--warn/--info accents);
 * webadmin class namespace, NOT the Streamlit .factory-* one.
 * ═══════════════════════════════════════════════════════════════════════ */

/* ── filter bar (4 GET selects + apply/export) ── */
.actfilter {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 16px;
  margin: 30px 0 0;
  padding-bottom: 22px;
  border-bottom: 1px solid var(--rule);
}

.actfilter__field { display: flex; flex-direction: column; gap: 6px; }

.actfilter__k {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: none;
  color: var(--ink-muted);
}

.actfilter__sel {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 8px;
  padding: 7px 10px;
  min-width: 150px;
}

.actfilter__sel:focus { outline: none; border-color: var(--accent); }
.actfilter__sel[multiple] { min-height: 64px; padding: 6px 8px; }
.actfilter__actions { display: inline-flex; align-items: center; gap: 12px; margin-left: auto; }

/* ── >500 cap banner ── */
.actcap {
  margin: 22px 0 0;
  border: 1px solid var(--warn);
  border-radius: 9px;
  padding: 9px 13px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--warn);
  background: var(--paper-card);
}

/* ── cross-app row: 4-column grid (time / app / body / actor) ── */
.actrow--cross { grid-template-columns: 120px 160px 1fr auto; }

.actrow__app { display: flex; align-items: flex-start; min-width: 0; padding-top: 2px; }

.actrow__app-link {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--accent);
  text-decoration: none;
  word-break: break-all;
}

.actrow__app-link:hover { color: var(--ink); text-decoration: underline; }

.actrow__app--cross {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: none;
  color: var(--ink-muted);
}

/* ═══════════════════════════════════════════════════════════════════════
 * Species profiles (P5) — `GET /species`. The metrics strip (.spmetrics) +
 * the profiles feed (.spfeed / .sprow). Read-only (no flag/unflag controls).
 * Same editorial idiom; webadmin class namespace, NOT the Streamlit one.
 * ═══════════════════════════════════════════════════════════════════════ */

/* ── metrics strip ── */
.spmetrics {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  margin: 30px 0 0;
  border-top: 1px solid var(--rule);
}

.spmetric { padding: 22px 28px 22px 0; border-right: 1px solid var(--rule-soft); }
.spmetric:last-child { border-right: 0; }

.spmetric__v {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 32px;
  line-height: 0.95;
  letter-spacing: -0.02em;
}

.spmetric__l {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: none;
  color: var(--ink-muted);
  margin-top: 11px;
}

/* ── profiles feed ── */
.spfoot { margin-top: 26px; }
.spfeed { margin: 12px 0 0; border-top: 1px solid var(--rule); }

.spfeed__head,
.sprow {
  display: grid;
  grid-template-columns: 2.4fr 1.6fr 0.9fr 1.1fr 0.7fr;
  gap: 0 18px;
  align-items: center;
  padding: 14px 0;
  border-bottom: 1px solid var(--rule-soft);
}

.spfeed__head {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: none;
  color: var(--ink-muted);
  padding: 0 0 12px;
}

.sprow__canonical {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 17px;
  letter-spacing: -0.01em;
  line-height: 1.15;
}

.sprow__sci { font-family: var(--body); font-style: italic; font-size: 13px; color: var(--ink-muted); margin-top: 3px; }
.sprow__common { font-size: 14px; color: var(--ink-soft); }
.sprow__seen { font-family: var(--mono); font-size: 11px; color: var(--ink-muted); }

.spflag {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: none;
  color: var(--danger);
  border: 1px solid var(--danger);
  border-radius: 999px;
  padding: 2px 9px;
}

/* ───────────────────────────────────────────── responsive */

@media (max-width: 720px) {
  .app { display: block; }   /* single-column on mobile; block flow avoids the grid min-content widening of .main */
  .side, .main { min-width: 0; }
  .tabs { flex-wrap: wrap; gap: 12px 16px; }
  .top { flex-wrap: wrap; gap: 10px; }
  .side { flex-direction: row; flex-wrap: wrap; gap: 20px; border-right: 0; border-bottom: 1px solid var(--rule); }
  .acct { margin-top: 0; border-top: 0; padding-top: 0; }
  .main { padding: 24px 22px 48px; }
  .fleet { grid-template-columns: repeat(2, 1fr); }
  .appcols { grid-template-columns: 1fr; }
  .subcards { grid-template-columns: 1fr; }
  .appcol { border-right: 0; padding: 22px 0; border-bottom: 1px solid var(--rule-soft); }
  .appcol:last-child { padding-left: 0; }
  .actrow { grid-template-columns: 1fr; gap: 6px 0; }
  .actrow--cross { grid-template-columns: 1fr; }
  .actrow__actor { text-align: left; }
  .actfilter__actions { margin-left: 0; }
  .spmetric { border-right: 0; padding: 16px 0; border-bottom: 1px solid var(--rule-soft); }
  .spfeed__head { display: none; }
  .sprow { grid-template-columns: 1fr; gap: 4px 0; }
  .edcard__controls { gap: 14px; }
  .edpublish { flex-direction: column; align-items: stretch; }
  .wmchosen { flex-direction: column; align-items: flex-start; }
}

/* ── Assets tab — GCS-backed media gallery (In use / Not in use) ───────── */
.assetbar { display: flex; align-items: center; justify-content: space-between; margin: 22px 0 0; }
.assetbar__stamp { font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; color: var(--ink-muted); text-transform: none; }
.assetbar__filter { display: inline-flex; gap: 16px; }
.assetbar__f { font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; text-transform: none; color: var(--ink-muted); text-decoration: none; padding-bottom: 2px; border-bottom: 1px solid transparent; }
.assetbar__f:hover { color: var(--ink); }
.assetbar__f.on { color: var(--accent); border-bottom-color: var(--accent); }

.assetgroup { margin: 30px 0 0; }
.assetgroup__head { display: flex; align-items: baseline; gap: 12px; margin: 0 0 14px; padding-bottom: 8px; border-bottom: 1px solid var(--rule); font-family: var(--serif); font-weight: 500; font-size: 17px; color: var(--ink); }
.assetgroup__store { font-family: var(--mono); font-size: 9px; letter-spacing: 0.1em; text-transform: none; color: var(--ink-muted); border: 1px solid var(--rule-soft); border-radius: 3px; padding: 1px 5px; }
.assetgroup__counts { margin-left: auto; font-family: var(--mono); font-size: 11px; letter-spacing: 0.04em; color: var(--ink-muted); }

.assetgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 16px; }
.assettile { margin: 0; }
.assettile__link { display: block; position: relative; border: 1px solid var(--rule); border-radius: 6px; overflow: hidden; background: var(--paper-card); aspect-ratio: 1 / 1; }
.assettile__img { width: 100%; height: 100%; object-fit: contain; display: block; }
.assettile__play { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 28px; color: #fff; background: rgba(0, 0, 0, 0.25); }
.assettile__cap { display: flex; flex-direction: column; gap: 3px; margin-top: 7px; }
.assettile__name { font-family: var(--mono); font-size: 11px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.assettile__meta { font-family: var(--mono); font-size: 10px; color: var(--ink-muted); }
.assettile__used { font-family: var(--mono); font-size: 10px; color: var(--ink-muted); line-height: 1.35; word-break: break-word; }

.assetbadge { align-self: flex-start; font-family: var(--mono); font-size: 9px; letter-spacing: 0.08em; text-transform: none; padding: 1px 6px; border-radius: 3px; border: 1px solid; }
.assetbadge--ok { color: var(--ok); border-color: var(--ok); }
.assetbadge--warn { color: var(--warn); border-color: var(--warn); }
.assetbadge--info { color: var(--info); border-color: var(--info); }

/* =========================================================================
 * Content tab (app_content.html) — read-only baked-content library.
 * Components: .ctnav sticky section pills · .ctsec/.ctsrc section chrome ·
 * .persona strip · .mail* email previews · .push* notification previews ·
 * .bub*/.chatq chat-nudge bubbles · .kvrow key/value rows · .prompt reader ·
 * .quizcard quiz steps · .digest tiles · .keywords chips · .ctcards grid.
 * ========================================================================= */
.ctnav{position:sticky;top:0;z-index:30;display:flex;flex-wrap:wrap;gap:6px;
  padding:10px 0 12px;background:var(--paper);border-bottom:1px solid var(--rule-soft);margin-bottom:22px}
.ctnav a{font-family:var(--mono);font-size:11.5px;letter-spacing:.02em;text-decoration:none;
  color:var(--ink-soft);border:1px solid var(--rule);border-radius:999px;padding:5px 11px;background:var(--paper-card)}
.ctnav a b{color:var(--ink);font-weight:500}
.ctnav a:hover{border-color:var(--accent-soft);color:var(--accent)}
.ctnav a .n{color:var(--ink-muted);margin-left:4px}

.ctsec{margin:0 0 34px}
.ctsrc{font-family:var(--mono);font-size:11px;color:var(--ink-muted);margin:6px 0 14px}
.ctsrc code{font-size:11px;color:var(--ink-soft)}
.ctsrc .bake{color:var(--accent)}
.ctcards{display:grid;grid-template-columns:repeat(auto-fill,minmax(340px,1fr));gap:14px}
.ctcards .edcard{margin:0}
.ctcols{display:grid;grid-template-columns:repeat(auto-fit,minmax(330px,1fr));gap:14px}

.persona{display:flex;gap:16px;align-items:flex-start;border:1px solid var(--rule);border-radius:12px;
  background:var(--paper-card);padding:16px 18px}
.persona__av{width:54px;height:54px;border-radius:50%;background:#3f4d36;color:#e9efe2;display:flex;
  align-items:center;justify-content:center;font-family:'Fraunces',serif;font-size:24px;flex:0 0 auto}
.persona__name{font-family:'Fraunces',serif;font-size:19px;margin:0}
.persona__meta{font-family:var(--mono);font-size:11px;color:var(--ink-muted);margin:2px 0 8px}
.sig{display:flex;flex-wrap:wrap;gap:6px;margin:8px 0 0}
.sig span{font-family:'Newsreader',serif;font-style:italic;font-size:13.5px;color:var(--ink-soft);
  border:1px solid var(--rule-soft);border-radius:999px;padding:3px 10px;background:var(--paper)}
.voicebox{margin-top:10px;border-top:1px dashed var(--rule);padding-top:10px;font-size:13px;color:var(--ink-soft)}
.voicebox code{font-family:var(--mono);font-size:11px}

.mailgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(330px,1fr));gap:14px}
.mail{border:1px solid var(--rule);border-radius:12px;background:var(--paper-card);overflow:hidden;display:flex;flex-direction:column}
.mail__bar{display:flex;align-items:center;gap:8px;padding:9px 13px;border-bottom:1px solid var(--rule-soft);background:var(--paper)}
.mail__day{font-family:var(--mono);font-size:10.5px;color:var(--paper);background:var(--ink);border-radius:4px;padding:2px 7px}
.mail__seg{font-family:var(--mono);font-size:10.5px;color:var(--ink-soft);border:1px solid var(--rule);border-radius:4px;padding:2px 7px}
.mail__id{margin-left:auto;font-family:var(--mono);font-size:10.5px;color:var(--ink-muted)}
.mail__body{padding:13px 15px 15px;display:flex;flex-direction:column;flex:1}
.mail__from{font-family:var(--mono);font-size:10.5px;color:var(--ink-muted);margin:0 0 6px}
.mail__subj{font-family:'Fraunces',serif;font-size:17px;font-weight:500;margin:0 0 2px;color:var(--ink)}
.mail__pre{font-size:12.5px;color:var(--ink-muted);margin:0 0 10px;font-style:italic}
.mail__txt{font-family:'Newsreader',serif;font-size:14px;line-height:1.5;color:var(--ink-soft)}
.mail__txt p{margin:0 0 9px}
.mail__cta{margin-top:auto;padding-top:6px;display:flex;align-items:center;gap:10px}
.mail__cta b{display:inline-block;font-size:12.5px;font-weight:500;color:var(--paper-card);background:var(--accent);
  border-radius:999px;padding:6px 14px}
.mail__cta code{font-family:var(--mono);font-size:10.5px;color:var(--ink-muted)}

.pushwrap{max-width:520px}
.push{display:flex;gap:10px;align-items:flex-start;border:1px solid var(--rule);border-radius:16px;
  background:var(--paper-card);box-shadow:0 1px 4px rgba(0,0,0,.06);padding:11px 14px;margin:10px 0}
.push--ghost{border-style:dashed;opacity:.75}
.push__icon{width:34px;height:34px;border-radius:8px;background:#3f4d36;display:flex;align-items:center;justify-content:center;flex:0 0 auto}
.push__icon svg{width:19px;height:19px;stroke:#e9efe2;fill:none;stroke-width:1.6}
.push__t{font-size:13.5px;font-weight:600;margin:0;color:var(--ink)}
.push__b{font-size:13px;color:var(--ink-soft);margin:1px 0 0}
.push__dl{font-family:var(--mono);font-size:10.5px;color:var(--ink-muted)}
.push__app{font-family:var(--mono);font-size:9.5px;letter-spacing:.08em;color:var(--ink-muted);text-transform:none}
.push__now{margin-left:auto;font-size:11px;color:var(--ink-muted)}

.chatbox{border:1px solid var(--rule);border-radius:12px;background:var(--paper-card);padding:16px 16px 12px}
.bub{max-width:78%;border-radius:14px;padding:8px 12px;margin:0 0 8px;font-size:13.5px;line-height:1.45}
.bub--a{background:var(--paper);border:1px solid var(--rule-soft);color:var(--ink-soft);border-bottom-left-radius:4px}
.bub--u{background:var(--accent);color:var(--paper-card);margin-left:auto;border-bottom-right-radius:4px}
.bub__ms{display:block;font-family:var(--mono);font-size:9.5px;color:var(--ink-muted);margin-top:3px}
.chatq{display:flex;flex-wrap:wrap;gap:6px;margin:10px 0 4px}
.chatq span{font-size:12.5px;color:var(--accent);border:1px solid var(--accent-soft);border-radius:999px;padding:4px 11px;background:var(--paper)}

.kvrow{display:grid;grid-template-columns:140px 1fr;gap:6px 14px;font-size:13.5px;padding:7px 0;border-bottom:1px solid var(--rule-soft)}
.kvrow:last-child{border-bottom:0}
.kvrow .k{font-family:var(--mono);font-size:11px;color:var(--ink-muted);padding-top:2px}
.kvrow .v{color:var(--ink-soft)}
.kvrow .v b{color:var(--ink);font-weight:500}

.prompt{border:1px solid var(--rule);border-radius:12px;background:var(--paper-card);padding:4px 18px 14px;
  font-family:var(--mono);font-size:12px;line-height:1.62;color:var(--ink-soft);overflow-x:auto}
.prompt h4{font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:none;color:var(--accent);margin:16px 0 4px}
.prompt p{margin:0 0 6px;white-space:pre-wrap}

.quiz{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:14px}
.quizcard{border:1px solid var(--rule);border-radius:12px;background:var(--paper-card);padding:13px 15px}
.quizcard__step{font-family:var(--mono);font-size:10.5px;letter-spacing:.06em;text-transform:none;color:var(--accent);margin:0 0 8px}
.quizcard .kvrow{grid-template-columns:96px 1fr;font-size:13px}

.digest{display:flex;gap:12px;flex-wrap:wrap;margin-top:10px}
.digest .tile{border:1px solid var(--rule);border-radius:10px;background:var(--paper);padding:10px 16px;min-width:110px}
.digest .tile b{font-family:'Fraunces',serif;font-size:21px;font-weight:500;display:block}
.digest .tile span{font-family:var(--mono);font-size:10.5px;color:var(--ink-muted)}
.digest__summary{font-family:'Newsreader',serif;font-size:15px;color:var(--ink-soft);margin:4px 0 0}

.keywords{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}
.keywords code{font-size:11.5px;border:1px solid var(--rule);border-radius:999px;padding:3px 9px;background:var(--paper-card);color:var(--ink-soft)}

details.more summary{cursor:pointer;font-family:var(--mono);font-size:11.5px;color:var(--accent);margin:10px 0}

/* ── Swipe library — paste-to-library bar (feed-link ingest) ───────────── */
.pastebar { margin: 22px 0 0; border: 1px solid var(--rule); border-radius: 12px;
  background: var(--paper-card); padding: 15px 17px 13px; }
.pastebar__label { font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em;
  text-transform: none; color: var(--ink-muted); margin: 0 0 9px; }
.pastebar__row { display: flex; gap: 10px; }
.pastebar__input { flex: 1; min-width: 0; font-family: var(--mono); font-size: 13px;
  color: var(--ink); background: var(--paper); border: 1px solid var(--rule);
  border-radius: 8px; padding: 9px 12px; outline: none; }
.pastebar__input:focus { border-color: var(--accent); }
.pastebar__input::placeholder { color: var(--ink-muted); }
.pastebar__save { font-family: var(--mono); font-size: 12px; letter-spacing: 0.04em;
  font-weight: 500; color: var(--paper-card); background: var(--accent); border: 0;
  border-radius: 999px; padding: 9px 20px; cursor: pointer; white-space: nowrap; }
.pastebar__save:disabled { opacity: 0.55; cursor: default; }
.pastebar__hint { font-family: var(--mono); font-size: 10.5px; color: var(--ink-muted);
  margin: 9px 0 0; }
.pastebar__hint b { color: var(--ink-soft); font-weight: 500; }
.pastebar__progress { font-family: var(--mono); font-size: 11px; color: var(--accent);
  margin: 9px 0 0; }
.retrylink { font-family: var(--mono); font-size: 10px; color: var(--accent);
  background: none; border: 0; padding: 0; cursor: pointer; text-align: left; }

@media (max-width: 720px) {
  .pastebar__row { flex-direction: column; }
  .pastebar__save { padding: 11px 20px; }
}

/* ── Swipe library — Deleted tab (soft delete, 30-day purge) ───────────── */
.viewtabs { margin: 24px 0 0; }
.delnote { font-family: var(--mono); font-size: 11px; color: var(--ink-muted);
  margin: 16px 0 0; }
.dellink { color: var(--ink-muted); }
.dellink:hover { color: var(--warn); }
.assettile--deleted .assettile__link { opacity: 0.45; filter: grayscale(0.7); }
.confirmbox { display: none; position: fixed; inset: 0; z-index: 300;
  background: rgba(12, 11, 9, 0.55); align-items: center; justify-content: center; }
.confirmbox.on { display: flex; }
.confirmbox__card { background: var(--paper-card); border: 1px solid var(--rule);
  border-radius: 12px; padding: 20px 22px; max-width: 380px; margin: 0 16px; }
.confirmbox__title { font-family: var(--serif); font-size: 18px; color: var(--ink);
  margin: 0 0 6px; }
.confirmbox__body { font-family: var(--mono); font-size: 11.5px; color: var(--ink-soft);
  line-height: 1.5; margin: 0 0 14px; }
.confirmbox__row { display: flex; gap: 10px; justify-content: flex-end; }
.confirmbox__cancel { font-family: var(--mono); font-size: 12px; background: none;
  border: 1px solid var(--rule); border-radius: 999px; padding: 7px 16px;
  color: var(--ink-soft); cursor: pointer; }
.confirmbox__go { font-family: var(--mono); font-size: 12px; font-weight: 500;
  background: var(--warn); border: 0; border-radius: 999px; padding: 7px 16px;
  color: var(--paper-card); cursor: pointer; }

/* paste bar inline error (clipboard guard messages) */
.pastebar__error { font-family: var(--mono); font-size: 11px; color: var(--warn);
  margin: 9px 0 0; }

/* ── Ad-creative reskin — detail-page entry + brand-map review ──────────── */
.reskinbar { display: flex; gap: 10px; align-items: center; margin-top: 10px; }
.reskinseg { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  border: 1px solid var(--rule); border-radius: 10px; background: var(--paper-card);
  padding: 11px 14px; margin: 8px 0; }
.reskinseg--hard { opacity: 0.6; }
.reskinseg__pick { display: inline-flex; align-items: center; gap: 8px; }
.reskinseg__time { font-family: var(--mono); font-size: 11px; color: var(--ink-muted); }
.reskinseg__desc { font-family: var(--body); font-size: 13px; color: var(--ink-soft);
  flex: 1; min-width: 140px; }
.reskinseg__swap { font-family: var(--mono); font-size: 11px; color: var(--ink-soft); }
.reskinseg__flag { font-family: var(--mono); font-size: 11px; color: var(--warn); }

/* ── Analytics control bar + multi-app picker (shared) ──────────────────────
   The pill/select primitives for the RC-parity analytics area. Used by the chart
   control bar (analytics_charts.html), the filter/segment/metric/range/compare
   selects (_control_bar.html) and the portfolio multi-app picker
   (analytics_portfolio.html). Consolidated here from per-template <style> blocks. */
.an-bar2 { display: flex; flex-wrap: wrap; gap: 7px; align-items: center; margin: 6px 0 14px; }
.an-pill { font-family: var(--mono); font-size: 12px; display: inline-flex; align-items: center;
  gap: 5px; padding: 6px 11px; border-radius: 8px; border: 1px solid var(--rule);
  background: var(--paper-card, #fffdf7); color: var(--ink-soft); cursor: pointer;
  white-space: nowrap; transition: border-color .12s, color .12s; }
.an-pill:hover { border-color: var(--accent); color: var(--ink); }
.an-pill--solid { background: var(--accent); color: #fff; border-color: var(--accent); }
.an-pill--solid:disabled { opacity: .45; cursor: not-allowed; }
.an-car { opacity: .55; font-size: 10px; }
.an-select { appearance: none; -webkit-appearance: none; cursor: pointer;
  max-width: 220px; overflow: hidden; text-overflow: ellipsis; }
.an-filter-wrap { display: inline-flex; }
.an-multi { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.an-pick-cell { text-align: center; }
.an-pick { cursor: pointer; }

/* ── Unified date picker shell (date-picker-p0) ─────────────────────────────
   Reusable Meta Ads-style range pill + popover. JS owns the state, calendar
   rendering, sticky localStorage, and Apply navigation; CSS here keeps it
   within the existing admin token system. */
.af-dp { position: relative; display: inline-flex; }
.af-dp__trigger {
  min-height: 36px;
  padding-right: 13px;
  gap: 8px;
  color: var(--ink);
}
.af-dp__trigger[aria-expanded="true"] {
  border-color: var(--accent);
  color: var(--accent);
}
.af-dp__trigger-label {
  display: inline-block;
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.af-dp__caret { font-size: 10px; color: currentColor; }

.af-dp__popover {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  z-index: 60;
  width: min(720px, calc(100vw - 28px));
  background: var(--paper-card);
  border: 1px solid var(--rule);
  border-radius: 14px;
  box-shadow: 0 20px 40px rgba(9, 9, 13, 0.16);
}
.af-dp__popover[hidden] { display: none; }

.af-dp__shell {
  display: flex;
  align-items: stretch;
  min-width: 0;
}

.af-dp__presets {
  width: 184px;
  flex: 0 0 184px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px;
  border-right: 1px solid var(--rule);
  background: var(--paper);
}

.af-dp__preset {
  width: 100%;
  text-align: left;
  font-family: var(--body);
  font-size: 13px;
  color: var(--ink-soft);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 10px;
  padding: 8px 10px;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.af-dp__preset:hover {
  background: var(--paper-card);
  border-color: var(--rule);
  color: var(--ink);
}
.af-dp__preset.is-active {
  background: var(--highlight);
  border-color: var(--accent);
  color: var(--accent);
  font-weight: 600;
}

.af-dp__body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 14px;
}

.af-dp__preview {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--rule-soft);
}
.af-dp__preview-label {
  font-family: var(--serif);
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.af-dp__preview-sub {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-muted);
}

.af-dp__calendars {
  display: flex;
  gap: 12px;
  align-items: flex-start;
}
.af-dp__calendar {
  flex: 1 1 0;
  min-width: 0;
  border: 1px solid var(--rule-soft);
  border-radius: 12px;
  background: var(--paper-card);
  padding: 12px;
}

.af-dp__monthbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 10px;
}
.af-dp__monthtitle {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--ink);
  text-transform: none;
}
.af-dp__nav {
  width: 28px;
  height: 28px;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: var(--paper);
  color: var(--ink-soft);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
}
.af-dp__nav:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.af-dp__nav--ghost {
  opacity: 0;
  pointer-events: none;
}

.af-dp__dowgrid,
.af-dp__daygrid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 4px;
}
.af-dp__dow {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--ink-muted);
  text-align: center;
  padding: 2px 0 6px;
}
.af-dp__blank { min-height: 34px; }
.af-dp__day {
  min-height: 34px;
  border: 1px solid transparent;
  border-radius: 10px;
  background: transparent;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 12px;
  cursor: pointer;
}
.af-dp__day:hover {
  background: var(--paper);
  border-color: var(--rule);
}
.af-dp__day.is-other {
  color: var(--ink-muted);
  opacity: 0.6;
}
.af-dp__day.is-in-range {
  background: var(--highlight);
  border-color: transparent;
  color: var(--accent);
}
.af-dp__day.is-edge {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-weight: 600;
}

.af-dp__actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding-top: 12px;
  border-top: 1px solid var(--rule-soft);
}
.af-dp__btn {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: none;
  border-radius: 999px;
  padding: 8px 14px;
  cursor: pointer;
}
.af-dp__btn--ghost {
  color: var(--ink-soft);
  background: transparent;
  border: 1px solid var(--rule);
}
.af-dp__btn--ghost:hover {
  border-color: var(--ink);
  color: var(--ink);
}
.af-dp__btn--accent {
  color: #fff;
  background: var(--accent);
  border: 1px solid var(--accent);
}
.af-dp__btn--accent:hover {
  background: var(--accent-soft);
  border-color: var(--accent-soft);
}
.af-dp__btn--accent:disabled,
.af-dp__btn--accent:disabled:hover {
  opacity: 0.45;
  cursor: not-allowed;
  background: var(--accent);
  border-color: var(--accent);
}


/* ============================================================
   ANALYTICS AREA — consolidated from per-template <style> blocks.
   Shared shell + per-page component styles; every admin style now
   lives in this design-system stylesheet. */

.an-crumb {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-muted);
  margin: 0 0 14px;
}
.an-crumb a { color: var(--ink-muted); text-decoration: none; }
.an-crumb a:hover { color: var(--accent); }
.an-crumb b { color: var(--ink); font-weight: 500; }
.an-appshell {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 16px;
}
.an-chartnav {
  background: var(--paper-card);
  border: 1px solid var(--rule);
  border-radius: 12px;
  padding: 10px 8px;
  align-self: start;
  position: sticky;
  top: 18px;
}
.an-grp {
  font-family: var(--mono);
  font-size: 10px;
  text-transform: none;
  letter-spacing: .1em;
  color: var(--ink-muted);
  padding: 10px 10px 4px;
}
.an-cnav {
  display: block;
  padding: 6px 10px;
  border-radius: 7px;
  font-size: 13px;
  color: var(--ink-soft);
  text-decoration: none;
  transition: background .12s, color .12s;
}
.an-cnav:hover { background: var(--rule-soft); color: var(--ink); }
.an-cnav.on { background: var(--highlight); color: var(--accent); font-weight: 500; }
.an-cnav--disabled {
  color: var(--ink-muted);
  cursor: default;
  opacity: .5;
}
.an-pane {
  background: var(--paper-card);
  border: 1px solid var(--rule);
  border-radius: 12px;
  padding: 18px 20px;
}
.an-panehead { margin-bottom: 10px; }
.an-panetitle {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 22px;
  margin: 0;
}
.an-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-soft);
  margin-top: 8px;
}
.an-legend span { display: flex; align-items: center; gap: 5px; }
.an-sw { display: inline-block; width: 9px; height: 9px; border-radius: 2px; }
.an-sw--new { background: var(--ok); }
.an-sw--resub { background: var(--chart-mint); }
.an-sw--expansion { background: var(--info); }
.an-sw--contraction { background: var(--chart-gold); }
.an-sw--churned { background: var(--danger); }
.an-kpis {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
  margin-top: 26px;
}
.an-kpi {
  background: var(--paper-card);
  border: 1px solid var(--rule);
  border-radius: 12px;
  padding: 16px 18px;
}
.an-kpi__lab {
  font-family: var(--mono);
  font-size: 11px;
  text-transform: none;
  letter-spacing: .08em;
  color: var(--ink-muted);
}
.an-kpi__val {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 28px;
  margin: 6px 0 2px;
  letter-spacing: -.02em;
}
.an-kpi__sub {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-muted);
}
.an-tcard {
  background: var(--paper-card);
  border: 1px solid var(--rule);
  border-radius: 12px;
  overflow: hidden;
}
.an-tcard__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: 16px 20px 12px;
  border-bottom: 1px solid var(--rule);
}
.an-tcard__title {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 16px;
  margin: 0;
}
.an-tcard__cap {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-muted);
  margin: 2px 0 0;
}
.an-tbl {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
}
.an-tbl thead th {
  font-family: var(--mono);
  font-size: 10.5px;
  text-transform: none;
  letter-spacing: .06em;
  color: var(--ink-muted);
  font-weight: 400;
  padding: 10px 16px;
  text-align: left;
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
}
.an-tbl thead th.r { text-align: right; }
.an-tbl tbody td {
  padding: 12px 16px;
  border-bottom: 1px solid var(--rule-soft);
  vertical-align: middle;
}
.an-tbl tbody td.r { text-align: right; }
.an-tbl tbody tr { cursor: pointer; transition: background .12s; }
.an-tbl tbody tr:hover { background: var(--highlight); }
.an-tbl tbody tr:last-child td { border-bottom: none; }
.an-app-cell { display: flex; align-items: center; gap: 10px; }
.an-av {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border-radius: 7px;
  display: grid;
  place-items: center;
  font-family: var(--serif);
  font-weight: 600;
  font-size: 11px;
  color: #fff;
}
.an-nm { font-family: var(--serif); font-size: 15px; font-weight: 500; }
.an-bid { font-family: var(--mono); font-size: 10.5px; color: var(--ink-muted); }
.an-mono { font-family: var(--mono); font-size: 12.5px; }
.an-roas { font-weight: 500; }
.an-tag {
  font-family: var(--mono);
  font-size: 10.5px;
  padding: 3px 9px;
  border-radius: 999px;
  white-space: nowrap;
}
.an-tag--scale { background: var(--ok-soft); color: var(--ok); }
.an-tag--steady { background: var(--rule-soft); color: var(--ink-muted); }
.an-tag--watch { background: var(--warn-soft); color: var(--warn-ink); }
.an-tag--fix { background: var(--danger-soft); color: var(--danger); }
.an-empty {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-muted);
  text-align: center;
  padding: 32px;
}
.an-pane-cap {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-muted);
  margin: 0;
}
/* ── Installs panel (installs-panel-v1) ──────────────────────────────────────
   The KPI row carries three cards here (the Analytics portfolio's carries two),
   so this modifier widens the grid rather than letting the third card wrap onto
   a half-empty row. Collapses to one column on narrow viewports. */
.an-kpis--3 { grid-template-columns: repeat(3, 1fr); }
/* Grid items default to `min-width: auto`, so a long KPI subtitle ("Store
   truth through 2026-07-22 · -31% vs prior 7d") sets a min-content floor that
   widens the track and, through .main, the page. Let the cards shrink and let
   the text wrap instead. */
.an-kpis--3 > .an-kpi { min-width: 0; }
@media (max-width: 1200px) {
  .an-kpis--3 { grid-template-columns: 1fr; }
}
/*
   Single-series daily-shape sparkline + a change chip. One accent hue for the
   marks; every number stays in a text token, never in the series colour. The
   chip pairs its colour with a sign glyph (+/-) so direction is never
   colour-alone. */
.in-spark {
  display: flex;
  align-items: flex-end;
  gap: 2px;              /* the 2px surface gap between adjacent fills */
  height: 22px;
  min-width: 72px;
}
.in-spark__bar {
  flex: 1 1 auto;
  min-width: 3px;
  background: var(--accent);
  border-radius: 2px 2px 0 0;
  opacity: .85;
}
.in-delta {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
}
.in-delta--up { color: var(--ok); }
.in-delta--down { color: var(--danger); }
.in-delta--flat { color: var(--ink-muted); }
.in-terr {
  font-size: 11px;
  color: var(--ink-muted);
}
.in-note {
  font-family: var(--mono);
  font-size: 12px;
  margin: 18px 0 0;
  padding: 10px 12px;
  border-radius: 8px;
}
.in-note--warn {
  background: var(--warn-soft);
  color: var(--warn-ink);
}
/* Live (first-party events) columns — tinted so the eye can tell at a glance
   which numbers are real-time and which are Apple's lagging report. The tint
   is the accent at low alpha, not a second hue: the two column groups are the
   same measure from different sources, not different series. */
/* The two-source layout runs to 12 columns. This scroller is what keeps the
   trailing columns (Redownloads / Updates / Top market) REACHABLE — without
   it they are clipped by the card and simply unreadable.
   Note it does not stop the page itself scrolling sideways below ~1400px:
   `.main` is a grid item whose `min-width: auto` lets wide content widen the
   track. That is pre-existing shell behaviour, not specific to this page —
   the 12-column /analytics leaderboard overflows the same way at 1180/1280
   and is clean at 1440. Fixing it properly is a shell change that should be
   made once, for every wide table, not smuggled in here. */
.in-tscroll { overflow-x: auto; min-width: 0; }
.in-tscroll > .an-tbl { min-width: 1180px; }   /* 12 cols; below this, scroll */
.in-col-live { background: color-mix(in srgb, var(--accent) 5%, transparent); }
.an-kpi--live { border-color: var(--accent); }
.in-spark--live .in-spark__bar { opacity: 1; }
.in-badge {
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--accent);
  background: var(--highlight);
  border-radius: 4px;
  padding: 1px 5px;
  margin-left: 4px;
}
.ov-kpis {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin-bottom: 24px;
}
.ov-kpi {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 10px;
  padding: 14px 16px;
}
.ov-kpi--beacon {
  opacity: .6;
}
.ov-kpi__lab {
  font-family: var(--mono);
  font-size: 10.5px;
  text-transform: none;
  letter-spacing: .08em;
  color: var(--ink-muted);
  margin-bottom: 4px;
}
.ov-kpi__val {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 26px;
  letter-spacing: -.02em;
  margin-bottom: 2px;
}
.ov-kpi__val--dash {
  color: var(--ink-muted);
  font-size: 22px;
}
.ov-kpi__sub {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--ink-muted);
}
.ov-kpi__sub--beacon {
  font-style: italic;
}
.ov-events-head {
  margin-bottom: 10px;
}
.ov-events-title {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 16px;
  margin: 0 0 2px;
}
.ov-events-cap {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-muted);
  margin: 0 0 10px;
}
.ov-tcard {
  border: 1px solid var(--rule);
  border-radius: 10px;
  overflow: hidden;
}
.ov-evtype {
  font-family: var(--mono);
  font-size: 10.5px;
  padding: 2px 8px;
  border-radius: 999px;
  white-space: nowrap;
  background: var(--rule-soft);
  color: var(--ink-soft);
}
.ov-evtype--subscribed,
.ov-evtype--did-renew { background: var(--ok-soft); color: var(--ok); }
.ov-evtype--expired,
.ov-evtype--did-fail-to-renew { background: var(--danger-soft); color: var(--danger); }
.ov-evtype--refund { background: var(--warn-soft); color: var(--warn-ink); }
.pa-eyebrow {
  font-family: var(--mono);
  font-size: 11px;
  text-transform: none;
  letter-spacing: .14em;
  color: var(--accent);
  margin: 0 0 4px;
}
.pa-h {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 24px;
  margin: 0 0 4px;
}
.pa-sub {
  color: var(--ink-soft);
  font-size: 14px;
  margin: 0 0 18px;
  max-width: 70ch;
}
.pa-kpis {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-bottom: 22px;
}
.pa-kpi {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 12px;
  padding: 13px 14px 10px;
}
.pa-kpi-lab {
  font-family: var(--mono);
  font-size: 11px;
  text-transform: none;
  letter-spacing: .05em;
  color: var(--ink-muted);
}
.pa-kpi-val {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 22px;
  margin: 5px 0 2px;
}
.pa-kpi-val--sm { font-size: 15px; }
.pa-kpi-d {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-muted);
}
.pa-pos { color: var(--ok); }
.pa-warn { color: var(--chart-gold); }
.pa-dim { color: var(--ink-muted); }
.pa-tcard {
  border: 1px solid var(--rule);
  border-radius: 12px;
  overflow: hidden;
  margin-bottom: 16px;
}
.pa-tcard-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: 14px 18px 10px;
  border-bottom: 1px solid var(--rule-soft);
}
.pa-tcard-title {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 16px;
  margin: 0 0 2px;
}
.pa-tcard-cap {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-muted);
  margin: 0;
}
.pa-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.pa-th {
  font-family: var(--mono);
  font-size: 10.5px;
  text-transform: none;
  letter-spacing: .05em;
  color: var(--ink-muted);
  text-align: right;
  padding: 8px 14px;
  border-bottom: 1px solid var(--rule);
  font-weight: 400;
  white-space: nowrap;
}
.pa-th--left { text-align: left; }
.pa-td {
  padding: 11px 14px;
  text-align: right;
  border-bottom: 1px solid var(--rule-soft);
  font-family: var(--mono);
  font-size: 13px;
}
.pa-td--left { text-align: left; font-family: var(--body); }
.pa-table tbody tr:last-child .pa-td { border-bottom: none; }
.pa-table tbody tr:hover { background: var(--highlight); }
.pa-tag {
  font-family: var(--mono);
  font-size: 10.5px;
  padding: 3px 8px;
  border-radius: 999px;
  white-space: nowrap;
}
.pa-tag--match { background: var(--ok-soft); color: var(--ok); }
.pa-tag--review { background: var(--warn-soft); color: var(--chart-gold); }
.pa-tag--off { background: var(--danger-soft); color: var(--danger); }
.pa-empty {
  padding: 28px 18px;
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink-muted);
  text-align: center;
}
.pa-empty code {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 5px;
  padding: 2px 6px;
  font-size: 12px;
}
.pa-card {
  border: 1px solid var(--rule);
  border-radius: 12px;
  padding: 16px 18px;
}
.pa-card--mt { margin-top: 16px; }
.pa-card-title {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 16px;
  margin: 0 0 2px;
}
.pa-card-cap {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-muted);
  margin: 0 0 12px;
}
.pa-ins {
  display: flex;
  gap: 11px;
  padding: 11px 0;
  border-top: 1px solid var(--rule-soft);
}
.pa-ic {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
}
.pa-ic--warn { background: var(--warn-soft); color: var(--warn-ink); }
.pa-ic--off  { background: var(--danger-soft); color: var(--danger); }
.pa-ins-tx {
  font-size: 14px;
  line-height: 1.45;
}
.pa-ins-tx b { font-weight: 500; }
.pa-ins-tx small {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-muted);
  display: block;
  margin-top: 1px;
}
.an-pane-sub {
  font-size: 12px;
  color: var(--ink-muted);
  margin: 4px 0 0;
}
.rtn-wrap {
  overflow-x: auto;
  margin-top: 14px;
}
.rtn-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--mono);
  font-size: 12px;
}
.rtn-th {
  padding: 8px 10px;
  text-align: right;
  font-weight: 500;
  color: var(--ink-muted);
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
}
.rtn-cohort-col, .rtn-size-col { text-align: left; }
.rtn-td {
  padding: 7px 10px;
  text-align: right;
  border-bottom: 1px solid var(--rule-soft);
}
.rtn-cohort-label {
  text-align: left;
  font-weight: 500;
  color: var(--ink);
}
.rtn-size {
  text-align: left;
  color: var(--ink-muted);
}
.rtn-cell {
  background-color: rgba(79, 122, 77, var(--rtn-alpha, 0));
  color: var(--ink);
  transition: background-color .15s;
}
.rtn-cell:hover { opacity: .85; cursor: default; }
.rtn-empty {
  margin-top: 28px;
  text-align: center;
  color: var(--ink-muted);
  font-size: 13px;
}
.rtn-empty-sub {
  font-size: 11px;
  margin-top: 6px;
  color: var(--ink-muted);
}
.cex-select-wrap { display: flex; align-items: center; gap: 6px; }
.cex-label { font-family: var(--mono); font-size: 11px; color: var(--ink-muted); }
.cex-select { cursor: pointer; }
.cex-beacon-notice {
  background: var(--highlight);
  border: 1px solid var(--rule);
  border-radius: 10px;
  padding: 14px 16px;
  font-size: 13px;
  color: var(--ink-soft);
  margin-top: 10px;
}
.cex-cell { background: var(--paper-card); }
.cex-cell--na { color: var(--ink-muted); }
.analytics-tbl .kpi { font-family: var(--mono); font-size: 14px; text-align: right; }
.analytics-tbl .muted { color: var(--ink-muted); }
.analytics-tbl .spark-cell { padding: 6px 12px; }
.analytics-tbl .bid { font-family: var(--mono); font-size: 13px; color: var(--ink-soft); }
svg.spark { display: block; }
.back-link { margin: 16px 0 24px; }
.back-link a { font-family: var(--mono); font-size: 12px; color: var(--ink-muted); text-decoration: none; letter-spacing: 0.08em; }
.back-link a:hover { color: var(--accent); }
.score-section { margin: 32px 0 0; padding-bottom: 28px; border-bottom: 1px solid var(--rule-soft); }
.score-section:last-child { border-bottom: 0; }
.score-h { font-family: var(--serif); font-size: 22px; font-weight: 400; margin: 0 0 12px; letter-spacing: -0.01em; }
.score-note { font-size: 13px; color: var(--ink-muted); margin: 0 0 16px; font-family: var(--mono); }
.score-note code { color: var(--ink-soft); }
.funnel { display: flex; flex-direction: column; gap: 8px; max-width: 640px; }
.funnel-row { display: grid; grid-template-columns: 160px 1fr 80px 60px; align-items: center; gap: 10px; }
.funnel-label { font-size: 13px; font-family: var(--mono); color: var(--ink-soft); }
.funnel-bar-wrap { height: 18px; background: var(--rule-soft); border-radius: 3px; overflow: hidden; }
.funnel-bar { height: 100%; background: var(--accent); border-radius: 3px; transition: width 0.3s; }
.funnel-count { font-family: var(--mono); font-size: 13px; text-align: right; color: var(--ink); }
.funnel-conv { font-family: var(--mono); font-size: 12px; color: var(--ink-muted); text-align: right; }
.ret-panel { display: flex; align-items: flex-start; gap: 32px; flex-wrap: wrap; }
.ret-stats { display: flex; gap: 24px; }
.ret-stat { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.ret-n { font-family: var(--serif); font-size: 28px; font-weight: 500; letter-spacing: -0.02em; }
.ret-l { font-family: var(--mono); font-size: 11px; letter-spacing: 0.14em; text-transform: none; color: var(--ink-muted); }
.ret-bars { display: flex; flex-direction: column; gap: 6px; min-width: 200px; }
.ret-bar-row { display: grid; grid-template-columns: 28px 1fr 40px; align-items: center; gap: 8px; }
.ret-bar-wrap { height: 10px; background: var(--rule-soft); border-radius: 2px; overflow: hidden; }
.ret-bar { height: 100%; background: var(--ok); border-radius: 2px; }
.ret-pct { font-family: var(--mono); font-size: 12px; text-align: right; }
svg.ret-curve { display: block; }
.act-panel { display: flex; align-items: center; gap: 32px; flex-wrap: wrap; }
.act-big { display: flex; flex-direction: column; gap: 4px; }
.act-n { font-family: var(--serif); font-size: 48px; font-weight: 500; letter-spacing: -0.03em; color: var(--ok); line-height: 1; }
.act-l { font-family: var(--mono); font-size: 12px; letter-spacing: 0.12em; text-transform: none; color: var(--ink-muted); }
.act-meta { font-size: 14px; color: var(--ink-soft); }

/* analytics area — responsive */
@media (max-width: 900px) {
  .an-appshell { grid-template-columns: 1fr; }
  .an-chartnav { position: static; }
}
@media (max-width: 900px) {
  .an-appshell { grid-template-columns: 1fr; }
  .an-chartnav { position: static; }
  .ov-kpis { grid-template-columns: repeat(2, 1fr); }
  .af-dp__popover { right: auto; left: 0; width: min(640px, calc(100vw - 28px)); }
  .af-dp__shell { flex-direction: column; }
  .af-dp__presets {
    width: auto;
    flex: 0 0 auto;
    border-right: 0;
    border-bottom: 1px solid var(--rule);
  }
  .af-dp__calendars { flex-direction: column; }
}
@media (max-width: 900px) {
  .an-appshell { grid-template-columns: 1fr; }
  .an-chartnav { position: static; }
  .pa-kpis { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 480px) {
  .pa-kpis { grid-template-columns: 1fr; }
  .af-dp__trigger-label { max-width: 140px; }
  .af-dp__body { padding: 12px; }
  .af-dp__calendar { padding: 10px; }
  .af-dp__actions {
    flex-direction: column;
    align-items: stretch;
  }
}
/* Busy/loading state for slow synchronous submits (set by admin.js on a
   <button data-busy>: Reskin "Analyzing…" ~10-30s, Render "Rendering…" ~100s). */
.actbtn.is-busy { opacity: 0.6; pointer-events: none; cursor: progress; }
.actbtn.is-busy::after {
  content: ""; display: inline-block; width: 0.7em; height: 0.7em;
  margin-left: 0.5em; vertical-align: -1px; border-radius: 50%;
  border: 2px solid currentColor; border-right-color: transparent;
  animation: actbtn-spin 0.7s linear infinite;
}
@keyframes actbtn-spin { to { transform: rotate(360deg); } }

/* ── Mission Control decision table (mission-ui-polish) ──────────────────────
   The "What changes" cell is bounded + wrapping so the Approve/Reject column
   can never be pushed off-screen; the table scrolls on a narrow window instead
   of clipping. aso_metadata proposals show a before→after keyword diff instead
   of the raw evidence-dict dump. */
.mc-scroll { overflow-x: auto; }
.mc-cell { min-width: 300px; max-width: 520px; }
.mc-ev {
  display: block; max-width: 460px; color: var(--ink-muted);
  font-size: 13px; line-height: 1.5; word-break: break-word;
}
.mc-diff__axis {
  display: inline-block; font-family: var(--mono); font-size: 11px;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-muted);
  margin-bottom: 8px;
}
.mc-diff__line { display: flex; gap: 8px; align-items: flex-start; margin: 5px 0; }
.mc-diff__lbl {
  flex: 0 0 44px; font-family: var(--mono); font-size: 11px;
  color: var(--ink-muted); text-transform: uppercase; letter-spacing: 0.06em;
  padding-top: 3px;
}
.mc-diff__lbl--new { color: var(--ok); }
/* Each keyword renders as a whole chip; the row is a wrapping flexbox so chips
   break BETWEEN terms, never mid-word (the per-character wrap bug). */
.mc-val { display: flex; flex-wrap: wrap; gap: 4px; min-width: 0; }
.mc-tok {
  font-family: var(--mono); font-size: 12px; white-space: nowrap;
  padding: 1px 7px; border-radius: 5px; line-height: 1.65;
}
.mc-tok--old { color: var(--ink-muted); background: var(--rule-soft); }
.mc-tok--kept { color: var(--ink-soft); background: var(--rule-soft); }
.mc-tok--removed {
  color: var(--danger); background: var(--danger-soft); text-decoration: line-through;
}
.mc-tok--added {
  color: var(--ink); background: var(--ok-soft); font-weight: 600;
  box-shadow: inset 0 0 0 1px var(--ok);
}
.mc-prose {
  font-size: 13px; line-height: 1.5; overflow-wrap: anywhere; color: var(--ink);
}
.mc-why {
  margin: 10px 0 0; font-size: 12.5px; font-style: italic;
  color: var(--ink-soft); line-height: 1.45; max-width: 460px;
}
.mc-act code {
  white-space: normal; word-break: break-word; display: inline-block;
  max-width: 210px; font-size: 12px;
}
.tbl tbody tr.mc-row { cursor: default; }

/* ── Social review queue (/social/review — social-pipeline-p2-v1) ─────────
   Mobile-first card stack (plan §3.4: thumb-reach on a 390px viewport).
   Slide strips use pure CSS scroll-snap — no JS. */
.sc-filters { display: flex; flex-wrap: wrap; gap: 6px; margin: 14px 0 18px; }
.sc-batch { margin: 0 0 16px; }
.sc-stack { display: flex; flex-direction: column; gap: 20px; max-width: 480px; }
.sc-card {
  background: var(--paper-card); border: 1px solid var(--rule);
  border-radius: 14px; padding: 14px; display: flex;
  flex-direction: column; gap: 10px;
}
.sc-card__head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.sc-video {
  width: 100%; max-height: 70vh; aspect-ratio: 9 / 16;
  border-radius: 10px; background: #000; object-fit: contain;
}
.sc-slides {
  display: flex; gap: 8px; overflow-x: auto;
  scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch;
  border-radius: 10px;
}
.sc-slide {
  flex: 0 0 auto; width: 72%; max-width: 260px; scroll-snap-align: start;
  border-radius: 10px; border: 1px solid var(--rule-soft);
}
.sc-slide--single { width: 72%; max-width: 260px; }
.sc-caption { margin: 0; font-size: 14px; line-height: 1.5; color: var(--ink); }
.sc-tags { margin: 0; font-size: 12.5px; }
.sc-params { display: flex; flex-wrap: wrap; gap: 6px; }
.sc-actions { display: flex; gap: 10px; align-items: stretch; }
.sc-actions form { display: flex; gap: 8px; flex: 1; }
.sc-reject { flex: 2; }
.sc-reason {
  flex: 1; min-width: 0; border: 1px solid var(--rule); border-radius: 8px;
  padding: 8px 10px; font-size: 13px; background: var(--paper);
  color: var(--ink);
}
.sc-btn { padding: 10px 16px; font-size: 14px; }
.sc-btn--approve { color: var(--ok); border-color: var(--ok); }
.sc-btn--reject { color: var(--danger); border-color: var(--danger); }

@media (max-width: 640px) {
  .sc-stack { max-width: 100%; }
  .sc-card { padding: 12px; }
  .sc-slide, .sc-slide--single { width: 82%; }
  .sc-actions { flex-direction: column; }
  .sc-btn { width: 100%; padding: 13px 16px; }
  .sc-reason { padding: 12px 10px; }
}

/* ── Operator OS: nav badges, ⌘K palette, desk glance ──────────────────── */
.nav-badge {
  margin-left: auto;
  min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 999px; font-size: 11px; font-weight: 600;
  line-height: 18px; text-align: center;
  background: var(--highlight); color: var(--accent);
}
.nav-badge--warn { background: #fef3c7; color: var(--warn); }
.rail-collapsed .nav-badge { display: none; }
.kbd--btn {
  cursor: pointer; border: 1px solid var(--rule);
  background: var(--paper-card); font: inherit;
}
.kbd--btn:hover { border-color: var(--accent); color: var(--accent); }

.cmd-palette[hidden] { display: none !important; }
.cmd-palette {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: flex-start; justify-content: center;
  padding-top: 12vh;
}
.cmd-palette__backdrop {
  position: absolute; inset: 0; background: rgba(9, 9, 13, 0.35);
}
.cmd-palette__panel {
  position: relative; width: min(560px, calc(100vw - 32px));
  background: var(--paper-card); border: 1px solid var(--rule);
  border-radius: 12px; box-shadow: 0 18px 50px rgba(9, 9, 13, 0.18);
  overflow: hidden;
}
.cmd-palette__input {
  width: 100%; border: 0; border-bottom: 1px solid var(--rule);
  padding: 14px 16px; font-size: 16px; outline: none;
  background: transparent; color: var(--ink);
}
.cmd-palette__list {
  list-style: none; margin: 0; padding: 6px;
  max-height: 360px; overflow-y: auto;
}
.cmd-palette__item {
  display: flex; gap: 12px; align-items: baseline;
  padding: 10px 12px; border-radius: 8px; cursor: pointer;
}
.cmd-palette__item.is-active,
.cmd-palette__item:hover { background: var(--highlight); }
.cmd-palette__group {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--ink-muted); min-width: 72px;
}
.cmd-palette__label { font-size: 14px; font-weight: 500; }
.cmd-palette__empty {
  padding: 18px 12px; color: var(--ink-muted); font-size: 13px;
}
.cmd-palette__hint {
  margin: 0; padding: 8px 14px 12px; font-size: 12px; color: var(--ink-muted);
  border-top: 1px solid var(--rule-soft);
}
.cmd-palette__hint kbd {
  font-size: 11px; border: 1px solid var(--rule); border-radius: 4px;
  padding: 1px 5px; background: var(--paper);
}

.desk-strip {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px; margin: 18px 0 22px;
}
.desk-strip__card {
  background: var(--paper-card); border: 1px solid var(--rule);
  border-radius: 10px; padding: 12px 14px;
}
.desk-strip__card.is-hot { border-color: #f5c26b; background: #fffbeb; }
.desk-strip__n { font-size: 22px; font-weight: 700; line-height: 1.1; }
.desk-strip__lbl { font-size: 12px; color: var(--ink-muted); margin-top: 4px; }
.desk-glance {
  margin: 8px 0 20px; padding: 12px 14px;
  border: 1px solid var(--rule); border-radius: 10px; background: var(--paper-card);
}
.desk-glance ol { margin: 8px 0 0; padding-left: 20px; }
.desk-glance li { margin: 4px 0; }
.desk-monday {
  margin: 0 0 20px; padding: 12px 14px;
  border: 1px dashed var(--rule); border-radius: 10px;
  background: var(--paper);
}
.inbox-chip {
  display: inline-block; font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.03em;
  padding: 2px 7px; border-radius: 999px; background: var(--highlight);
  color: var(--accent);
}
.inbox-chip--social { background: #e0f2fe; color: #0369a1; }
.inbox-chip--ads { background: #fae8ff; color: #86198f; }
.inbox-chip--backlog { background: #ecfccb; color: #3f6212; }
.inbox-chip--release { background: #fef3c7; color: #92400e; }
.inbox-chip--collector { background: #e0e7ff; color: #3730a3; }
.inbox-chip--decision { background: var(--highlight); color: var(--accent); }

/* ── Keywords experiment log (keywords-experiment-log-v1) ─────────────── */
.kw-app-head { margin: 0 0 10px; font-size: 1.05rem; }
.kw-app-link { text-decoration: none; color: inherit; }
.kw-app-link:hover { text-decoration: underline; }
.kw-open-list {
  margin: 6px 0 14px; padding-left: 18px; font-size: 13px; line-height: 1.5;
}
.kw-open-list li { margin: 3px 0; }
.kw-low-signal { color: var(--warn, #b45309); font-weight: 600; }
.kw-banner-warn {
  margin: 12px 0 18px; padding: 12px 14px;
  border: 1px solid var(--warn, #b45309); border-radius: 10px;
  background: var(--warn-soft, #fff7ed); font-size: 13px; line-height: 1.45;
}

/* ── Operator OS follow-ups ───────────────────────────────────────────── */
.navgroup--configure {
  display: block;
  margin: 0;
  border: 0;
  padding: 0;
}
.navgroup--configure > summary.glabel--toggle {
  list-style: none;
  cursor: pointer;
  user-select: none;
}
.navgroup--configure > summary.glabel--toggle::-webkit-details-marker { display: none; }
.navgroup--configure > summary.glabel--toggle::after {
  content: "▸";
  float: right;
  opacity: 0.55;
  font-size: 11px;
}
.navgroup--configure[open] > summary.glabel--toggle::after { content: "▾"; }
.rail-collapsed .navgroup--configure > summary.glabel--toggle::after { display: none; }
.rail-collapsed .navgroup--configure:not([open]) > .nav { display: none; }

.backlog-add {
  margin: 0 0 18px; padding: 12px 14px;
  border: 1px solid var(--rule); border-radius: 10px;
  background: var(--paper-card);
}
.backlog-add > summary { cursor: pointer; }
.backlog-add__form {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  margin-top: 10px;
}
.backlog-add__form input,
.backlog-add__form select {
  font: inherit; font-size: 13px;
  padding: 6px 8px; border: 1px solid var(--rule); border-radius: 6px;
  background: var(--paper); color: var(--ink);
}

.report-md {
  white-space: pre-wrap; margin: 16px 0 0; padding: 14px 16px;
  border: 1px solid var(--rule); border-radius: 10px;
  background: var(--paper-card); font-size: 13px; line-height: 1.5;
  max-height: none; overflow: auto;
}

.collector-session {
  margin: 0 0 22px; padding: 14px 16px;
  border: 1px solid #f5c26b; border-radius: 10px; background: #fffbeb;
}
.collector-session__steps { margin: 8px 0 0; padding-left: 20px; }
.collector-session__steps li { margin: 8px 0; }
.collector-session__cue {
  margin: 8px 0; padding: 10px 12px; white-space: pre-wrap;
  border: 1px dashed var(--rule); border-radius: 8px;
  background: var(--paper); font-size: 12px; max-height: 220px; overflow: auto;
}

/* ═══════════════════════════════════════════════════════════════════════
 * Collector design-approval desk (collector-design-approval-desk-v1) —
 * `GET /collector`. The direction grid is the only new primitive; the
 * wordmark grid reuses the P4 .wmgrid/.wmcard family verbatim. Local-desk
 * only: in deployed mode the card renders without any of these controls.
 * ═══════════════════════════════════════════════════════════════════════ */

.cdesign {
  margin: 0 0 26px; padding: 18px 20px;
  border: 1px solid var(--rule); border-radius: 14px;
  background: var(--paper-card);
}

.cdesign__hd { margin: 6px 0 0; }

.cdesign__meta { font-family: var(--mono); font-size: 12px; color: var(--ink-soft); margin: 6px 0 0; }

.cdesign__persona { margin: 16px 0 0; }

.cdesign__k {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.14em;
  color: var(--ink-muted);
}

.cdesign__v { margin-top: 5px; }

.cdesign__phrases { margin: 8px 0 0; padding-left: 20px; font-size: 13px; color: var(--ink-soft); }

.cdesign__pick {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em;
  color: var(--accent);
}

.cdesign__note { font-family: var(--mono); font-size: 11px; color: var(--ink-muted); margin-top: 7px; }

.cdesign__submit { display: flex; align-items: center; gap: 14px; margin: 22px 0 0; flex-wrap: wrap; }

.cdesign__acts { display: flex; align-items: center; gap: 12px; margin: 18px 0 0; flex-wrap: wrap; }

.cdesign__act { display: flex; align-items: center; gap: 8px; }

.cdesign__foot { font-family: var(--mono); font-size: 11px; color: var(--ink-muted); margin: 16px 0 0; }

.cdirgrid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 18px; margin: 14px 0 0;
}

.cdircard {
  display: block; padding: 14px; cursor: pointer;
  border: 1px solid var(--rule); border-radius: 14px; background: var(--paper);
}

.cdircard:hover { border-color: var(--accent); }

.cdircard__imgs { display: flex; gap: 8px; align-items: flex-start; }

.cdircard__img {
  width: 33%; height: auto; display: block;
  border: 1px solid var(--rule-soft); border-radius: 8px;
}

.cdircard__row { display: flex; align-items: center; gap: 9px; margin-top: 12px; }

.cdircard__name { font-size: 14px; }

.cdircard__meta { font-family: var(--mono); font-size: 11px; color: var(--ink-muted); margin-top: 6px; }
