/* admin.css — Olnesta Admin components, authored to the olnesta.com
 * standard. Layered ON TOP of styles.css (the verbatim olnesta-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;
}

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

/* The admin runs a fixed app-shell layout, not olnesta.com'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: 17px;
  line-height: 1.55;
  /* Readability (admin only, scoped to body.admin so styles.css / the public
   * olnesta.com site stay untouched): lift the inherited editorial text tokens
   * to WCAG AA. Light values here; dark lift in the @media block below. */
  --ink-soft: #5e5749;   /* was #6a6356 (5.4:1) -> 6.3:1 */
  --ink-muted: #6c6453;  /* was #9b9485 (2.7:1, fails AA) -> 5.3:1 */
}

/* The mock's grain is a touch stronger than the site's; nudge opacity on
 * the admin body only (the ::before element itself comes from styles.css). */
body.admin::before { opacity: 0.05; mix-blend-mode: multiply; }

@media (prefers-color-scheme: dark) {
  body.admin::before { opacity: 0.06; mix-blend-mode: screen; }
  /* Readability: dark-mode contrast lift (admin only). */
  body.admin {
    --ink-soft: #ada48f;   /* was #908976 (5.4:1) -> 7.6:1 */
    --ink-muted: #8f8674;  /* was #5e574b (2.6:1, fails AA) -> 5.2:1 */
  }
}

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

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

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

.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: uppercase;
  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: uppercase;
  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; }

.nav.soon .pill {
  margin-left: auto;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  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;
}

.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: uppercase;
  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 {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  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: uppercase;
  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: uppercase;
  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: uppercase;
  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: uppercase;
  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: uppercase;
  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; }

/* 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: uppercase;
  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: uppercase;
  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: uppercase;
  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: uppercase;
  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: uppercase;
  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 .olnesta-* 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: uppercase;
  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: uppercase;
  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: uppercase;
  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: uppercase;
  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: uppercase;
  color: var(--info);
}

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

.revs__head {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  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: uppercase;
  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: uppercase;
  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: uppercase;
  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: uppercase;
  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
 * .olnesta-* 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;
}

.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: uppercase;
  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: uppercase;
  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: uppercase;
  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);
}

.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: uppercase;
  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: uppercase;
  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 .olnesta-* 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: uppercase;
  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: uppercase;
  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: uppercase;
  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: uppercase;
  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: uppercase;
  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: uppercase; }
.assetbar__filter { display: inline-flex; gap: 16px; }
.assetbar__f { font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; 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: uppercase; 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: uppercase; 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); }
