/*
 * BA Agents — member surface styling.
 * Uses the shared brand tokens from /_styles/brand.css. Mobile-first;
 * breakpoints mirror the rest of the member area (880 / 760 / 640 / 380).
 *
 * 2026-07-14 UX/UI overhaul: same brand palette + selectors, modernized
 * component design — chat bubbles with real markdown blocks, tap-to-answer
 * cards, toggle switches, focus-visible rings, softer cards/modals. Every
 * selector the JS emits is preserved (see _setup/render-markdown-smoke.mjs +
 * the selector parity check run before shipping).
 *
 * Increment 33 ("tells the truth and looks finished"): the connection-state
 * taxonomy (5 badges, 5 meanings — amber used to carry six), the Activity feed,
 * the mobile canvas scroll-trap fix, and the clipped title/composer/topbar.
 */

/* Local, additive tokens. _styles/brand.css is SHARED by dashboard/admin/community —
   never edit it. Two brand pairs FAIL WCAG AA as text-on-tint: --green on --green-tint
   is 2.96:1 and --amber on --amber-tint is 3.80:1. They stay for FILLS; text-on-tint
   uses the AA-passing pairs below. */
:root {
  --ok-ink: #15803d;   --ok-tint: #e8f7ee;   /* 4.53:1 */
  --need-ink: #b91c1c; --need-tint: #fde8e8; /* 5.51:1 */
  --need-line: #f3c9c9;
  --warn-tint: #fef3e2;
  --r-sm: 8px; --r-md: 12px; --r-lg: 16px;
}

* { box-sizing: border-box; }
/* The HTML `hidden` attribute must always win — component CSS below sets an
 * explicit `display` on .boot (grid) and .modal, which would otherwise override
 * the user-agent's `[hidden] { display: none }` rule (same specificity, author
 * rule wins by source order). Without this, `el.hidden = true` is inert and the
 * full-screen boot overlay (z-index:50) never disappears. Mirrors community.css. */
[hidden] { display: none !important; }
html, body { margin: 0; padding: 0; }
body {
  font-family: "Inter", system-ui, -apple-system, sans-serif;
  color: var(--ink);
  background: var(--bg-soft);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
h1, h2, h3, h4 { font-family: "Inter Tight", "Inter", sans-serif; margin: 0; }
a { color: inherit; }
.muted { color: var(--ink-3); }
::selection { background: rgba(122,51,255,.16); }
/* One consistent, token-colored keyboard focus ring everywhere. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--purple);
  outline-offset: 2px;
}
.spinner {
  width: 28px; height: 28px; border: 3px solid #e0d4ff; border-top-color: var(--purple);
  border-radius: 50%; animation: spin .8s linear infinite; margin: 0 auto;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ── Boot ─────────────────────────────────────────────────────────── */
.boot { position: fixed; inset: 0; display: grid; place-items: center; background: var(--bg-soft); z-index: 50; }
.boot-card { text-align: center; display: grid; gap: 14px; }
.brand-lockup, .brand { font-family: "Inter Tight", sans-serif; font-weight: 800; font-size: 20px; letter-spacing: -.01em; text-decoration: none; }
.brand-name { color: var(--ink); }
.brand-grad { background: var(--grad-wordmark); -webkit-background-clip: text; background-clip: text; color: transparent; }

/* ── Topbar ───────────────────────────────────────────────────────── */
.topbar { position: sticky; top: 0; z-index: 30; background: rgba(255,255,255,.86); backdrop-filter: saturate(180%) blur(12px); border-bottom: 1px solid var(--line); }
.topbar-inner { max-width: 1240px; margin: 0 auto; padding: 11px 20px; display: flex; align-items: center; gap: 18px; }
.tabnav { display: flex; gap: 4px; margin-left: 6px; flex: 1; overflow-x: auto; scrollbar-width: none; }
.tabnav::-webkit-scrollbar { display: none; }
.tab {
  display: inline-flex; align-items: center; gap: 6px; padding: 8px 13px; border-radius: 10px;
  font-weight: 600; font-size: 14px; color: var(--ink-3); text-decoration: none; white-space: nowrap;
  transition: background .15s ease, color .15s ease;
}
.tab:hover { background: var(--bg-tint); color: var(--ink); }
.tab.is-active { background: var(--purple-tint); color: var(--purple-3); }
.top-actions { display: flex; align-items: center; gap: 12px; }
.top-link { font-size: 13px; font-weight: 600; color: var(--ink-3); text-decoration: none; white-space: nowrap; }
.top-link:hover { color: var(--purple-3); }
.as-btn { background: none; border: none; cursor: pointer; font-family: inherit; }
.tier-chip { font-size: 12px; font-weight: 700; padding: 4px 10px; border-radius: 999px; background: var(--purple-tint); color: var(--purple-3); white-space: nowrap; }
.tier-chip.is-pro { background: var(--amber-tint); color: var(--amber); }

/* ── Layout ───────────────────────────────────────────────────────── */
.view { max-width: 1240px; margin: 0 auto; padding: 26px 20px 80px; }
.loading { display: grid; place-items: center; min-height: 50vh; }
.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 22px; }
.page-head h1 { font-size: 28px; letter-spacing: -.02em; }
.page-head p { margin: 5px 0 0; color: var(--ink-3); max-width: 60ch; }
.head-actions { display: flex; gap: 10px; flex-wrap: wrap; }
/* "← back" links (studio head + client detail) — styled globally so every
 * surface that emits .back gets the same treatment. */
.back { font-size: 13px; font-weight: 600; color: var(--ink-3); text-decoration: none; }
.back:hover { color: var(--purple-3); }

/* ── Buttons ──────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 11px 18px; border-radius: 11px; border: 1px solid transparent;
  font-family: "Inter Tight", sans-serif; font-weight: 600; font-size: 14px; cursor: pointer;
  transition: transform .12s ease, background .15s ease, box-shadow .15s ease, border-color .15s ease, color .15s ease;
  text-decoration: none; white-space: nowrap;
}
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .55; cursor: not-allowed; box-shadow: none; }
.btn-primary { background: var(--ink); color: #fff; }
.btn-primary:hover { background: #222; }
.btn-purple { background: var(--purple); color: #fff; box-shadow: 0 6px 18px rgba(122,51,255,.28); }
.btn-purple:hover { background: var(--purple-3); box-shadow: 0 8px 22px rgba(122,51,255,.34); }
.btn.ghost { background: #fff; border-color: var(--line-2); color: var(--ink-2); }
.btn.ghost:hover { border-color: var(--purple); color: var(--purple-3); }
.btn.danger { background: var(--red); color: #fff; }
.btn.sm { padding: 7px 12px; font-size: 13px; border-radius: 9px; }
.btn.block { width: 100%; }

/* ── Cards / grids ────────────────────────────────────────────────── */
.grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.card {
  background: #fff; border: 1px solid var(--line); border-radius: 16px; padding: 18px;
  box-shadow: var(--shadow-sm); transition: box-shadow .18s ease, transform .18s ease, border-color .18s ease;
  display: flex; flex-direction: column; gap: 10px; min-width: 0;
}
.card.clickable { cursor: pointer; }
.card.clickable:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); border-color: var(--line-2); }
.card-icon { width: 42px; height: 42px; border-radius: 12px; display: grid; place-items: center; font-size: 22px; background: var(--purple-tint); }
.card h3 { font-size: 16px; letter-spacing: -.01em; }
.card .sub { font-size: 13px; color: var(--ink-3); line-height: 1.5; flex: 1; }
.card-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 4px; flex-wrap: wrap; }
.meta-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }

.badge { font-size: 11px; font-weight: 700; padding: 3px 8px; border-radius: 999px; letter-spacing: .01em; }
.badge.draft { background: var(--bg-tint); color: var(--ink-3); text-transform: capitalize; }
.badge.active { background: var(--green-tint); color: var(--green); text-transform: capitalize; }
.badge.paused { background: var(--amber-tint); color: var(--amber); text-transform: capitalize; }
.badge.cat { background: var(--bg-tint); color: var(--ink-3); }
.badge.lock { background: var(--amber-tint); color: var(--amber); }
.badge.template { background: var(--purple-tint); color: var(--purple-3); }
/* ── Connection-state taxonomy (Increment 33) ──────────────────────────────────
 * The member must tell "YOUR AGENT CANNOT RUN UNTIL YOU ACT" from "there is nothing
 * to do here" AT A GLANCE. Before this, .lock and .paused were byte-identical amber
 * and carried SIX different meanings between them — including "Coming soon" (you
 * CANNOT act) styled exactly like "Not connected" (you MUST act).
 * ADDITIVE: .lock/.paused stay — the Templates card (🔒 Premium), agentCard's status
 * and outputCard still emit them. */
.badge.need { background: var(--need-tint); color: var(--need-ink); }
.badge.ok   { background: var(--ok-tint);   color: var(--ok-ink); }
.badge.info { background: var(--bg-tint);   color: var(--ink-3); }
.badge.wait { background: transparent; color: var(--ink-3); border: 1px dashed var(--line-2); }
.badge.plan { background: var(--purple-tint); color: var(--purple-3); }

/* ── Empty / locked states ────────────────────────────────────────── */
.empty { text-align: center; padding: 56px 20px; background: #fff; border: 1px dashed var(--line-2); border-radius: 18px; }
.empty .big { font-size: 40px; margin-bottom: 8px; }
.empty h2 { font-size: 20px; margin-bottom: 6px; }
.empty p { color: var(--ink-3); max-width: 44ch; margin: 0 auto 18px; }
.locked-wrap { display: grid; place-items: center; min-height: 70vh; padding: 24px; }
.locked-card { max-width: 480px; text-align: center; background: #fff; border: 1px solid var(--line); border-radius: 20px; padding: 36px 28px; box-shadow: var(--shadow-md); }
.locked-card .big { font-size: 46px; }

/* ── Studio (builder + diagram split) ─────────────────────────────── */
.studio-head { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.studio-head .back { font-size: 13px; font-weight: 600; color: var(--ink-3); text-decoration: none; }
.studio-head .back:hover { color: var(--purple-3); }
/* The title is an <input>. With no flex it sized to the UA's default `size` (~20ch) and
   CLIPPED every real agent name ("Personal Assistant (Telegr…").
   `flex: 0 1 auto` + a JS-maintained `size` attribute (paintStudio → sizeTitle) makes it
   size to its CONTENT, so the whole name shows AND the status badge stays next to it.
   (Growing it with flex:1 instead would fix the clip but strand the badge over by the
   action buttons, since the text is left-aligned inside a now-very-wide box.)
   The action buttons wrap to a second row before the title is ever squeezed. */
.studio-title {
  flex: 0 1 auto; min-width: 140px; max-width: 100%;
  font-size: 22px; letter-spacing: -.02em; border: 1px solid transparent; border-radius: var(--r-sm);
  padding: 2px 6px; background: transparent; font-family: "Inter Tight", sans-serif;
  font-weight: 700; color: var(--ink); text-overflow: ellipsis;
}
.studio-title:hover { border-color: var(--line-2); }
.studio-title:focus { outline: none; border-color: var(--purple); background: #fff; box-shadow: 0 0 0 4px rgba(122,51,255,.1); }
/* Keeps the action buttons right-aligned. This ONLY works because the title above is
   flex-grow:0 (content-sized) — if the title ever grows again, these two would split the
   free space 50/50 and the title would be starved back into clipping. */
.studio-head .spacer { flex: 1; }

.studio { display: grid; grid-template-columns: minmax(340px, 0.85fr) 1.15fr; gap: 18px; align-items: start; }
/* NOTE: no overflow:hidden here — it would create a scroll container and silently
 * disable the Triggers tab's position:sticky save bar (.trig-save). */
.pane { background: #fff; border: 1px solid var(--line); border-radius: 16px; box-shadow: var(--shadow-sm); min-width: 0; }
.pane-head { padding: 13px 16px; border-bottom: 1px solid var(--line); display: flex; align-items: center; justify-content: space-between; gap: 8px; background: #fff; }
.pane-head h3 { font-size: 14px; }
.pane-body { padding: 16px; }
/* RAGGED PANES: .studio uses align-items:start (REQUIRED — a scroll container here
   would silently kill the Triggers tab's position:sticky .trig-save), so the right
   pane was content-height: it collapsed to a ~200px spinner stub beside a 640px chat,
   then JUMPED when the content landed. Give it the chat's height as a FLOOR instead —
   no overflow, no new scroll container, sticky save bar intact. */
.pane.studio-pane { display: flex; flex-direction: column; min-height: calc(min(640px, 72vh) + 44px); }
#studioContent { flex: 1; min-width: 0; display: flex; flex-direction: column; }
/* The 6 async tabs open with `<div class="loading" style="min-height:160px">`. flex:1
   makes that stub FILL the pane, so the spinner sits where the content will be and
   there is no jump when it arrives. */
#studioContent > .loading { flex: 1; }

/* mobile tab toggle for studio panes */
.studio-toggle { display: none; gap: 6px; margin-bottom: 14px; background: var(--bg-tint); padding: 4px; border-radius: 12px; }
.studio-toggle button { flex: 1; padding: 10px; border: none; border-radius: 9px; background: transparent; font-weight: 600; font-size: 13px; color: var(--ink-3); cursor: pointer; font-family: inherit; }
.studio-toggle button.is-active { background: #fff; color: var(--ink); box-shadow: var(--shadow-sm); }

/* ── Builder chat ─────────────────────────────────────────────────── */
.chat { display: flex; flex-direction: column; height: min(640px, 72vh); }
.chat-log {
  flex: 1; overflow-y: auto; padding: 16px 14px; display: flex; flex-direction: column; gap: 12px;
  background: var(--bg-soft);
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent;
}
.chat-log::-webkit-scrollbar { width: 8px; }
.chat-log::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 8px; }
.chat-log::-webkit-scrollbar-track { background: transparent; }
.bubble { max-width: 92%; padding: 11px 15px; border-radius: 16px; font-size: 14px; line-height: 1.6; word-wrap: break-word; }
/* Only USER text needs pre-wrap (typed literally, nl2br'd) — assistant/card bubbles
 * are structured markdown blocks now, where stray whitespace must not add gaps. */
.bubble.user { align-self: flex-end; background: var(--ink); color: #fff; border-bottom-right-radius: 6px; box-shadow: var(--shadow-sm); white-space: pre-wrap; }
.bubble.assistant { align-self: flex-start; background: #fff; color: var(--ink-2); border: 1px solid var(--line); border-bottom-left-radius: 6px; box-shadow: var(--shadow-sm); }
.bubble.plan { align-self: flex-start; background: var(--purple-tint); color: var(--purple-3); border: 1px solid #e6dbff; font-weight: 600; font-size: 13px; border-radius: 12px; }
.bubble.plan b { color: var(--purple-3); }
/* Rendered markdown inside AI replies + agent outputs — real blocks now:
 * paragraphs, bullet/numbered lists and light headings (renderMarkdown). */
.bubble strong, .out-body strong { font-weight: 700; color: var(--ink); }
.bubble.user strong { color: #fff; }
.bubble em, .out-body em { font-style: italic; }
.bubble a, .out-body a { color: var(--purple-3); text-decoration: underline; word-break: break-word; }
.bubble.user a { color: #fff; }
.bubble code, .out-body code { background: rgba(99,57,255,.10); color: var(--purple-3); padding: 1px 5px; border-radius: 5px; font-size: .9em; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; word-break: break-word; }
.bubble.user code { background: rgba(255,255,255,.18); color: #fff; }
.bubble p, .out-body p { margin: 0 0 10px; }
.bubble p:last-child, .out-body p:last-child { margin-bottom: 0; }
.bubble ul, .bubble ol, .out-body ul, .out-body ol { margin: 6px 0 10px; padding-left: 20px; }
.bubble ul:last-child, .bubble ol:last-child, .out-body ul:last-child, .out-body ol:last-child { margin-bottom: 0; }
.bubble li, .out-body li { margin: 4px 0; }
.bubble li::marker { color: var(--purple); }
.bubble ol > li::marker { color: var(--ink-3); font-weight: 600; }
.bubble .md-h, .out-body .md-h { margin-top: 14px; }
.bubble .md-h:first-child, .out-body .md-h:first-child { margin-top: 0; }
.thinking-row {
  align-self: flex-start; font-size: 12px; color: var(--ink-3); display: flex; gap: 8px; align-items: center;
  background: #fff; border: 1px solid var(--line); border-radius: 999px; padding: 7px 13px; box-shadow: var(--shadow-sm);
}
.thinking-row .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--purple); animation: pulse 1s ease-in-out infinite; }
/* Shared header treatment for chat cards: the emoji sits in a soft tinted chip. */
.card-emoji {
  display: inline-grid; place-items: center; width: 26px; height: 26px; border-radius: 8px;
  background: var(--purple-tint); font-size: 14px; margin-right: 7px; vertical-align: -7px;
}
/* R5 (Inc 17): durable "how to connect this tool" setup card in the Builder chat. */
.bubble.setup-card { align-self: stretch; background: #fff; border: 1px solid var(--line-2); color: var(--ink-2); max-width: 100%; border-radius: 16px; padding: 14px 16px; }
.setup-card .setup-h { font-weight: 700; color: var(--ink); font-size: 13.5px; margin-bottom: 6px; }
.setup-card .setup-steps { font-size: 12.5px; line-height: 1.55; color: var(--ink-2); }
.setup-card .setup-note { font-size: 12px; color: var(--ink-3); margin-top: 7px; background: var(--bg-tint); border-radius: 8px; padding: 7px 9px; }
.setup-card .setup-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 10px; }
.setup-card .setup-docs { font-size: 12.5px; color: var(--purple-3); text-decoration: underline; white-space: nowrap; }
/* Increment 19: the opt-in additive auto-fix "Apply this fix?" card. */
.bubble.fix-card { align-self: stretch; background: #fff; border: 1px solid var(--line-2); color: var(--ink-2); max-width: 100%; border-radius: 16px; padding: 14px 16px; }
.fix-card .fix-h { font-weight: 700; color: var(--ink); font-size: 13.5px; margin-bottom: 6px; }
.fix-card .fix-body { font-size: 12.5px; line-height: 1.55; color: var(--ink-2); }
.fix-card .fix-type { color: var(--ink-3); }
.fix-card .fix-reason { font-size: 12px; color: var(--ink-3); margin-top: 6px; background: var(--bg-tint); border-radius: 8px; padding: 7px 9px; }
.fix-card .fix-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 10px; }
.fix-card .fix-status { margin-top: 8px; font-size: 12.5px; }
.fix-card .fix-ok { color: var(--green); font-weight: 600; }
.fix-card .fix-err { color: var(--red); }
/* Increment 20: the exact inputs a generic (non-Airtable-field) fix will send, so the
   Apply button is an informed confirmation. */
.fix-card .fix-params { margin-top: 7px; background: var(--bg-tint); border-radius: 8px; padding: 6px 9px; display: flex; flex-direction: column; gap: 3px; }
.fix-card .fix-param { font-size: 11.5px; color: var(--ink-3); word-break: break-word; }
.fix-card .fix-param .fix-pk { color: var(--ink-2); font-weight: 600; }
/* Increment 35: the created-resource link on a fix card's success state (e.g. the
   ElevenLabs talk-to link) — a real tappable button, comfortable on mobile too. */
.fix-card .fix-link { margin-top: 8px; }
.fix-card .fix-link a { text-decoration: none; display: inline-flex; align-items: center; gap: 6px; }
/* R4 (Inc 17): the inline self-check / verify card in the Builder chat. */
.bubble.verify-card { align-self: stretch; background: #fff; border: 1px solid var(--line-2); color: var(--ink-2); max-width: 100%; font-size: 13px; border-radius: 16px; padding: 14px 16px; }
.verify-card .vc-h { font-weight: 700; color: var(--ink); font-size: 13.5px; margin-bottom: 8px; }
.verify-card .vc-row { margin-top: 9px; line-height: 1.5; }
.verify-card .vc-ok { color: var(--green); font-weight: 600; }
.verify-card .vc-err { color: var(--red); }
.verify-card .vc-err ul, .verify-card .vc-warns ul { margin: 5px 0 0; padding-left: 18px; }
.verify-card .vc-err li, .verify-card .vc-warns li { margin: 3px 0; color: var(--ink-2); }
.verify-card .vc-warns { margin-top: 8px; }
.verify-card .vc-warns summary { cursor: pointer; color: var(--ink-3); font-size: 12.5px; }
.verify-card .vc-miss { background: var(--amber-tint); color: var(--amber); border-radius: 9px; padding: 8px 10px; display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
/* Increment 25: the "Builder already test-ran this" note inside the verify card. */
.verify-card .vc-note { margin-top: 9px; color: var(--ink-3); font-size: 12.5px; line-height: 1.5; }
.verify-card .vc-conns { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.verify-card .vc-chip { font-size: 11.5px; padding: 4px 9px; border-radius: 999px; background: var(--bg-tint); color: var(--ink-2); }
.verify-card .vc-chip.ok { background: var(--green-tint); color: var(--green); }
.verify-card .vc-chip.miss { background: var(--amber-tint); color: var(--amber); }
.verify-card .vc-chip.err { background: var(--red-tint, #fde8e8); color: var(--red); }
/* Increment 31: the ask_user tap-to-answer questions card. Options are comfortable
   tap targets (mobile-first); the selected chip goes purple; answered cards go inert. */
.bubble.ask-card {
  align-self: stretch; background: #fff; border: 1px solid #e6dbff; color: var(--ink-2);
  max-width: 100%; width: 100%; border-radius: 16px; padding: 14px 16px;
  box-shadow: 0 8px 24px rgba(122,51,255,.08);
}
.ask-card .ask-h { font-weight: 700; color: var(--ink); font-size: 13.5px; margin-bottom: 4px; }
.ask-card .ask-q { margin-top: 12px; }
.ask-card .ask-q-text { font-size: 13.5px; font-weight: 600; color: var(--ink); line-height: 1.45; }
.ask-card .ask-multi { font-weight: 500; color: var(--ink-4); font-size: 11.5px; }
.ask-card .ask-opts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.ask-card .ask-opt {
  background: var(--bg-soft); border: 1px solid var(--line-2); border-radius: 999px;
  padding: 9px 14px; font-size: 13px; font-family: inherit; color: var(--ink-2); cursor: pointer; text-align: left;
  line-height: 1.3; max-width: 100%; word-break: break-word;
  transition: border-color .12s ease, background .12s ease, color .12s ease, box-shadow .12s ease;
}
.ask-card .ask-opt:hover { border-color: var(--purple); color: var(--purple-3); background: #fff; }
.ask-card .ask-opt.sel { background: var(--purple-tint); border-color: var(--purple); color: var(--purple-3); font-weight: 600; box-shadow: 0 2px 8px rgba(122,51,255,.14); }
.ask-card .ask-opt.sel::before { content: "✓ "; font-weight: 800; }
.ask-card .ask-rec { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: var(--purple-3); background: rgba(122,51,255,.12); border-radius: 999px; padding: 2px 6px; margin-left: 4px; vertical-align: 1px; }
.ask-card .ask-other {
  display: block; width: 100%; margin-top: 8px; border: 1px solid var(--line-2); border-radius: 10px;
  padding: 9px 12px; font-family: inherit; font-size: 13px; background: var(--bg-soft); color: var(--ink);
}
.ask-card .ask-other:focus { outline: none; border-color: var(--purple); background: #fff; box-shadow: 0 0 0 4px rgba(122,51,255,.1); }
.ask-card .ask-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 14px; }
.ask-card .ask-hint { font-size: 11.5px; color: var(--ink-4); }
.ask-card.answered { opacity: .62; box-shadow: none; border-color: var(--line-2); }
.ask-card.answered .ask-opt, .ask-card.answered .ask-other, .ask-card.answered .ask-actions .btn { cursor: default; pointer-events: none; }
/* Tapped while the turn was still streaming — the answer is queued and auto-sends. */
.ask-card.queued { border-color: var(--purple); }
.ask-card.queued .ask-hint { color: var(--purple-3); font-weight: 600; }
@keyframes pulse { 0%,100%{ opacity:.3 } 50%{ opacity:1 } }
.chat-empty { color: var(--ink-3); font-size: 14px; text-align: center; padding: 28px 12px; }
.chat-empty .suggest { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.chat-empty .suggest button { background: #fff; border: 1px solid var(--line-2); border-radius: 12px; padding: 11px 13px; font-size: 13px; font-family: inherit; color: var(--ink-2); cursor: pointer; text-align: left; transition: border-color .12s ease, color .12s ease, box-shadow .12s ease; }
.chat-empty .suggest button:hover { border-color: var(--purple); color: var(--purple-3); box-shadow: var(--shadow-sm); }
.chat-input { border-top: 1px solid var(--line); padding: 12px; display: flex; gap: 9px; align-items: flex-end; background: #fff; }
.chat-input textarea {
  flex: 1; min-width: 0;                 /* a flex form control refuses to shrink without this */
  min-height: 46px;                      /* rows="1" + no min-height CLIPPED the placeholder */
  resize: none; border: 1px solid var(--line-2); border-radius: 13px; padding: 11px 13px;
  font-family: inherit; font-size: 14px; line-height: 1.45; max-height: 140px; background: var(--bg-soft); color: var(--ink);
  transition: border-color .12s ease, background .12s ease, box-shadow .12s ease;
}
/* The composer's auto-grow only fires on `input`, and scrollHeight IGNORES a placeholder —
   so a wrapping placeholder could NEVER be un-clipped from JS. It has to be CSS: keep it
   on one line and ellipsise it. (The placeholder text was also shortened — see agents.js.) */
.chat-input textarea::placeholder { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chat-input textarea:focus { outline: none; border-color: var(--purple); background: #fff; box-shadow: 0 0 0 4px rgba(122,51,255,.1); }
.chat-input .btn { border-radius: 12px; }

/* ── Node diagram ─────────────────────────────────────────────────── */
/* 8 tabs overflow a ~576px pane and the scrollbar is hidden, so there was NO affordance
   at all — and nothing scrolled the ACTIVE tab into view (see scrollActiveTabIntoView).
   Pure-CSS scroll shadows: the white "cover" layers are background-attachment:local so
   they slide away with the content, revealing the fixed shadow beneath at a scrollable edge. */
.studio-tabs {
  display: flex; gap: 4px; padding: 10px 12px; border-bottom: 1px solid var(--line);
  overflow-x: auto; scrollbar-width: none; scroll-behavior: smooth;
  background:
    linear-gradient(to right, #fff 40%, rgba(255,255,255,0)) left center,
    linear-gradient(to left,  #fff 40%, rgba(255,255,255,0)) right center,
    radial-gradient(farthest-side at 0 50%, rgba(8,2,58,.10), rgba(8,2,58,0)) left center,
    radial-gradient(farthest-side at 100% 50%, rgba(8,2,58,.10), rgba(8,2,58,0)) right center;
  background-repeat: no-repeat;
  background-size: 34px 100%, 34px 100%, 12px 100%, 12px 100%;
  background-attachment: local, local, scroll, scroll;
}
.studio-tabs::-webkit-scrollbar { display: none; }
.studio-tab { padding: 8px 12px; border-radius: 9px; border: none; background: transparent; font-weight: 600; font-size: 13px; color: var(--ink-3); cursor: pointer; white-space: nowrap; font-family: inherit; transition: background .12s ease, color .12s ease; }
.studio-tab:hover { background: var(--bg-tint); color: var(--ink); }
.studio-tab.is-active { background: var(--purple-tint); color: var(--purple-3); }

.flow { padding: 18px 16px; display: flex; flex-direction: column; align-items: center; gap: 0; }
.trigger-pill { background: var(--grad-card); color: #fff; padding: 12px 18px; border-radius: 14px; text-align: center; max-width: 460px; width: 100%; }
.trigger-pill .lbl { font-size: 11px; text-transform: uppercase; letter-spacing: .08em; opacity: .75; }
.trigger-pill .ttl { font-weight: 700; font-family: "Inter Tight", sans-serif; margin-top: 2px; }
.trigger-pill .dsc { font-size: 12px; opacity: .8; margin-top: 3px; }
.connector { width: 2px; height: 22px; background: var(--line-2); }
.connector.branch { position: relative; }
.node-card {
  background: #fff; border: 1px solid var(--line-2); border-radius: 14px; padding: 13px 15px; max-width: 460px; width: 100%;
  cursor: pointer; transition: border-color .15s ease, box-shadow .15s ease; box-shadow: var(--shadow-sm); position: relative;
}
.node-card:hover { border-color: var(--purple); box-shadow: var(--shadow-md); }
.node-card .nrow { display: flex; align-items: center; gap: 10px; }
.node-kind-ico { width: 32px; height: 32px; border-radius: 9px; display: grid; place-items: center; flex: none; font-size: 15px; color: #fff; }
.k-trigger { background: #08023a; } .k-integration { background: #2563eb; } .k-brain { background: var(--purple); }
.k-condition { background: var(--amber); } .k-approval { background: #c2410c; } .k-delay { background: #7c5cff; } .k-action { background: #0f9d58; } .k-knowledge { background: #0891b2; } .k-output { background: var(--ink-2); }
.k-agent { background: linear-gradient(135deg, var(--purple), #2563eb); }
.node-card.is-approval { border-color: #f0b884; background: #fffaf4; }
.node-card .napproval { font-size: 12px; color: #b3531a; margin-top: 8px; font-weight: 600; }
.node-card .nagent { font-size: 12px; color: var(--purple-3); margin-top: 8px; font-weight: 600; }
.agenttool-chips { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 7px; }
.agenttool-chip { font-size: 10.5px; font-weight: 600; padding: 2px 7px; border-radius: 6px; background: var(--purple-tint); color: var(--purple-3); }
.ntag.agenttools { background: var(--purple-tint); color: var(--purple-3); }
.node-card .ntitle { font-weight: 700; font-size: 14px; font-family: "Inter Tight", sans-serif; }
.node-card .nkind { font-size: 11px; color: var(--ink-4); text-transform: capitalize; }
.node-card .ndesc { font-size: 12.5px; color: var(--ink-3); margin-top: 8px; line-height: 1.5; }
.node-card .ntags { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 9px; }
.ntag { font-size: 10.5px; font-weight: 600; padding: 2px 7px; border-radius: 6px; background: var(--bg-tint); color: var(--ink-3); }
.ntag.model { background: var(--purple-tint); color: var(--purple-3); }
.ntag.foreach { background: #fff1e6; color: #c2410c; }
.ntag.newonly { background: #e8f7ee; color: #15803d; }
.edge-label { font-size: 10px; font-weight: 700; color: var(--ink-4); background: var(--bg-soft); padding: 1px 6px; border-radius: 6px; margin: -2px 0; }

/* lists inside studio tabs */
.list-item { border: 1px solid var(--line); border-radius: 13px; padding: 13px 15px; background: #fff; display: flex; gap: 12px; align-items: flex-start; }
.list-item + .list-item { margin-top: 10px; }
.list-item .li-main { flex: 1; min-width: 0; }
.list-item .li-title { font-weight: 600; font-size: 14px; }
.list-item .li-sub { font-size: 12.5px; color: var(--ink-3); margin-top: 3px; word-break: break-word; }
/* ── Activity feed (the Logs tab) ──────────────────────────────────────────────
 * Replaces .log-line/.lvl/.lt — a monospace dump of raw machine slugs
 * ("Jun 25  info  run.succeeded") shipped to non-technical customers who were sold
 * "build automation agents in plain English". Every row is now a human sentence;
 * the slug survives as a muted chip so support/debugging loses nothing. */
.act-day { font-size: 11.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-4); padding: 14px 4px 6px; }
.act-day:first-child { padding-top: 4px; }
.act-row { display: flex; gap: 12px; align-items: flex-start; padding: 11px 6px; border-top: 1px solid var(--line); }
/* The first row under each day heading gets no rule. (NOT :first-of-type — renderLogs always
   emits an .act-day <div> before the first .act-row <div>, so the first-of-type div is the
   heading and that selector could never match.) */
.act-day + .act-row { border-top: 0; }
.act-ic { flex: none; width: 30px; height: 30px; border-radius: 999px; display: flex; align-items: center; justify-content: center; font-size: 15px; line-height: 1; background: var(--bg-soft); }
.act-ic.ok { background: var(--ok-tint); }
.act-ic.warn { background: var(--warn-tint); }
.act-ic.error { background: var(--need-tint); }
.act-main { flex: 1; min-width: 0; }
.act-top { display: flex; gap: 10px; align-items: baseline; }
.act-title { flex: 1; min-width: 0; font-size: 14px; font-weight: 600; color: var(--ink-2); word-break: break-word; }
.act-time { flex: none; font-size: 12px; color: var(--ink-4); white-space: nowrap; }
.act-sub { font-size: 12.5px; color: var(--ink-3); margin-top: 3px; word-break: break-word; }
.act-foot { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 6px; }
.act-slug { font-family: "Geist Mono", monospace; font-size: 10.5px; color: var(--ink-4); background: var(--bg-soft); border-radius: 6px; padding: 2px 6px; }
.act-chip { font-size: 11px; color: var(--ink-3); background: var(--bg-soft); border-radius: 6px; padding: 2px 6px; }
.act-run { font: inherit; font-size: 12px; font-weight: 600; color: var(--purple-3); background: none; border: 0; padding: 2px 4px; cursor: pointer; border-radius: 6px; }
.act-run:hover { background: var(--purple-tint); }
.act-run:disabled { opacity: .55; cursor: default; }
@media (max-width: 480px) {
  .act-top { flex-direction: column; gap: 2px; }
  .act-time { font-size: 11.5px; }
}

/* ── Drawer ───────────────────────────────────────────────────────── */
.drawer { position: fixed; inset: 0; z-index: 60; }
.drawer-scrim { position: absolute; inset: 0; background: rgba(8,2,58,.36); backdrop-filter: blur(3px); }
.drawer-panel { position: absolute; top: 0; right: 0; bottom: 0; width: min(440px, 100%); background: #fff; box-shadow: -10px 0 40px rgba(10,10,10,.16); overflow-y: auto; padding: 22px; animation: slideIn .2s ease; }
@keyframes slideIn { from { transform: translateX(100%); } to { transform: translateX(0); } }
.drawer-panel h3 { font-size: 18px; margin-bottom: 4px; }
.drawer-field { margin-top: 16px; }
.drawer-field label { font-size: 12px; font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: .04em; display: block; margin-bottom: 6px; }
.drawer-field .val { font-size: 14px; color: var(--ink-2); line-height: 1.55; }
.drawer-field textarea, .field-input {
  width: 100%; border: 1px solid var(--line-2); border-radius: 11px; padding: 10px 12px; font-family: inherit; font-size: 14px; background: var(--bg-soft); color: var(--ink);
}
.drawer-field textarea { min-height: 120px; resize: vertical; font-family: "Geist Mono", monospace; font-size: 13px; line-height: 1.5; }
.field-input:focus, .drawer-field textarea:focus { outline: none; border-color: var(--purple); background: #fff; box-shadow: 0 0 0 4px rgba(122,51,255,.1); }

/* ── Modals ───────────────────────────────────────────────────────── */
.modal { position: fixed; inset: 0; z-index: 70; display: none; place-items: center; padding: 20px; background: rgba(8,2,58,.38); backdrop-filter: blur(4px); }
.modal.show { display: grid; }
/* The confirm dialog can open ON TOP of an already-open form/detail modal (e.g.
   the Remove/Disconnect button inside the connection-detail modal). Give it a
   higher stacking context so its backdrop + buttons are never occluded by the
   modal beneath it. Stays below the toast (z-index 90). */
.modal#confirmModal { z-index: 80; }
.modal-card { background: #fff; border-radius: 18px; padding: 24px; max-width: 460px; width: 100%; box-shadow: var(--shadow-lg); max-height: 88vh; overflow-y: auto; }
.modal-card h3 { font-size: 19px; margin-bottom: 8px; }
.modal-actions { display: flex; flex-wrap: wrap; gap: 10px; justify-content: flex-end; margin-top: 20px; }
.form-field { margin-top: 14px; }
.form-field label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 6px; color: var(--ink-2); }
.form-field textarea { min-height: 80px; resize: vertical; }

/* ── Toast ────────────────────────────────────────────────────────── */
.toast { position: fixed; left: 50%; bottom: 26px; transform: translate(-50%, 30px); background: var(--ink); color: #fff; padding: 12px 18px; border-radius: 12px; font-size: 14px; font-weight: 500; box-shadow: var(--shadow-lg); opacity: 0; pointer-events: none; transition: all .25s ease; z-index: 90; max-width: 90vw; }
.toast.show { transform: translate(-50%, 0); opacity: 1; }
.toast.error { background: var(--red); }
.toast.success { background: var(--green); }

/* ── Banner (tier / build count) ──────────────────────────────────── */
.banner { display: flex; align-items: center; gap: 14px; background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 14px 18px; margin-bottom: 20px; box-shadow: var(--shadow-sm); flex-wrap: wrap; }
.banner .bnum { font-family: "Inter Tight", sans-serif; font-weight: 800; font-size: 22px; color: var(--purple-3); }
.banner .btext { flex: 1; min-width: 160px; font-size: 13.5px; color: var(--ink-3); }
.banner .btext b { color: var(--ink); }

/* ── Responsive ───────────────────────────────────────────────────── */
@media (max-width: 880px) {
  .studio { grid-template-columns: 1fr; }
  .studio-toggle { display: flex; }
  .pane.builder-pane[data-mobile-hidden="true"], .pane.studio-pane[data-mobile-hidden="true"] { display: none; }
  .chat { height: min(560px, 66vh); }
  /* Single column: the panes are stacked, so there is no chat pane to match — a
     640px floor would just be dead space under a short tab. */
  .pane.studio-pane { min-height: 0; }
}
@media (max-width: 760px) {
  .topbar-inner { padding: 10px 14px; gap: 10px; flex-wrap: wrap; row-gap: 8px; }
  /* The tabs were a flex:1 item CLIPPED at .tabnav's right edge (a flex item with
     overflow:auto gets an automatic min-size of 0), so "Clients" vanished UNDER the
     tier chip with no scroll affordance. Give them their own full-width row. */
  .tabnav { order: 3; flex: 1 0 100%; margin-left: 0; }
  .top-actions { margin-left: auto; }
  /* Hide only the "← Member area" ANCHOR. #signOut is a <button class="top-link as-btn">,
     and the old `.top-actions .top-link` rule hid IT too — leaving no way to sign out
     below 760px. */
  .top-actions a.top-link { display: none; }
  .view { padding: 20px 14px 70px; }
  .page-head h1 { font-size: 23px; }
}
@media (max-width: 640px) {
  .grid { grid-template-columns: 1fr; }
  .drawer-panel { width: 100%; }
  .head-actions { width: 100%; }
  .head-actions .btn { flex: 1; }
  .bubble { max-width: 96%; font-size: 14.5px; }
  .chat-input { padding: 10px 10px calc(10px + env(safe-area-inset-bottom, 0px)); }
  .modal { padding: 12px; }
  .modal-card { padding: 20px 18px; }
  /* The title gets its own row on a phone:
         ← My agents   [paused]
         Personal Assistant (Telegram + ClickUp)
         [Run] [Activate] [Delete] …
     ⚠ The orders MUST be NEGATIVE. The action buttons are siblings with the default
     order:0, so any positive order here would push the TITLE below them (it did). */
  .studio-head .back { order: -3; }
  .studio-head #agentStatus { order: -2; }
  .studio-title { order: -1; flex: 1 1 100%; max-width: none; }
}
@media (max-width: 380px) {
  .brand-name { display: none; }
}

/* ── Increment 2: execution UI (run, connections, triggers, outputs) ──── */
.btn-run { background: var(--green, #0f9d58); color: #fff; box-shadow: 0 6px 18px rgba(15,157,88,.26); }
.btn-run:hover { background: #0b7c45; }

.notice { border-radius: 11px; padding: 11px 14px; font-size: 13px; line-height: 1.5; margin-bottom: 12px; }
.notice.amber { background: var(--amber-tint); color: var(--amber); border: 1px solid #f3dca0; }

/* Run modal */
.run-live { display: grid; place-items: center; gap: 12px; padding: 28px 8px; text-align: center; }
.run-status { display: inline-block; font-size: 12px; font-weight: 700; padding: 3px 10px; border-radius: 999px; text-transform: capitalize; margin-bottom: 6px; }
.run-status.ok { background: var(--green-tint); color: var(--green); }
.run-status.warn { background: var(--amber-tint); color: var(--amber); }
.run-status.err { background: var(--red-tint, #fde8e8); color: var(--red); }
.run-output { background: var(--bg-soft); border: 1px solid var(--line-2); border-radius: 11px; padding: 12px 14px; font-size: 14px; line-height: 1.55; max-height: 260px; overflow-y: auto; white-space: pre-wrap; word-wrap: break-word; }
.run-steps { display: flex; flex-direction: column; gap: 6px; }
.run-step { display: flex; gap: 9px; align-items: baseline; font-size: 13px; padding: 8px 10px; border-radius: 9px; background: var(--bg-soft); flex-wrap: wrap; }
.run-step .rs-ic { font-weight: 700; flex: none; width: 16px; text-align: center; }
.run-step.ok .rs-ic { color: var(--green); } .run-step.skipped .rs-ic { color: var(--ink-4); } .run-step.error .rs-ic { color: var(--red); }
.run-step .rs-title { font-weight: 600; flex: none; max-width: 100%; }
.run-step .rs-sum { color: var(--ink-3); min-width: 0; flex: 1 1 200px; overflow-wrap: anywhere; }
/* "What the agent did" — the thinking agent's per-tool-call trace (Increment 34). */
.run-step .rs-trace { flex-basis: 100%; margin: 4px 0 0 25px; display: flex; flex-direction: column; gap: 2px; border-left: 2px solid var(--line); padding-left: 8px; }
.rs-tcall { display: flex; gap: 6px; align-items: baseline; font-size: 12px; color: var(--ink-3); min-width: 0; }
.rs-tcall .rs-tic { flex: none; width: 10px; text-align: center; color: var(--ink-4); }
.rs-tcall.err .rs-tic, .rs-tcall.err .rs-tname { color: var(--red); }
.rs-tcall .rs-tname { font-weight: 600; flex: none; max-width: 46%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rs-tcall .rs-tnote { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Connections guide */
.conn-guide { font-size: 12.5px; color: var(--ink-3); line-height: 1.5; margin-top: 12px; background: var(--bg-soft); border-radius: 10px; padding: 10px 12px; min-height: 0; }
.conn-limiteduse { font-size: 11.5px; color: var(--ink-4); background: transparent; border: 1px dashed var(--line); padding: 8px 10px; margin-top: 8px; }
.conn-guide:empty { display: none; }
.conn-guide a { color: var(--purple-3); text-decoration: none; }

/* Connections — graph-aware tool cards */
.conn-tool .li-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.conn-tool .conn-guide { margin-top: 10px; }
.conn-actions { display: flex; flex-direction: column; gap: 6px; align-items: stretch; flex-shrink: 0; }
.conn-actions:empty { display: none; }
.conn-fixed { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 600; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--bg-soft); }
.conn-others { margin-top: 14px; }
.conn-others > summary { cursor: pointer; font-size: 13px; color: var(--ink-3); padding: 6px 2px; user-select: none; }
.conn-others > summary:hover { color: var(--ink-2); }
.conn-others .list-item { margin-top: 8px; }
/* A saved-key card opens its detail/edit view on click (whole card is the mouse
   target; the real "Manage" button is the keyboard control — its click bubbles up). */
.conn-clickable { cursor: pointer; transition: border-color .12s, box-shadow .12s, background .12s; }
.conn-clickable:hover { border-color: var(--purple); box-shadow: var(--shadow-md); }
.conn-clickable:focus-within { border-color: var(--purple); }
/* The ONE card you must act on reads urgent without shouting: a red rail + warm guide.
   NEVER applied to a `pending` (planned) card — a chat-staged tool has no graph step, so
   it can never block a run, and painting it red would recreate the very defect we're
   fixing ("the product demands an action that isn't needed"). */
.conn-tool.is-blocking { border-color: var(--need-line); box-shadow: inset 3px 0 0 var(--need-ink); }
.conn-tool.is-blocking .conn-guide { background: #fdf3f3; }
/* Nothing you — or we — can do yet. Recede, and never show a button (a button here
   would be a lie: oauth.start 503s when the family isn't configured). */
.conn-tool.is-waiting { background: var(--bg-soft); border-style: dashed; }
.conn-tool.is-waiting .card-icon { filter: grayscale(1); opacity: .7; }
.notice.red   { background: var(--need-tint); color: var(--need-ink); border: 1px solid var(--need-line); }
.notice.green { background: var(--ok-tint);   color: var(--ok-ink);   border: 1px solid #c7ead6; }
.notice.red a, .notice.green a { color: inherit; font-weight: 700; }
.vc-chip.wait { background: var(--bg-tint); color: var(--ink-3); border: 1px dashed var(--line-2); }
/* ⚠ SOURCE ORDER: the ≤560 .conn-tool rules below must stay AFTER the .is-* rules above. */
@media (max-width: 560px) {
  .conn-tool { flex-wrap: wrap; }
  .conn-tool .conn-actions { flex-direction: row; width: 100%; }
  .conn-tool .conn-actions .btn { flex: 1; }
}

/* Connection detail / edit modal (masked key + live API data + replace/remove) */
.cd-title { display: flex; align-items: center; gap: 8px; }
.cd-status { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; font-size: 13px; font-weight: 600; color: var(--green); background: var(--green-tint); border-radius: 10px; padding: 9px 12px; margin: 4px 0 12px; }
.cd-status .cd-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--green); flex-shrink: 0; }
.cd-key { font-family: "Geist Mono", monospace; font-size: 12.5px; color: var(--ink-1, var(--ink-2)); background: #fff; border: 1px solid var(--line-2); border-radius: 7px; padding: 2px 8px; font-weight: 700; }
.cd-enc { font-size: 11.5px; font-weight: 600; color: var(--ink-3); }
.cd-rows { border: 1px solid var(--line); border-radius: 11px; overflow: hidden; margin-bottom: 14px; }
.cd-row { display: flex; gap: 12px; padding: 8px 12px; font-size: 13px; }
.cd-row + .cd-row { border-top: 1px solid var(--line); }
.cd-row .cd-k { flex: 0 0 38%; max-width: 160px; color: var(--ink-3); font-weight: 600; }
.cd-row .cd-v { flex: 1; min-width: 0; color: var(--ink-2); overflow-wrap: anywhere; }
.cd-data-h { font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: var(--ink-3); margin-bottom: 6px; }
.cd-data { min-height: 0; }
.cd-replace { border: 1px solid var(--line-2); border-radius: 11px; padding: 12px; margin-top: 6px; background: var(--bg-soft); }
.cd-actions { align-items: center; }
.cd-actions .cd-spacer { flex: 1 1 auto; }
.btn.ghost.danger { background: #fff; border-color: #f0c8c4; color: var(--red); }
.btn.ghost.danger:hover { border-color: var(--red); color: var(--red); background: #fff5f4; }
@media (max-width: 560px) {
  .cd-row { flex-direction: column; gap: 2px; }
  .cd-row .cd-k { flex-basis: auto; max-width: none; }
  .cd-actions .cd-spacer { display: none; }
  .cd-actions .btn { flex: 1; }
}

/* Add-connection modal: FOUR buttons (Cancel · Test · Explore my data · Save) jumbled
   into a 2×2 grid on a phone with no clear primary. Stack them, primary on top. */
.conn-modal-actions { justify-content: flex-end; }
.conn-modal-actions .cd-spacer { flex: 1 1 auto; }
@media (max-width: 560px) {
  .conn-modal-actions { flex-direction: column-reverse; align-items: stretch; }
  .conn-modal-actions .cd-spacer { display: none; }
  .conn-modal-actions .btn { width: 100%; }
}
/* Searchable service picker — the catalog is long and a <select> is unsearchable.
   The <select id="connProv"> STAYS in the DOM (hidden) as the single source of truth,
   so gatherConn()/refreshExtra() and the tagName==='SELECT' check are unchanged. */
.conn-pick { border: 1px solid var(--line-2); border-radius: var(--r-md); background: var(--bg-soft); }
.conn-pick-search { width: 100%; border: 0; border-bottom: 1px solid var(--line); background: transparent; padding: 10px 12px; font-family: inherit; font-size: 14px; color: var(--ink); border-radius: var(--r-md) var(--r-md) 0 0; }
.conn-pick-search:focus { outline: none; border-bottom-color: var(--purple); background: #fff; }
.conn-pick-list { max-height: 190px; overflow-y: auto; padding: 4px; display: flex; flex-direction: column; gap: 2px; }
.conn-pick-opt { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; font: inherit; font-size: 13.5px; color: var(--ink-2); background: transparent; border: 0; border-radius: var(--r-sm); padding: 8px 10px; cursor: pointer; }
.conn-pick-opt:hover { background: var(--purple-tint); color: var(--purple-3); }
.conn-pick-opt.sel { background: var(--purple-tint); color: var(--purple-3); font-weight: 600; }
.conn-pick-none { padding: 10px 12px; font-size: 13px; color: var(--ink-3); }
/* The <select> is hidden, so this line IS the member's only confirmation of where their
   secret is about to be POSTed. Do not remove it without un-hiding the select. */
.conn-pick-chosen { margin-top: 6px; font-size: 12.5px; color: var(--ink-3); }
.conn-pick-chosen b { color: var(--ink); }

/* Triggers */
.triggers .trig-block { border: 1px solid var(--line); border-radius: 14px; padding: 16px 18px; margin-bottom: 12px; background: #fff; box-shadow: var(--shadow-sm); }
.triggers .trig-h { font-family: "Inter Tight", sans-serif; font-weight: 700; font-size: 14.5px; margin-bottom: 6px; display: flex; align-items: center; gap: 8px; }
.triggers .trig-list { margin: 8px 0 0; padding-left: 20px; }
.triggers .trig-list li { margin: 4px 0; font-size: 13.5px; color: var(--ink-2); }
.triggers .trig-list li::marker { color: var(--purple); }
/* Real toggle switches (the inputs stay native checkboxes — keyboard + a11y intact). */
.switch-row { display: flex; align-items: center; gap: 10px; font-size: 13.5px; color: var(--ink-2); cursor: pointer; }
.switch-row input {
  appearance: none; -webkit-appearance: none; flex: none;
  width: 40px; height: 23px; border-radius: 999px; margin: 0;
  background: var(--line-2); position: relative; cursor: pointer;
  transition: background .18s ease;
}
.switch-row input::after {
  content: ""; position: absolute; top: 2.5px; left: 3px; width: 18px; height: 18px;
  border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(10,10,10,.28);
  transition: transform .18s ease;
}
.switch-row input:checked { background: var(--purple); }
.switch-row input:checked::after { transform: translateX(16px); }
.switch-row input:disabled { opacity: .45; cursor: not-allowed; }
.webhook-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.webhook-row code { flex: 1; min-width: 0; font-family: "Geist Mono", monospace; font-size: 12px; background: var(--bg-soft); border: 1px solid var(--line-2); border-radius: 9px; padding: 9px 11px; overflow-x: auto; white-space: nowrap; color: var(--ink-2); }
/* The one save bar for switches + schedules — sticky so it's never lost below
   the fold on a long Triggers tab. */
.triggers .trig-save {
  position: sticky; bottom: 10px; z-index: 5;
  display: flex; gap: 10px; align-items: center; justify-content: flex-end;
  background: rgba(255,255,255,.92); backdrop-filter: blur(8px);
  border: 1px solid var(--line); border-radius: 14px; padding: 10px 12px;
  box-shadow: var(--shadow-md); margin-top: 14px;
}
@media (max-width: 640px) {
  .triggers .trig-save { justify-content: stretch; }
  .triggers .trig-save .btn { flex: 1; }
}

/* Outputs */
.out-card { border: 1px solid var(--line); border-radius: 14px; padding: 14px 16px; background: #fff; margin-bottom: 12px; box-shadow: var(--shadow-sm); }
.out-head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.out-ico { font-size: 16px; }
.out-title { font-weight: 700; font-size: 14px; font-family: "Inter Tight", sans-serif; flex: 1; min-width: 0; }
.out-time { font-size: 12px; margin-left: auto; }
.out-body { font-size: 14px; line-height: 1.6; color: var(--ink-2); margin-top: 10px; white-space: pre-wrap; word-wrap: break-word; max-height: 320px; overflow-y: auto; background: var(--bg-soft); border-radius: 10px; padding: 12px 14px; }
.out-actions { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }

/* Run-as client switcher (studio head) */
.run-as { font-size: 12.5px; font-weight: 600; color: var(--ink-2); background: #fff; border: 1px solid var(--line-2); border-radius: 9px; padding: 6px 9px; max-width: 200px; cursor: pointer; font-family: inherit; }
.run-as:hover { border-color: var(--purple); color: var(--purple-3); }

/* tiny button (KB row actions) */
.btn.xs { font-size: 11.5px; padding: 4px 9px; border-radius: 8px; }

/* Knowledge rows — fetched status (#3) */
.kb-row .kb-st { font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 999px; }
.kb-st.ok { background: var(--green-tint); color: var(--green); }
.kb-st.err { background: var(--red-tint, #fdeaea); color: var(--red, #c0392b); }
.kb-st.pending { background: var(--bg-tint); color: var(--ink-3); }
.kb-preview { font-size: 12px; color: var(--ink-3); margin-top: 8px; line-height: 1.5; background: var(--bg-soft); border-radius: 9px; padding: 9px 11px; max-height: 88px; overflow: hidden; }

/* Client-detail page sections (#4) */
.client-sec { background: #fff; border: 1px solid var(--line); border-radius: 16px; padding: 18px 20px; margin-bottom: 18px; box-shadow: var(--shadow-sm); }
.client-sec .cs-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 6px; flex-wrap: wrap; }
.client-sec .cs-head h2 { font-size: 17px; font-family: "Inter Tight", sans-serif; letter-spacing: -.01em; }
.client-sec > p { margin-bottom: 14px; }
.client-sec .list-item + .list-item { margin-top: 10px; }

/* ── Agent canvas (drag-anywhere studio) ─────────────────────────────────────── */
.canvas-toolbar { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
/* Viewport: clips the world; scroll/drag pans, ctrl/pinch zooms. touch-action:none
 * keeps the page from scrolling/zooming while you interact with the diagram. */
.agent-canvas {
  position: relative; overflow: hidden; height: min(68vh, 640px);
  background-color: var(--bg-soft); border-radius: 0 0 16px 16px;
  cursor: grab; touch-action: none; overscroll-behavior: contain;
}
.agent-canvas.panning { cursor: grabbing; }
/* World: the pan/zoom-transformed layer holding the SVG edges + node cards. The dot
 * grid lives here so it moves with the content. */
.canvas-world {
  position: absolute; top: 0; left: 0; transform-origin: 0 0; will-change: transform;
  background-image: radial-gradient(rgba(122,51,255,.12) 1px, transparent 1px);
  background-size: 24px 24px;
}
.canvas-edges { position: absolute; top: 0; left: 0; pointer-events: none; z-index: 1; overflow: visible; }
.edge-path { fill: none; stroke: var(--line-2); stroke-width: 2; }
.edge-dot { fill: var(--purple); }
.edge-lbl-bg { fill: #fff; stroke: var(--line-2); stroke-width: 1; }
.edge-text { fill: var(--ink-3); font-size: 10.5px; font-weight: 700; text-anchor: middle; }
/* Floating zoom / fit / tidy controls — fixed over the viewport (outside the transform). */
.canvas-controls {
  position: absolute; right: 12px; bottom: 12px; z-index: 6; display: flex; align-items: center; gap: 4px;
  background: rgba(255,255,255,.94); border: 1px solid var(--line); border-radius: 12px;
  padding: 4px; box-shadow: var(--shadow-md); backdrop-filter: blur(4px);
}
.canvas-controls .zc {
  border: none; background: transparent; color: var(--ink-2); font-size: 15px; font-weight: 700;
  width: 34px; height: 34px; border-radius: 8px; cursor: pointer; display: grid; place-items: center; line-height: 1;
  font-family: inherit;
}
.canvas-controls .zc:hover { background: var(--purple-tint); color: var(--purple-3); }
.canvas-controls .zc-tidy { width: auto; padding: 0 11px; font-size: 12.5px; gap: 4px; }
.canvas-controls .zc-level { font-size: 11.5px; font-weight: 700; color: var(--ink-4); min-width: 38px; text-align: center; user-select: none; }

/* ── THE MOBILE SCROLL TRAP ────────────────────────────────────────────────────
 * THE MECHANISM: `touch-action` is INTERSECTED down the ancestor chain, so the
 * viewport's `none` VETOES any descendant's `pan-y` — the viewport itself has to
 * relax. With pan-y the nearest scroll container (the document) takes the gesture,
 * so a one-finger swipe scrolls the PAGE.
 *
 * On a COARSE pointer the diagram starts LOCKED behind a transparent overlay: the
 * overlay carries no pan handler AND covers the cards, so a swipe produces ZERO world
 * movement before the browser claims it. Because the UA fires `pointercancel` when it
 * takes the scroll, NO click fires — a scroll can therefore never accidentally unlock;
 * only a deliberate TAP does, and that tap is handed through to the step underneath
 * (so tap-to-edit still costs ONE tap).
 *
 * Desktop (fine pointer) never gets .is-touch/.is-locked → every mouse path is
 * byte-identical to before. `.agent-canvas.is-locked` (0,2,0) beats `.agent-canvas`
 * (0,1,0), so this is order-independent and does NOT belong in the late @media block. */
.agent-canvas.is-locked { touch-action: pan-y; cursor: default; }
.canvas-lock { display: none; }
.agent-canvas.is-locked .canvas-lock {
  display: block; position: absolute; inset: 0; z-index: 7;
  touch-action: pan-y; background: transparent; -webkit-tap-highlight-color: transparent;
}
/* Locked: the floating controls are unreachable behind the overlay anyway — and on a
   phone they sit right ON TOP of the node cards. Hide them; show one honest hint. */
.agent-canvas.is-locked .canvas-controls { display: none; }
.canvas-lock-hint {
  position: absolute; left: 50%; bottom: 12px; transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; pointer-events: none;
  padding: 8px 14px; border-radius: 999px; background: rgba(255,255,255,.94);
  border: 1px solid var(--line); box-shadow: var(--shadow-md); backdrop-filter: blur(4px);
  font-size: 12.5px; font-weight: 700; color: var(--ink-2);
}
/* The way BACK to a scrollable page — only on touch, only while unlocked. */
.canvas-controls .zc-lock { display: none; }
.agent-canvas.is-touch:not(.is-locked) .canvas-controls .zc-lock {
  display: grid; width: auto; padding: 0 11px; font-size: 12.5px;
  background: var(--purple-tint); color: var(--purple-3);
}
.canvas-node {
  position: absolute; z-index: 2; cursor: grab; touch-action: none;
  box-shadow: var(--shadow-sm); user-select: none;
}
.canvas-node.node-card:hover { border-color: var(--purple); box-shadow: var(--shadow-md); }
.canvas-node.dragging { cursor: grabbing; box-shadow: var(--shadow-md); opacity: .96; z-index: 5; }
.canvas-node.is-trigger { background: var(--grad-card); color: #fff; border: none; padding: 13px 15px; border-radius: 14px; cursor: default; }
.canvas-node.is-trigger .ntitle { color: #fff; }
.canvas-node.is-trigger .nkind { color: rgba(255,255,255,.75); }
.canvas-node.is-trigger .ndesc { color: rgba(255,255,255,.85); }
/* Keep canvas cards compact + evenly sized — long descriptions are clamped here
 * (the full text shows in the node drawer on click), so the measured column
 * reflow stays tidy and the diagram reads as an organized flow. */
.canvas-node .ndesc {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4;
  line-clamp: 4; overflow: hidden;
}
.canvas-node.is-trigger .ndesc { -webkit-line-clamp: 2; line-clamp: 2; }
.ntag.op { background: #e7f0ff; color: #2563eb; }
/* Per-node data-flow footer (Increment 22): last-run status + output field count. */
.node-card .nfoot { display: flex; align-items: center; gap: 8px; margin-top: 9px; padding-top: 8px; border-top: 1px dashed var(--line); font-size: 11px; }
.io-dot { font-weight: 800; font-size: 12px; line-height: 1; }
.io-dot.ok { color: #15803d; }
.io-dot.err { color: #dc2626; }
.io-dot.skip { color: var(--ink-3); }
.io-foot-f { color: var(--ink-3); font-weight: 600; }

/* Node drawer — AI edit box + actions */
.drawer-ai { margin-top: 14px; background: var(--purple-tint); border: 1px solid #e6dbff; border-radius: 13px; padding: 12px; }
.drawer-ai label { font-size: 12px; font-weight: 700; color: var(--purple-3); text-transform: uppercase; letter-spacing: .04em; display: block; margin-bottom: 7px; }
.drawer-ai textarea { width: 100%; min-height: 56px; resize: vertical; border: 1px solid var(--line-2); border-radius: 10px; padding: 9px 11px; font-family: inherit; font-size: 13.5px; line-height: 1.45; background: #fff; color: var(--ink); box-sizing: border-box; }
.drawer-ai textarea:focus { outline: none; border-color: var(--purple); box-shadow: 0 0 0 4px rgba(122,51,255,.1); }
.btn.block { display: block; width: 100%; }
.drawer-actions { margin-top: 18px; display: flex; gap: 8px; }
.drawer-actions .btn { flex: 1; }
.btn.danger-ghost { background: #fff; border: 1px solid #f3c9c9; color: var(--red); }
.btn.danger-ghost:hover { border-color: var(--red); background: #fff5f5; }
.param-list { margin-top: 8px; display: flex; flex-direction: column; gap: 4px; }
.param-row { display: flex; gap: 8px; font-size: 12.5px; background: var(--bg-soft); border-radius: 7px; padding: 4px 8px; }
.param-row .pk { font-weight: 700; color: var(--ink-2); font-family: "Geist Mono", monospace; }
.param-row .pv { color: var(--ink-3); min-width: 0; overflow-wrap: anywhere; }

/* Editable tool-action inputs in the node drawer (req #2/#3 — node variables). */
.op-pill { display: inline-block; font-family: "Geist Mono", monospace; font-size: 12px; font-weight: 700; color: #2563eb; background: #e7f0ff; border-radius: 7px; padding: 3px 9px; }
.param-edits { margin-top: 10px; display: flex; flex-direction: column; gap: 10px; }
.param-edit .pk-label { display: block; font-size: 12px; font-weight: 700; color: var(--ink-2); font-family: "Geist Mono", monospace; text-transform: none; letter-spacing: 0; margin-bottom: 4px; }
.param-input { width: 100%; box-sizing: border-box; border: 1px solid var(--line-2); border-radius: 9px; padding: 8px 10px; font-family: "Geist Mono", monospace; font-size: 12.5px; line-height: 1.45; background: var(--bg-soft); color: var(--ink); resize: vertical; }
.param-input:focus { outline: none; border-color: var(--purple); background: #fff; box-shadow: 0 0 0 4px rgba(122,51,255,.1); }
.var-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.var-chip { font-family: "Geist Mono", monospace; font-size: 11.5px; font-weight: 600; color: var(--purple-3); background: var(--purple-tint); border: 1px solid #e6dbff; border-radius: 7px; padding: 3px 8px; cursor: pointer; user-select: none; }
.var-chip:hover { background: #e6dbff; }
.out-hint { font-size: 11.5px; margin-top: 10px; padding: 8px 10px; background: var(--bg-soft); border-radius: 9px; color: var(--ink-3); }
.out-hint code { font-family: "Geist Mono", monospace; color: var(--purple-3); font-size: 11px; }
/* ── Per-node Input / Output data-flow panels (Increment 22 — n8n-style) ── */
.io-statusrow { margin: 10px 0 2px; }
.io-pill { display: inline-block; font-size: 11.5px; font-weight: 700; padding: 3px 10px; border-radius: 999px; }
.io-pill.ok { background: #e8f7ee; color: #15803d; }
.io-pill.error { background: #fde8e8; color: #b91c1c; }
.io-pill.skipped { background: var(--bg-tint); color: var(--ink-3); }
.io-panel { border-left: 3px solid var(--line-2); padding-left: 11px; }
.io-panel.io-in { border-left-color: #93c5fd; }
.io-panel.io-out { border-left-color: #c4b5fd; }
.io-pre { margin: 2px 0 0; max-height: 200px; overflow: auto; background: #0f172a; color: #e2e8f0; border-radius: 10px; padding: 10px 12px; font-family: "Geist Mono", monospace; font-size: 11.5px; line-height: 1.5; white-space: pre-wrap; word-break: break-word; }
.io-src { font-size: 11px; margin-top: 5px; }
.io-wired { display: flex; flex-direction: column; gap: 4px; }
.io-wired code { font-family: "Geist Mono", monospace; font-size: 11.5px; color: var(--ink-2); background: var(--bg-tint); border-radius: 6px; padding: 3px 7px; overflow-wrap: anywhere; }
.io-fields { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; margin-top: 9px; }
.io-fl { font-size: 11px; font-weight: 700; color: var(--ink-3); }
.io-field { font-family: "Geist Mono", monospace; font-size: 11px; color: #1d4ed8; background: #eef4ff; border: 1px solid #d6e4ff; border-radius: 6px; padding: 2px 7px; overflow-wrap: anywhere; }

/* Fix-with-AI button on a failed run step */
.run-step .rs-fix { margin-left: auto; flex: none; font-size: 11.5px; font-weight: 700; color: var(--purple-3); background: var(--purple-tint); border: 1px solid #e6dbff; border-radius: 8px; padding: 3px 9px; cursor: pointer; white-space: nowrap; font-family: inherit; }
.run-step .rs-fix:hover { background: var(--purple); color: #fff; border-color: var(--purple); }

/* Field-level variable chips in the node drawer (data the API returned). */
.var-chip.field { color: #1d4ed8; background: #eef4ff; border-color: #d6e4ff; }
.var-chip.field:hover { background: #dbe8ff; }
.var-group { margin-top: 10px; }
.var-group-h { font-size: 11px; font-weight: 700; color: var(--ink-3); text-transform: none; letter-spacing: 0; margin-bottom: 5px; }

/* Connection test / preview panel (under the add-connection form). */
.conn-test:empty { display: none; }
.conn-test { margin: 4px 0 12px; }
.ct-loading { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink-3); }
.spinner.sm { width: 15px; height: 15px; border-width: 2px; margin: 0; display: inline-block; vertical-align: middle; }
.ct-ok { font-size: 13px; font-weight: 700; color: var(--green); background: var(--green-tint); border-radius: 9px; padding: 9px 11px; }
.ct-note { font-size: 13px; color: var(--ink-2); background: var(--bg-soft); border-radius: 9px; padding: 9px 11px; }
.ct-fail { font-size: 13px; font-weight: 600; color: #b42318; background: #fef3f2; border-radius: 9px; padding: 9px 11px; }
.ct-fields { margin-top: 9px; font-size: 12px; color: var(--ink-2); }
.ct-fields b { font-size: 11.5px; }
.ct-chips { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 6px; }
.ct-chip { font-family: "Geist Mono", monospace; font-size: 11px; color: #1d4ed8; background: #eef4ff; border: 1px solid #d6e4ff; border-radius: 6px; padding: 2px 7px; max-width: 100%; overflow-wrap: anywhere; }
.ct-pre { margin-top: 9px; max-height: 220px; overflow: auto; background: #0f172a; color: #e2e8f0; border-radius: 10px; padding: 11px 13px; font-family: "Geist Mono", monospace; font-size: 11.5px; line-height: 1.5; white-space: pre-wrap; word-break: break-word; }

/* "Explore my data" — discovered resources (lists/boards/fields) with copyable IDs. */
.ct-group { margin-top: 10px; }
.ct-group > b { font-size: 11.5px; color: var(--ink-2); text-transform: uppercase; letter-spacing: .03em; }
.ct-res { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; text-align: left; cursor: pointer; background: #eef4ff; border: 1px solid #d6e4ff; border-radius: 7px; padding: 4px 8px; font: inherit; transition: background .12s, border-color .12s; }
.ct-res:hover { background: #e0ecff; border-color: #b9d2ff; }
.ct-res-lbl { font-size: 12px; font-weight: 600; color: var(--ink-1); overflow-wrap: anywhere; }
.ct-res-id { font-family: "Geist Mono", monospace; font-size: 10.5px; color: #1d4ed8; overflow-wrap: anywhere; }

/* Pretty JSON / API-response output in the Outputs tab. */
.out-json-status { font-family: "Geist Mono", monospace; font-size: 11.5px; font-weight: 700; color: var(--ink-3); margin-top: 10px; }
.out-json { margin-top: 7px; max-height: 340px; overflow: auto; background: #0f172a; color: #e2e8f0; border-radius: 11px; padding: 12px 14px; font-family: "Geist Mono", monospace; font-size: 12px; line-height: 1.55; white-space: pre-wrap; word-break: break-word; }
.out-fields { margin-top: 10px; }
.out-fields summary { font-size: 12px; font-weight: 700; color: var(--purple-3); cursor: pointer; }
.out-fields .ct-chips { margin-top: 8px; }
/* Say it when a preview is trimmed. The output used to just STOP mid-token at 6000
   chars with no indicator — the member had no way to know they weren't seeing it all. */
.out-trunc { margin-top: 6px; font-size: 11.5px; color: var(--ink-3); background: var(--bg-tint); border-radius: var(--r-sm); padding: 6px 9px; }

/* ── Late responsive overrides ─────────────────────────────────────────────────
 * These MUST stay at the end of the file: media queries add no specificity, so an
 * override placed before its base rule (e.g. the .agent-canvas height above) is
 * silently cascaded away by source order. Anything overriding a component defined
 * later in this stylesheet belongs here. */
@media (max-width: 640px) {
  /* Leave room to scroll PAST the diagram on a phone (the canvas swallows one-finger
     drags to pan, so a full-height canvas can trap the page scroll). */
  .agent-canvas { height: min(54vh, 520px); }
}
