/* Connector Cloud — Modgard Studio shell + Ngentix brand tokens */

:root {
  --ngentix-primary: #00b26e;
  --ngentix-primary-light: #d3fdb1;
  --ngentix-secondary-dark: #042222;
  --ngentix-secondary: #184a4b;
  --ngentix-secondary-mid: #006d5a;
  --ngentix-accent-green: #30c986;
  --grey-975: #0e1014;
  --grey-950: #111318;
  --grey-900: #181b22;
  --grey-850: #22262e;
  --grey-700: #3b3f47;
  --grey-600: #52565e;
  --grey-500: #858587;
  --grey-400: #9d9d9f;
  --grey-300: #b4b4b5;
  --grey-200: #cacacb;
  --grey-100: #e1e1e2;
  --grey-50: #ededed;
  --grey-25: #f8f8f8;
  --ink: #f5f4f2;
  --ink-secondary: #cdcbc6;
  --ink-muted: #97948c;
  --status-ok: #2a9b6a;
  --status-attention: #c9852a;
  --status-broken: #c4523d;
  --err: #e5484d;
  --radius-sm: 3px;
  --radius-md: 6px;
  --radius-lg: 9px;
  --radius-xl: 12px;
  --sidebar-width: 15.5rem;
  --sidebar-collapsed-width: 4.5rem;
  --topbar-height: 3.5rem;
  --focus-ring: rgba(0, 178, 110, 0.45);
  --surface: #181b22;
  /* One step above --surface. Used where an element must read as an object
     sitting ON the page rather than a recess in it — code blocks, explain
     panels. */
  --surface-raised: #21262f;
  --canvas: #0e1014;
}

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

html,
body {
  height: 100%;
}

body.studio-app {
  margin: 0;
  font-family: Inter, system-ui, sans-serif;
  font-size: 15px;
  font-weight: 450;
  line-height: 1.5;
  color: var(--ink);
  background: var(--grey-975);
  -webkit-font-smoothing: antialiased;
}

/* The `hidden` attribute is only a `display: none` default — any explicit
   `display` in a class rule beats it. Both of these set `display: flex`, so
   toggling `.hidden` in showAuth() left the hidden panel laid out at 100vh and
   pushed the other one a full viewport down the page: after logging in you saw
   the login card and had to scroll to reach the console. */
.auth-gate[hidden],
.app-shell[hidden] {
  display: none;
}

/* Password reset affordances (FEA-CC-055). */
.auth-alt {
  margin: 0.85rem 0 0;
  text-align: center;
}

.linkish {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-size: 0.85rem;
  color: var(--brand-400, #12b981);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.linkish:hover {
  opacity: 0.85;
}

.field-hint {
  margin: -0.35rem 0 0.6rem;
  font-size: 0.78rem;
  color: var(--grey-400, #9fb0c3);
}

/* ——— Auth gate (AuthActionFrame) ——— */

.auth-gate {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background:
    radial-gradient(ellipse 80% 50% at 100% 0%, rgba(0, 178, 110, 0.1), transparent 55%),
    radial-gradient(ellipse 60% 40% at 0% 100%, rgba(24, 74, 75, 0.4), transparent 50%),
    var(--grey-975);
}

.auth-frame {
  width: 100%;
  max-width: 24rem;
}

.auth-brand {
  text-align: center;
  margin-bottom: 1.5rem;
}

.auth-brand img {
  height: 28px;
  width: auto;
  margin-bottom: 0.75rem;
}

.auth-product {
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.auth-tagline {
  margin: 0.35rem 0 0;
  font-size: 0.8125rem;
  color: var(--ink-muted);
}

.auth-card {
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--radius-xl);
  background: var(--grey-900);
  padding: 1.5rem;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.35);
}

.auth-tabs {
  display: flex;
  gap: 0.35rem;
  margin-bottom: 1.25rem;
  padding: 0.25rem;
  background: rgba(255, 255, 255, 0.03);
  border-radius: var(--radius-md);
}

.tab {
  flex: 1;
  margin: 0;
  padding: 0.5rem 0.75rem;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--ink-muted);
  font: inherit;
  font-weight: 500;
  font-size: 0.8125rem;
  cursor: pointer;
}

.tab.active {
  background: rgba(0, 178, 110, 0.15);
  color: var(--ngentix-primary-light);
}

.auth-heading {
  margin: 0 0 0.35rem;
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.auth-form label {
  display: grid;
  gap: 0.3rem;
  margin: 0.75rem 0;
  font-size: 0.8125rem;
  color: var(--ink-secondary);
}

.auth-form input,
.inline-label input,
.inline-label select,
select,
input {
  width: 100%;
  padding: 0.55rem 0.7rem;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--radius-md);
  background: var(--grey-950);
  color: var(--ink);
  font: inherit;
}

.auth-form input:focus,
input:focus,
select:focus {
  outline: none;
  border-color: rgba(0, 178, 110, 0.55);
  box-shadow: 0 0 0 3px var(--focus-ring);
}

.oidc-divider {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 1.25rem 0 0.75rem;
  color: var(--ink-muted);
  font-size: 0.75rem;
}

.oidc-divider::before,
.oidc-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: rgba(255, 255, 255, 0.08);
}

.oidc-actions {
  display: flex;
  gap: 0.5rem;
}

.oidc-actions .btn-secondary {
  flex: 1;
  text-align: center;
}

/* ——— App shell ——— */

.app-shell {
  display: flex;
  min-height: 100vh;
  background:
    radial-gradient(ellipse 80% 50% at 100% 0%, rgba(0, 178, 110, 0.08), transparent 55%),
    radial-gradient(ellipse 60% 40% at 0% 100%, rgba(24, 74, 75, 0.35), transparent 50%),
    var(--grey-975);
}

.app-sidebar {
  width: var(--sidebar-width);
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  padding: 1rem 0.65rem;
  background: rgba(14, 16, 20, 0.96);
  backdrop-filter: blur(20px) saturate(160%);
  border-right: 1px solid rgba(255, 255, 255, 0.06);
  transition: width 0.2s ease;
}

.sidebar-top {
  display: flex;
  align-items: flex-start;
  gap: 0.35rem;
  padding-bottom: 1rem;
  margin-bottom: 0.5rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.sidebar-brand {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  flex: 1;
  min-width: 0;
  padding: 0 0.35rem;
  text-decoration: none;
  color: inherit;
}

.sidebar-wordmark {
  display: block;
  height: 26px;
  width: auto;
  max-width: 100%;
}

.sidebar-mark {
  display: none;
  height: 26px;
  width: auto;
}

.sidebar-brand-text {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.sidebar-product {
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.sidebar-tagline {
  font-size: 0.75rem;
  color: var(--ink-muted);
}

.sidebar-collapse-btn,
.sidebar-mobile-btn {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.03);
  color: var(--ink-muted);
  cursor: pointer;
}

.sidebar-collapse-btn:hover,
.sidebar-mobile-btn:hover {
  color: var(--ink);
  border-color: rgba(0, 178, 110, 0.35);
  background: rgba(0, 178, 110, 0.08);
}

.sidebar-mobile-btn {
  display: none;
}

.sidebar-nav {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  flex: 1;
}

.sidebar-link {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.6rem 0.75rem;
  border-radius: var(--radius-md);
  color: var(--ink-secondary);
  text-decoration: none;
  font-size: 0.9375rem;
  font-weight: 500;
  border-left: 3px solid transparent;
}

.sidebar-link:hover {
  color: var(--ink);
  background: rgba(255, 255, 255, 0.04);
}

.sidebar-link.is-active {
  color: var(--ink);
  background: rgba(0, 178, 110, 0.1);
  border-left-color: var(--ngentix-primary);
}

.sidebar-link-muted {
  margin-top: auto;
  color: var(--ink-muted);
  font-size: 0.8125rem;
}

.sidebar-icon {
  width: 1.25rem;
  text-align: center;
  opacity: 0.85;
}

.sidebar-footer {
  padding: 0.75rem 0.5rem 0.25rem;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  margin-top: 0.75rem;
}

.sidebar-footer-label {
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.app-shell.sidebar-collapsed .app-sidebar {
  width: var(--sidebar-collapsed-width);
}

.app-shell.sidebar-collapsed .sidebar-wordmark,
.app-shell.sidebar-collapsed .sidebar-brand-text,
.app-shell.sidebar-collapsed .sidebar-footer,
.app-shell.sidebar-collapsed .sidebar-label {
  display: none;
}

.app-shell.sidebar-collapsed .sidebar-mark {
  display: block;
}

.app-shell.sidebar-collapsed .sidebar-link {
  justify-content: center;
  border-left: none;
}

.app-main-column {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.app-topbar {
  height: var(--topbar-height);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 1.5rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  background: rgba(14, 16, 20, 0.72);
  backdrop-filter: blur(12px);
}

.topbar-left,
.topbar-right {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.topbar-title {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.user-chip {
  font-size: 0.8125rem;
  color: var(--ink-muted);
  max-width: 20rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.app-content {
  flex: 1;
  overflow-y: auto;
  padding: 2rem;
  max-width: 1100px;
}

.view[hidden] {
  display: none !important;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  margin-bottom: 1.5rem;
  flex-wrap: wrap;
}

.page-heading {
  margin: 0;
  font-size: 1.375rem;
  font-weight: 600;
  letter-spacing: -0.025em;
}

.page-sub {
  margin: 0.35rem 0 0;
  color: var(--ink-muted);
  font-size: 0.875rem;
}

.muted {
  color: var(--ink-muted);
  font-size: 0.875rem;
}

/* Buttons */

.btn-primary,
.btn-secondary,
.btn-ghost,
button.checkout {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  margin: 0;
  padding: 0.55rem 0.95rem;
  border-radius: var(--radius-md);
  font: inherit;
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  border: 1px solid transparent;
}

.btn-primary,
button.checkout.btn-primary {
  background: var(--ngentix-primary);
  color: #fff;
  border-color: var(--ngentix-primary);
}

.btn-primary:hover {
  background: #00c57a;
}

.btn-secondary,
button.checkout.btn-secondary {
  background: rgba(255, 255, 255, 0.04);
  color: var(--ink);
  border-color: rgba(255, 255, 255, 0.12);
}

.btn-ghost {
  background: transparent;
  color: var(--ink-muted);
  border-color: transparent;
}

.btn-ghost:hover {
  color: var(--ink);
  background: rgba(255, 255, 255, 0.04);
}

.btn-block {
  width: 100%;
  margin-top: 0.5rem;
}

.row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
}

.row.compact {
  gap: 0.4rem;
}

/* Stat cards / panels / lists */

.stat-cards {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}

.stat-card {
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--radius-lg);
  background: var(--grey-900);
  padding: 1rem 1.1rem;
}

.stat-card-label {
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.stat-card-value {
  margin-top: 0.35rem;
  font-size: 1.5rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.03em;
}

.stat-card-hint {
  margin-top: 0.25rem;
  font-size: 0.75rem;
  color: var(--ink-muted);
}

.panel {
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--radius-lg);
  background: var(--grey-900);
  padding: 1rem 1.15rem;
  margin-bottom: 1rem;
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 0.75rem;
}

.panel-title {
  margin: 0 0 0.65rem;
  font-size: 0.9375rem;
  font-weight: 600;
}

.panel-header .panel-title {
  margin-bottom: 0;
}

.list-section {
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--radius-lg);
  background: var(--grey-900);
  overflow: hidden;
}

.list-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  padding: 0.65rem 1rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  background: rgba(255, 255, 255, 0.02);
  font-size: 0.75rem;
  color: var(--ink-muted);
}

.row-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.row-list > li {
  padding: 0.85rem 1rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  font-size: 0.875rem;
}

.row-list > li:last-child {
  border-bottom: 0;
}

.row-list > li.muted {
  color: var(--ink-muted);
}

.status-dot {
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  margin-right: 0.35rem;
  vertical-align: middle;
}

.status-dot.ok {
  background: var(--status-ok);
}

.status-dot.attention {
  background: var(--status-attention);
}

.status-dot.broken {
  background: var(--status-broken);
}

.conn-row {
  display: flex;
  align-items: center;
  gap: 0.65rem;
}

.conn-meta {
  color: var(--ink-muted);
  font-size: 0.8125rem;
}

.empty-state {
  text-align: center;
  padding: 2.5rem 1.5rem;
  border: 1px dashed rgba(255, 255, 255, 0.12);
  border-radius: var(--radius-xl);
  background: rgba(255, 255, 255, 0.02);
}

.empty-state-title {
  font-size: 1.0625rem;
  font-weight: 600;
  margin-bottom: 0.35rem;
}

.empty-state-desc {
  max-width: 28rem;
  margin: 0 auto 1.25rem;
  color: var(--ink-muted);
  font-size: 0.875rem;
}

.soft-banner {
  padding: 0.75rem 1rem;
  border-radius: var(--radius-md);
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.03);
  margin-bottom: 1rem;
  font-size: 0.875rem;
}

.soft-banner.ok {
  border-color: rgba(0, 178, 110, 0.35);
  color: var(--ngentix-primary-light);
}

.soft-banner.warn {
  border-color: rgba(201, 133, 42, 0.4);
  color: #e6c07b;
}

.soft-banner.err {
  border-color: rgba(229, 72, 77, 0.4);
  color: #f2a4a6;
}

.summary-line {
  margin-bottom: 1rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.code-block {
  margin: 0;
  padding: 0.85rem 1rem;
  border-radius: var(--radius-md);
  background: #0a0c10;
  color: #c9efe0;
  overflow: auto;
  font-family: "Geist Mono", ui-monospace, monospace;
  font-size: 0.75rem;
  line-height: 1.45;
}

.debug-details {
  margin-top: 1rem;
}

.debug-details summary {
  cursor: pointer;
  color: var(--ink-muted);
  font-size: 0.8125rem;
  margin-bottom: 0.5rem;
}

.inline-label {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.75rem;
  color: var(--ink-muted);
}

.inline-label input,
.inline-label select {
  width: auto;
  min-width: 7rem;
}

/* --- API keys (ENH-CC-048 Phase 1) --------------------------------------- */

.btn-small {
  padding: 0.35rem 0.7rem;
  font-size: 0.8125rem;
}

.btn-danger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  margin: 0;
  padding: 0.35rem 0.7rem;
  border-radius: var(--radius-md);
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
  background: rgba(196, 82, 61, 0.12);
  color: #e08874;
  border: 1px solid rgba(196, 82, 61, 0.4);
}

.btn-danger:hover {
  background: rgba(196, 82, 61, 0.2);
}

/* The show-once panel. Deliberately the loudest thing on the page: if the user
   navigates away without copying, the secret is unrecoverable. */
.key-reveal {
  border: 1px solid rgba(0, 178, 110, 0.45);
  background: rgba(0, 178, 110, 0.07);
  border-radius: var(--radius-lg);
  padding: 1rem 1.15rem;
  margin-bottom: 1.25rem;
}

.key-reveal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.35rem;
}

.key-reveal-warn {
  margin: 0 0 0.75rem;
  font-size: 0.875rem;
  color: var(--ngentix-primary-light);
}

.key-reveal-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
}

.key-value {
  flex: 1 1 22rem;
  min-width: 0;
  overflow-wrap: anywhere;
  padding: 0.6rem 0.75rem;
  border-radius: var(--radius-md);
  background: var(--grey-975);
  border: 1px solid rgba(255, 255, 255, 0.12);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.875rem;
  color: var(--ink);
}

.key-quickstart {
  margin-top: 0.85rem;
}

.key-quickstart summary {
  cursor: pointer;
  font-size: 0.875rem;
  color: var(--ink-secondary);
}

.key-quickstart .code-block {
  margin: 0.6rem 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.key-create {
  display: flex;
  align-items: flex-end;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}

.key-create .field {
  margin: 0;
}

.key-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.key-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.75rem 0.9rem;
  border-radius: var(--radius-md);
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.02);
}

.key-row.is-revoked {
  opacity: 0.55;
}

.key-actions {
  display: flex;
  gap: 0.5rem;
  flex-shrink: 0;
}

@media (max-width: 720px) {
  .key-row {
    flex-direction: column;
    align-items: flex-start;
  }
}

@media (max-width: 960px) {
  .stat-cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 720px) {
  .app-sidebar {
    position: fixed;
    z-index: 40;
    height: 100%;
    transform: translateX(-105%);
    transition: transform 0.2s ease;
  }

  .app-shell.sidebar-open .app-sidebar {
    transform: translateX(0);
  }

  .sidebar-mobile-btn {
    display: inline-flex;
  }

  .sidebar-collapse-btn {
    display: none;
  }

  .app-content {
    padding: 1.25rem;
  }

  .stat-cards {
    grid-template-columns: 1fr;
  }

  .user-chip {
    display: none;
  }
}

/* ---------------------------------------------------------------------------
   Provider credentials (FEA-CC-038 Phase 3)

   Sits inside the keys view and reuses .page-header, .key-create, .field,
   .key-row, .conn-meta, .status-dot, and .soft-banner. The only genuinely new
   pieces are the section divider and the redirect-URL callout, which has no
   equivalent elsewhere in the console.
   --------------------------------------------------------------------------- */

/* Sub-tabs within a view. First tab pattern in the console: the keys page holds
   two separate jobs (issue an API key vs register a provider OAuth app) and
   stacking both made the page long enough that the second was below the fold. */
.subtabs {
  display: flex;
  gap: 0.25rem;
  margin: 1.1rem 0 1.4rem;
  border-bottom: 1px solid var(--hairline, #2a2f3a);
}

.subtab {
  appearance: none;
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  color: var(--ink-muted);
  font: inherit;
  font-size: 0.88rem;
  padding: 0.5rem 0.75rem;
  cursor: pointer;
  margin-bottom: -1px;
}

.subtab:hover {
  color: var(--ink-secondary);
}

.subtab.is-active {
  color: var(--ink);
  font-weight: 600;
  border-bottom-color: var(--ngentix-primary);
}

.subtab:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: -2px;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}

.cred-intro {
  margin: 0 0 1.1rem;
}

/* The redirect URL is the value a customer must paste into the provider's
   console before anything works, and it is identical for every connector — so
   it is stated once, prominently, rather than repeated per form. */
.redirect-callout {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  flex-wrap: wrap;
  background: rgba(0, 178, 110, 0.07);
  border: 1px solid rgba(0, 178, 110, 0.3);
  border-radius: var(--radius-md);
  padding: 0.7rem 0.85rem;
  margin-bottom: 0.5rem;
}

.redirect-label {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--ngentix-primary);
  font-weight: 600;
}

.redirect-callout code {
  font-family: "Geist Mono", ui-monospace, monospace;
  font-size: 0.84rem;
  color: var(--ink);
  overflow-x: auto;
  max-width: 100%;
}

.redirect-note {
  margin: 0 0 1rem;
  font-size: 0.8rem;
}

.cred-hint {
  margin: 0.6rem 0 0;
  font-size: 0.8rem;
}

.cred-advanced {
  margin-top: 0.9rem;
}

.cred-advanced > summary {
  cursor: pointer;
  font-size: 0.82rem;
  color: var(--ink-secondary);
}

.cred-advanced[open] > summary {
  margin-bottom: 0.8rem;
}

.cred-advanced-fields {
  display: grid;
  gap: 0.7rem;
  max-width: 34rem;
}

.cred-advanced-fields input {
  width: 100%;
}

#cred-list {
  margin-top: 1rem;
}

/* ---------------------------------------------------------------------------
   Explain dots (ported from modgard-control-plane's ExplainDot, FEA-070)

   A question mark you CLICK, not hover. Hover was rejected there because a
   tooltip anchored near its target always occludes what it explains, and fires
   on transit. Quiet at rest — an affordance, not an instrument.
   --------------------------------------------------------------------------- */

.xd {
  position: relative;
  display: inline-flex;
  align-items: center;
  margin-left: 0.3rem;
  vertical-align: middle;
}

.xd-dot {
  width: 14px;
  height: 14px;
  padding: 0;
  display: grid;
  place-items: center;
  border: 1px solid var(--hairline, #2a2f3a);
  border-radius: 50%;
  background: transparent;
  color: var(--ink-muted);
  font-size: 9px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  transition:
    color 0.15s ease,
    border-color 0.15s ease;
}

.xd-dot:hover,
.xd-dot[aria-expanded="true"] {
  color: var(--ink);
  border-color: var(--ink-muted);
}

.xd-dot:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* Opaque: it covers content by definition, so it must be legible on its own. */
.xd-panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 70;
  width: max-content;
  max-width: 270px;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--hairline, #2a2f3a);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
  color: var(--ink-secondary);
  font-size: 0.78rem;
  font-weight: 400;
  line-height: 1.45;
  letter-spacing: normal;
  text-align: left;
  text-transform: none;
  white-space: normal;
}

/* Pull back from a right edge so a wide panel does not run off the card. */
.xd-panel[data-align="end"] {
  left: auto;
  right: 0;
}

/* ---------------------------------------------------------------------------
   Setup steps disclosure — the ordered "what to do at the provider" list.
   A real <details>, not a dot: it is a procedure, not a definition.
   --------------------------------------------------------------------------- */

.setup-steps {
  margin: 0 0 1.1rem;
  border: 1px solid var(--hairline, #2a2f3a);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.015);
}

.setup-steps > summary {
  cursor: pointer;
  padding: 0.6rem 0.85rem;
  font-size: 0.84rem;
  color: var(--ink-secondary);
  font-weight: 500;
}

.setup-steps > summary:hover {
  color: var(--ink);
}

.setup-steps[open] > summary {
  border-bottom: 1px solid var(--hairline, #2a2f3a);
}

.setup-steps ol {
  margin: 0;
  padding: 0.8rem 0.85rem 0.9rem 2rem;
  display: grid;
  gap: 0.5rem;
  font-size: 0.83rem;
  color: var(--ink-secondary);
}

.setup-steps li::marker {
  color: var(--ngentix-primary);
  font-weight: 600;
}

.setup-steps code {
  font-family: "Geist Mono", ui-monospace, monospace;
  font-size: 0.88em;
  color: var(--ink);
}

.setup-steps a {
  color: var(--ngentix-primary);
}

/* ---------------------------------------------------------------------------
   Sandbox pointer — the fastest path to a first successful call needs no
   provider account at all (FEA-CC-041 shipped three synthetic connectors).
   --------------------------------------------------------------------------- */

.sandbox-note {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  padding: 0.7rem 0.85rem;
  margin-bottom: 1.1rem;
  border: 1px dashed var(--hairline, #2a2f3a);
  border-radius: var(--radius-md);
  font-size: 0.83rem;
  color: var(--ink-secondary);
}

.sandbox-note strong {
  color: var(--ink);
  font-weight: 600;
}

.sandbox-note code {
  font-family: "Geist Mono", ui-monospace, monospace;
  font-size: 0.88em;
  color: var(--ngentix-primary-light);
}

/* ---------------------------------------------------------------------------
   Credential verification state. The dot must mean something: a row existing
   in our database is NOT evidence the credentials work.
   --------------------------------------------------------------------------- */

.status-dot.unverified {
  background: var(--ink-muted);
}

.cred-verify {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

/* ---------------------------------------------------------------------------
   Documentation shell (FEA-CC-067 Phase 1)

   The docs used to carry their own inline palette — a light page (#f7faf9,
   teal #0f766e) linked from this dark console — so clicking "Docs" ejected the
   reader into what looked like another product. It now loads this stylesheet
   and uses these tokens, so the two are one system.
   --------------------------------------------------------------------------- */

.docs-body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: Inter, system-ui, -apple-system, sans-serif;
  font-size: 15px;
  line-height: 1.6;
}

/* ⚠ THIS HEADER IS THE CONSOLE'S HEADER. Do not restyle it in isolation.
   jg, 2026-08-17: *"when I click docs, it takes me out of the experience. that is
   the problem to be solved."* The docs used to carry a 128px wordmark image, the
   title "Connector Cloud docs", and a horizontal text nav — three differences that
   announced a different website at the exact moment the user crossed the seam.

   It now matches `.cc-header` (`apps/console-next/src/index.css`) exactly: 56px
   tall, one bottom hairline, and the same one-line lockup — mark · product name at
   full contrast · a DRAWN 1px rule · descriptor, smaller, uppercase, dimmer. The
   two files must be changed together; the header is a shared contract now, and the
   whole point is that a user cannot tell which one they are looking at.

   The descriptor string comes from the SALES MATERIAL ("hosted layer", the
   one-pager; "integration layer", the website), not from us. Same rule as the
   console's — see the comment on Header.tsx. */
.docs-topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* 56px, matching .cc-header exactly. Not padding-driven: the console sets an
     explicit height, and a header that is 54 or 58px here would read as a jump. */
  height: 56px;
  padding: 0 1rem;
  background: var(--surface);
  border-bottom: 1px solid var(--hairline);
}

/* The brand lockup — the console's `.cc-header__brand`. */
.docs-topbar-home {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  text-decoration: none;
  color: inherit;
}

/* ⚠ 26px, and an INLINE SVG rather than an <img>. The old markup used the 128px
   wordmark, which is the single loudest signal that this is a different site — it
   was roughly 4x the console mark. The inline mark also takes currentColor, so it
   follows the theme; the wordmark file hardcodes its green. */
.docs-topbar-mark {
  height: 26px;
  width: auto;
  flex-shrink: 0;
  color: var(--accent, #02b26e);
}

/* BASELINE, not centre — the product name and the descriptor differ in
   line-height, so box-centring leaves their baselines a couple of px apart. The
   console's header carries the same rule and the same reason. */
.docs-topbar-lockup {
  display: flex;
  align-items: baseline;
  gap: 10px;
  min-width: 0;
}

.docs-topbar-product {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  white-space: nowrap;
}

/* A DRAWN rule, never a "|" glyph — a character sits on the text baseline and
   inherits the neighbouring size and colour. align-self centre because a divider
   centres on the cap height rather than dropping to the baseline. */
.docs-topbar-rule {
  align-self: center;
  width: 1px;
  height: 14px;
  flex-shrink: 0;
  background: var(--hairline);
}

.docs-topbar-descriptor {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
  white-space: nowrap;
}

/* Below the console's own narrow breakpoint the descriptor is the first thing to
   go — the product name is the part that identifies where you are. */
@media (max-width: 560px) {
  .docs-topbar-rule,
  .docs-topbar-descriptor { display: none; }
}

/* The action group, mirroring the console's `.cc-header__actions`.
   The docs' own sections (Docs home, Connectors, Error codes) are NOT here any
   more — they are in the left rail, where the console keeps its navigation. A
   horizontal nav in the header was the second signal that this is a different
   product, and it duplicated the rail directly beneath it. */
.docs-topbar nav {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.86rem;
}

.docs-topbar nav a {
  color: var(--ink-muted);
  text-decoration: none;
}

.docs-topbar nav a:hover {
  color: var(--ink);
}

/* ⚠ "Back to console" is a BUTTON, not a text link, and it is the only action in
   this header. The old markup gave it the same muted styling as three sibling doc
   links, so the one control that returns you to the app looked like a fourth
   section of the docs. If the docs are going to be a place you visit, the way back
   has to be the most obvious thing in the chrome. */
.docs-topbar-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 500;
  border-radius: 6px;
  border: 1px solid var(--hairline);
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}

.docs-topbar-back:hover {
  color: var(--ink);
  border-color: var(--accent, #02b26e);
}

.docs-topbar-back svg {
  width: 13px;
  height: 13px;
  flex-shrink: 0;
}

/* The rail is FLUSH LEFT with a seam, like the console's, rather than a floating
   column inside a centred page. That difference was the third thing announcing a
   different site: the console's rail starts at x=0 and carries a right border, so
   a docs rail that began 100+px in read as a different layout even once the header
   matched. 256px matches `--cc-sidebar-width`'s default exactly.

   The MAIN column keeps its own max-width and centres within the remaining space,
   so prose stays at a readable measure — the console's content is tables and cards
   and wants the full width, but documentation does not. */
.docs-layout {
  display: grid;
  grid-template-columns: 256px minmax(0, 1fr);
  gap: 0;
  align-items: start;
}

/* The rail column: the seam and the surface, matching `.cc-shell__rail`. */
.docs-layout > div:first-child {
  position: sticky;
  top: 56px;
  /* The header is 56px and sticky, so the rail owns the rest of the viewport. */
  height: calc(100dvh - 56px);
  overflow-y: auto;
  overflow-x: hidden;
  padding: 1rem 0.75rem;
  background: var(--surface);
  border-right: 1px solid var(--hairline);
}

/* NOTE: `.docs-main`'s own width and padding are set at its main declaration
   further down (search `.docs-main {`), not here — two rules for one selector in
   one file is how the earlier one silently loses. */

.docs-nav {
  position: sticky;
  top: 4.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  font-size: 0.86rem;
}

.docs-nav-heading {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
  font-weight: 600;
  margin: 1rem 0 0.4rem;
}

.docs-nav-heading:first-child {
  margin-top: 0;
}

.docs-nav a {
  color: var(--ink-secondary);
  text-decoration: none;
  padding: 0.28rem 0.6rem;
  border-left: 2px solid transparent;
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}

.docs-nav a:hover {
  color: var(--ink);
  background: rgba(255, 255, 255, 0.03);
}

.docs-nav a.is-active {
  color: var(--ink);
  border-left-color: var(--ngentix-primary);
  background: rgba(0, 178, 110, 0.07);
  font-weight: 500;
}

/* The prose column. Padding lives here rather than on `.docs-layout` because the
   layout's grid now runs edge to edge — the rail is flush left, so the content's
   breathing room is the content's own. */
.docs-main {
  min-width: 0;
  max-width: 48rem;
  padding: 2rem 2rem 5rem;
}

.docs-main h1 {
  font-size: 1.9rem;
  letter-spacing: -0.02em;
  margin: 0 0 0.4rem;
  text-wrap: balance;
}

.docs-main h2 {
  font-size: 1.25rem;
  letter-spacing: -0.01em;
  margin: 2.75rem 0 0.6rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--hairline);
  scroll-margin-top: 4.5rem;
  text-wrap: balance;
}

.docs-main h3 {
  font-size: 1rem;
  margin: 1.75rem 0 0.5rem;
  scroll-margin-top: 4.5rem;
}

.docs-main p,
.docs-main li {
  /* Prose is deliberately quieter than code. The payload on a docs page is the
     thing you paste, so it gets the brightest ink and prose steps back. */
  color: var(--ink-muted);
  max-width: 68ch;
}

.docs-main strong {
  color: var(--ink-secondary);
}

.docs-main a {
  color: var(--ngentix-primary);
}

/* Code blocks sit ABOVE the page, not below it. The first version used a
   background darker than the canvas (#0a0c10 against #0e1014) which made a
   block read as a hole rather than an object — jg: "very difficult to tell
   which pieces are code that can be copy pasted". Every developer docs site
   worth copying raises the code surface and brightens the code ink. */
.docs-code {
  position: relative;
  margin: 1rem 0 1.5rem;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  overflow: hidden;
}

.docs-code-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.4rem 0.6rem 0.4rem 0.85rem;
  background: rgba(255, 255, 255, 0.025);
  border-bottom: 1px solid var(--hairline);
}

.docs-code-lang {
  font-family: "Geist Mono", ui-monospace, monospace;
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.docs-code-copy {
  margin-left: auto;
  font: inherit;
  font-size: 0.74rem;
  padding: 0.2rem 0.55rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--hairline);
  background: transparent;
  color: var(--ink-secondary);
  cursor: pointer;
}

.docs-code-copy:hover {
  color: var(--ink);
  border-color: var(--ink-muted);
}

.docs-code-copy:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 1px;
}

.docs-main pre {
  margin: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
  /* Brightest ink on the page. This is the thing the reader came for. */
  color: var(--ink);
  padding: 0.9rem 1rem;
  overflow-x: auto;
  font-family: "Geist Mono", ui-monospace, monospace;
  font-size: 0.82rem;
  line-height: 1.6;
}

/* Minimal, hand-rolled highlighting — enough that a block reads as code before
   a single character is parsed. A full highlighter (Prism, Shiki) would mean
   the Node toolchain this repo has deliberately avoided. */
.tok-comment { color: var(--ink-muted); font-style: italic; }
.tok-string  { color: var(--ngentix-primary-light); }
.tok-keyword { color: #7fb2ff; }
.tok-method  { color: #e0a856; font-weight: 600; }
.tok-number  { color: #d2a8ff; }

.docs-main :not(pre) > code {
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  padding: 0.05rem 0.32rem;
  font-family: "Geist Mono", ui-monospace, monospace;
  font-size: 0.85em;
  color: var(--ngentix-primary-light);
}

.docs-lede {
  font-size: 1.02rem;
  color: var(--ink-secondary);
  margin-bottom: 1.75rem;
}

/* Connector reference, rendered from GET /v1/catalog. */
.docs-catalog {
  list-style: none;
  padding: 0;
  margin: 1rem 0 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 0.4rem;
}

.docs-catalog li {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.5rem 0.7rem;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  background: var(--surface);
}

.docs-catalog .c-name {
  font-weight: 600;
  color: var(--ink);
  font-size: 0.88rem;
}

.docs-catalog .c-meta {
  font-family: "Geist Mono", ui-monospace, monospace;
  font-size: 0.72rem;
  color: var(--ink-muted);
}

.docs-catalog-filter {
  margin: 1rem 0 0;
  width: 100%;
  max-width: 22rem;
}

@media (max-width: 860px) {
  .docs-layout {
    grid-template-columns: minmax(0, 1fr);
    gap: 1.25rem;
    padding: 1.25rem 1.25rem 0;
  }
  /* Undo the flush-left sticky rail column: on one column a full-height sticky
     panel would eat the whole screen before the prose started. */
  .docs-layout > div:first-child {
    position: static;
    height: auto;
    overflow: visible;
    padding: 0;
    background: none;
    border-right: 0;
  }
  .docs-main {
    padding: 0 0 4rem;
  }
  .docs-nav {
    position: static;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 0.3rem;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--hairline);
  }
  .docs-nav-heading {
    display: none;
  }
  .docs-nav a {
    border-left: 0;
    border: 1px solid var(--hairline);
    border-radius: var(--radius-sm);
  }
  /* ⚠ The group headings are hidden on this breakpoint, so the four CONSOLE links
     would sit in the chip row looking exactly like doc sections — "Connectors"
     appears in BOTH groups and would be two identical chips going to different
     places. Tint the ones that leave the docs. */
  .docs-nav a[href^="/#"] {
    border-color: var(--accent, #02b26e);
    color: var(--ink);
  }
}

/* ---------------------------------------------------------------------------
   Try it — run a documented request from the docs page (FEA-CC-067)

   Real requests against this deployment, not a simulation. Endpoints that need
   no credential run immediately; the rest use a key the reader pastes, which is
   held in memory for the page session and never persisted.
   --------------------------------------------------------------------------- */

.tryit {
  border-top: 1px solid var(--hairline);
  background: rgba(0, 178, 110, 0.04);
}

.tryit-bar {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  padding: 0.55rem 0.85rem;
}

.tryit-run {
  font: inherit;
  font-size: 0.76rem;
  font-weight: 600;
  padding: 0.28rem 0.7rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--ngentix-primary);
  background: var(--ngentix-primary);
  color: #04120c;
  cursor: pointer;
}

.tryit-run:hover {
  background: #00c77c;
}

.tryit-run:disabled {
  opacity: 0.55;
  cursor: default;
}

.tryit-run:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

.tryit-note {
  font-size: 0.74rem;
  color: var(--ink-muted);
}

.tryit-key {
  font-family: "Geist Mono", ui-monospace, monospace;
  font-size: 0.74rem;
  background: var(--canvas);
  color: var(--ink);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  padding: 0.24rem 0.45rem;
  min-width: 15rem;
  flex: 1;
}

.tryit-key:focus {
  outline: 2px solid var(--focus-ring);
  outline-offset: -1px;
  border-color: var(--ngentix-primary);
}

.tryit-status {
  font-family: "Geist Mono", ui-monospace, monospace;
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.14rem 0.45rem;
  border-radius: 999px;
  white-space: nowrap;
}

.tryit-status.ok {
  background: rgba(42, 155, 106, 0.18);
  color: #6fd3a4;
  border: 1px solid rgba(42, 155, 106, 0.45);
}

.tryit-status.err {
  background: rgba(229, 72, 77, 0.15);
  color: #ff9ea1;
  border: 1px solid rgba(229, 72, 77, 0.45);
}

.tryit-out {
  margin: 0;
  padding: 0.75rem 0.95rem;
  border-top: 1px solid var(--hairline);
  background: var(--canvas);
  color: var(--ink-secondary);
  font-family: "Geist Mono", ui-monospace, monospace;
  font-size: 0.76rem;
  line-height: 1.5;
  max-height: 22rem;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
}

/* Generated documentation pages (error reference, FEA-CC-067 Phase 2). */
.docs-layout-single {
  grid-template-columns: minmax(0, 1fr);
  max-width: 52rem;
}

/* ══ THE PATH STRIP, DOCS EDITION ═══════════════════════════════════════════
   `docs/header/PROMPT-Page-Headers.md` Phase 4 — the docs site adopts the same
   three-slot structure and the same strip as the console.

   ⛔ **THE ARROW IS CHROME AT A FIXED LEFT POSITION, SEPARATED BY A HAIRLINE,
   AND IT TARGETS THE IMMEDIATE PARENT.** Three of these pages read `← Ngentix
   docs` — the arrow fused to a label — while three others carried a proper
   `Docs / Error reference` trail with no arrow at all. `← FLOWS` reads fine at
   one ancestor and `FLOWS / ← ERROR REFERENCE` reads badly at two, so the arrow
   never attaches to a segment: one position, one behaviour, everywhere.

   ⛔ **AND NOTHING IN IT CARRIES THE BRAND HUE.** A back link is the least
   important thing on the page. Links are ink; the focus ring stays brand.

   ⚠ **THE DOCS TITLE KEEPS ITS LARGER SIZE (`.docs-main h1`, 1.9rem) — A
   DELIBERATE EXCEPTION, RECORDED HERE SO NOBODY "FIXES" IT.** Docs is prose at
   reading measure and the console is tables at scanning density; one title size
   across both would be consistency for its own sake. This is the twin of the
   create-route exception in `components/ViewHeader.tsx` — both are written down
   WITH their reason so they cannot spread by imitation. */
.docs-crumb {
  display: flex;
  align-items: center;
  gap: 0;
  margin: 0 0 0.75rem;
  font-size: 0.8rem;
  white-space: nowrap;
  overflow: hidden;
}
.docs-crumb__up {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  padding-right: 12px;
  margin-right: 12px;
  border-right: 1px solid var(--hairline);
  line-height: 1;
  text-decoration: none;
}
.docs-crumb__trail {
  overflow: hidden;
  text-overflow: ellipsis;
}
.docs-crumb a { text-decoration: none; }
.docs-crumb a:hover { text-decoration: underline; }

/* ⛔ **GOING UP ONE LEVEL IS WHAT HAS TO SURVIVE ON A PHONE.** The full ancestry
   is not — the trail collapses and the arrow grows the parent's name. */
@media (max-width: 640px) {
  .docs-crumb__trail { display: none; }
  .docs-crumb__up {
    border-right: 0;
    margin-right: 0;
    padding-right: 0;
  }
  .docs-crumb__up::after {
    content: attr(data-parent);
    margin-left: 10px;
  }
}

.docs-errcode {
  font-family: "Geist Mono", ui-monospace, monospace;
  font-size: 1.35rem;
  color: var(--ngentix-primary-light);
  background: none;
  border: 0;
  padding: 0;
}

.docs-note {
  margin-top: 1.5rem;
  padding: 0.7rem 0.85rem;
  border-left: 2px solid var(--ngentix-primary);
  background: rgba(0, 178, 110, 0.05);
  font-size: 0.85rem;
}

.docs-errors {
  grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr));
}

/* Endpoint facts on a connector page. Narrow label column, monospace values;
   scrolls inside itself rather than widening the page on a phone. */
.docs-table {
  border-collapse: collapse;
  margin: 0.75rem 0 0;
  font-size: 0.85rem;
  /* `display: block` is what makes overflow-x work on a table, but it also
     means width:100% resolves against the content, not the column — so a long
     provider URL widened the page instead of scrolling inside the table.
     max-width is what actually constrains it. */
  display: block;
  max-width: 100%;
  overflow-x: auto;
}

.docs-table th,
.docs-table td {
  text-align: left;
  padding: 0.45rem 0.7rem;
  border-bottom: 1px solid var(--hairline);
  vertical-align: top;
}

.docs-table th {
  color: var(--ink-secondary);
  font-weight: 500;
  white-space: nowrap;
}

.docs-table tr:last-child th,
.docs-table tr:last-child td {
  border-bottom: 0;
}

.docs-errors a {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  text-decoration: none;
}

.docs-errors li {
  padding: 0;
}

.docs-errors li:hover {
  border-color: var(--ngentix-primary);
}

.docs-errors a {
  padding: 0.5rem 0.7rem;
}

/* Envelope detail inside a banner: the hint and the link to the code's page.
   Both only appear when the server actually sent them (FEA-CC-037). */
.banner-hint {
  margin-top: 0.35rem;
  font-size: 0.82rem;
  opacity: 0.85;
}

.banner-link {
  display: inline-block;
  margin-top: 0.4rem;
  font-size: 0.8rem;
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* The wordmark and title are one link back to the docs root. They read as the
   obvious thing to click, so they had better do something — on the generated
   error pages they were inert text, and the way out was not findable. */
.docs-topbar-home {
  display: flex;
  align-items: center;
  gap: 1rem;
  text-decoration: none;
  color: inherit;
}

.docs-topbar-home:hover .docs-topbar-title {
  color: var(--ngentix-primary);
}

.docs-crumb-sep {
  color: var(--ink-muted);
  margin: 0 0.15rem;
}

/* ---------------------------------------------------------------------------
   Documentation search (FEA-CC-067 Phase 4)

   One field over three corpora — page sections, 151 connectors, and 27 error
   codes. Client-side over a small index; the corpus is bounded and shipping a
   search service for it would be absurd.
   --------------------------------------------------------------------------- */

.docs-search {
  position: relative;
  margin-bottom: 1rem;
}

/* The field has to LOOK like a search field. The first version was a hairline
   box on a dark ground with no icon — jg: "I can't see that it's a search box".
   A raised surface, a magnifier, and a visible keyboard hint fix that. */
.docs-search-input {
  width: 100%;
  font-family: inherit;
  font-size: 0.84rem;
  background: var(--surface-raised);
  color: var(--ink);
  border: 1px solid var(--ink-muted);
  border-radius: 999px;
  padding: 0.45rem 2.3rem 0.45rem 2.1rem;
}

.docs-search-input:hover {
  border-color: var(--ink-secondary);
}

.docs-search-input:focus {
  outline: none;
  border-color: var(--ngentix-primary);
  box-shadow: 0 0 0 3px var(--focus-ring);
  background: var(--canvas);
}

.docs-search-input::placeholder {
  color: var(--ink-secondary);
}

/* Magnifier, drawn rather than shipped as an asset — one glyph, two rules. */
.docs-search::before {
  content: "";
  position: absolute;
  left: 0.78rem;
  top: 50%;
  width: 0.62rem;
  height: 0.62rem;
  margin-top: -0.42rem;
  border: 1.6px solid var(--ink-muted);
  border-radius: 50%;
  pointer-events: none;
  z-index: 1;
}

.docs-search::after {
  content: "";
  position: absolute;
  left: 1.32rem;
  top: 50%;
  width: 1.6px;
  height: 0.42rem;
  margin-top: 0.12rem;
  background: var(--ink-muted);
  transform: rotate(-45deg);
  transform-origin: top center;
  pointer-events: none;
  z-index: 1;
}

.docs-search:focus-within::before {
  border-color: var(--ngentix-primary);
}

.docs-search:focus-within::after {
  background: var(--ngentix-primary);
}

/* The "/" affordance, visible rather than hidden in the placeholder — the
   placeholder disappears the moment you type. */
.docs-search-kbd {
  position: absolute;
  right: 0.5rem;
  top: 50%;
  transform: translateY(-50%);
  font-family: "Geist Mono", ui-monospace, monospace;
  font-size: 0.68rem;
  line-height: 1;
  color: var(--ink-muted);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  padding: 0.15rem 0.3rem;
  pointer-events: none;
  background: var(--surface);
}

.docs-search:focus-within .docs-search-kbd {
  opacity: 0;
}

.docs-search-results {
  position: absolute;
  z-index: 60;
  left: 0;
  right: 0;
  top: calc(100% + 4px);
  max-height: 24rem;
  overflow-y: auto;
  background: var(--surface-raised);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.5);
  padding: 0.25rem;
}

.docs-search-results a {
  display: flex;
  flex-direction: column;
  gap: 0.05rem;
  padding: 0.4rem 0.55rem;
  border-radius: var(--radius-sm);
  text-decoration: none;
  color: var(--ink-secondary);
}

.docs-search-results a:hover,
.docs-search-results a.is-cursor {
  background: rgba(0, 178, 110, 0.12);
  color: var(--ink);
}

.docs-search-title {
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--ink);
}

.docs-search-kind {
  font-family: "Geist Mono", ui-monospace, monospace;
  font-size: 0.7rem;
  /* Not uppercased: these carry a summary sentence, and shouting a sentence
     makes it slower to read, not faster. */
  color: var(--ink-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.docs-search-empty {
  padding: 0.6rem 0.55rem;
  font-size: 0.82rem;
  color: var(--ink-muted);
}

/* ── FAQ (FEA-CC-073 Phase 3) ────────────────────────────────────────────────
   Each answer is its own anchored section so support can link ONE answer rather
   than the top of a long page. The left rule marks where an answer begins, which
   a page of h3-plus-prose otherwise leaves ambiguous. */
.docs-faq-item {
  margin: 0 0 1.75rem;
  padding-left: 1rem;
  border-left: 2px solid var(--hairline);
}
/* Arriving from a shared link should show WHICH answer was meant. */
.docs-faq-item:target {
  border-left-color: var(--accent, #02b26e);
}
.docs-faq-item h3 {
  margin: 0 0 0.5rem;
  font-size: 1rem;
}
.docs-faq-item h3 a {
  color: var(--ink);
  text-decoration: none;
}
.docs-faq-item h3 a:hover {
  color: var(--accent, #02b26e);
}
.docs-faq-item p,
.docs-faq-item ul {
  margin: 0 0 0.6rem;
  color: var(--ink-secondary);
}
.docs-faq-item ul {
  padding-left: 1.1rem;
}
.docs-faq-item li {
  margin-bottom: 0.3rem;
}
