/* /manage/app.css — list view ONLY. The editor lives in /carnegie/create?slug=…
   Most surface chrome (header, hero, footer, buttons) is inherited from
   create/app.css. This stylesheet only adds the card grid + a few helpers. */

/* iOS zoom-on-focus prevention — R7 of mobile UX rubric. */
.manage-app input,
.manage-app textarea,
.manage-app select {
  font-size: max(16px, 1rem);
}

/* Loading + empty states */
.manage-status {
  /* Now contains skeleton cards instead of plain "Loading…" text
     (Kenneth 2026-05-23: /manage felt broken with bare loading string). */
  padding: 0;
  background: transparent;
  border: 0;
  text-align: center;
}
.manage-skeleton-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--air-space-4, 16px);
}
@media (min-width: 640px) {
  .manage-skeleton-grid { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 1024px) {
  /* [R9] Unified with .manage-card-grid 1024 breakpoint so the skeleton
     placeholder and the real grid switch to 3-col at the same width. */
  .manage-skeleton-grid { grid-template-columns: 1fr 1fr 1fr; }
}
.manage-skel-card {
  height: 290px;
  min-height: 290px;
  border-radius: 16px;
  background: linear-gradient(
    90deg,
    var(--air-color-surface-soft, #f4f2ec) 0%,
    var(--air-color-surface, #ffffff) 50%,
    var(--air-color-surface-soft, #f4f2ec) 100%
  );
  background-size: 200% 100%;
  animation: manage-skel-shimmer 1.4s ease-in-out infinite;
  border: 1px solid var(--air-color-border, #e7e5dd);
}
@keyframes manage-skel-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
.manage-skeleton-label {
  display: block;
  margin-top: var(--air-space-4, 16px);
  color: var(--air-color-text-tertiary, #9a948a);
  font-size: 13px;
  letter-spacing: 0.02em;
}
@media (prefers-reduced-motion: reduce) {
  .manage-skel-card { animation: none; }
}
.manage-empty {
  padding: 48px 24px;
  background: var(--air-color-surface, #ffffff);
  border: 1px dashed var(--air-color-border, #e7e5dd);
  border-radius: 16px;
  text-align: center;
}
.manage-empty p {
  color: var(--air-color-text-secondary, #6b6b6b);
  margin: 0 0 16px 0;
}

/* Card grid — responsive 1/2/3 columns */
.manage-card-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}
@media (min-width: 640px) {
  .manage-card-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .manage-card-grid { grid-template-columns: repeat(3, 1fr); }
}

/* Card itself */
.manage-card {
  position: relative;
  background: var(--air-color-surface, #ffffff);
  border: 1px solid var(--air-color-border, #e7e5dd);
  border-radius: 16px;
  overflow: hidden;
  transition: transform 0.15s ease, border-color 0.15s ease;
}
.manage-card:hover {
  transform: translateY(-2px);
  border-color: var(--air-color-text-primary, #0b1020);
}
.manage-card-link {
  display: block;
  color: inherit;
  text-decoration: none;
}

/* Hero — 16:9 banner */
.manage-card-hero {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background-color: var(--air-color-canvas, #fafaf7);
  background-size: cover;
  background-position: center top;
  background-repeat: no-repeat;
  border-bottom: 1px solid var(--air-color-border, #e7e5dd);
}
.manage-card-hero-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  color: #ffffff;
}
.manage-card-hero-fallback-label {
  font-family: "Poppins", system-ui, sans-serif;
  font-weight: 600;
  font-size: 18px;
  text-align: center;
  line-height: 1.2;
  letter-spacing: -0.01em;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
  word-break: break-word;
  hyphens: auto;
}

/* Body */
.manage-card-body {
  padding: 14px 18px 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.manage-card-name {
  font-family: "Poppins", system-ui, sans-serif;
  font-weight: 600;
  font-size: 15px;
  color: var(--air-color-text-primary, #0b1020);
  letter-spacing: -0.01em;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.manage-card-owner-badge {
  display: inline-block;
  font-family: "DM Sans", system-ui, sans-serif;
  font-weight: 500;
  font-size: 12px; /* [R10] readability floor */
  padding: 2px 8px;
  border-radius: 9999px;
  background: var(--air-color-canvas, #fafaf7);
  color: var(--air-color-text-secondary, #6b6b6b);
  text-transform: lowercase;
}
.manage-card-slug {
  font-family: "Fira Code", ui-monospace, monospace;
  font-size: 12px;
  color: var(--air-color-text-secondary, #6b6b6b);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* "Created by <email>" row — always rendered on every card. Subtle: small,
   muted, with a hairline divider above so it reads as metadata, not as
   another primary line. Email itself is monospaced (matches slug style)
   and truncates with ellipsis on narrow cards. "(you)" suffix is pill-styled
   so super-admins scanning the grid can spot their own pages. */
.manage-card-creator {
  font-family: "DM Sans", system-ui, sans-serif;
  font-size: 12px; /* [R10] 11→12 readability floor */
  color: var(--air-color-text-secondary, #6b6b6b);
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--air-color-border, #e7e5dd);
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  overflow: hidden;
}
.manage-card-creator-email {
  font-family: "Fira Code", ui-monospace, monospace;
  font-size: 12px;
  color: var(--air-color-text-primary, #0b1020);
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1 1 auto;
  min-width: 0;
}
.manage-card-creator-you {
  flex: 0 0 auto;
  font-family: "DM Sans", system-ui, sans-serif;
  font-size: 12px; /* [R10] 10→12 readability floor */
  font-weight: 500;
  padding: 1px 7px;
  border-radius: 9999px;
  background: var(--air-color-canvas, #fafaf7);
  color: var(--air-color-text-secondary, #6b6b6b);
  text-transform: lowercase;
}
/* "Shared with you" pill — shown on editor-role cards on /carnegie/manage.
   Uses an accent tint (not the neutral canvas of the "you" pill) so editor
   cards are scannable from the owner cards in a mixed grid. Matches the
   AIR token palette; falls back to a soft indigo/slate so it never looks
   broken on themes that haven't loaded yet. */
.manage-card-creator-shared {
  flex: 0 0 auto;
  font-family: "DM Sans", system-ui, sans-serif;
  font-size: 12px;
  font-weight: 500;
  padding: 1px 7px;
  border-radius: 9999px;
  background: var(--air-color-accent-soft, rgba(53, 48, 182, 0.10));
  color: var(--air-color-accent, #3530b6);
  white-space: nowrap;
}
.manage-card-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  font-size: 12px; /* [R10] 11→12 readability floor */
  color: var(--air-color-text-secondary, #6b6b6b);
  margin-top: 6px;
}
.manage-card-meta > span:first-child {
  text-transform: capitalize;
}
.manage-card-time {
  font-family: "Fira Code", ui-monospace, monospace;
  font-size: 11px;
}

/* [P0/R9, R5] Per-card explicit action row — primary "Edit & redeploy" +
   ghost "Open ↗". Sits below .manage-card-body, outside the card-wide
   link so its clicks don't bubble. Matches Carnegie button hierarchy
   (1 primary + 1 ghost per row). 44px buttons via air-btn-sm + min-height. */
.manage-card-actions {
  display: flex;
  gap: 8px;
  padding: 0 18px 16px 18px;
  align-items: stretch;
}
.manage-card-actions .air-btn {
  min-height: 44px;
  flex: 1 1 auto;
  justify-content: center;
  text-decoration: none;
}
.manage-card-action-edit { flex: 2 1 auto; }
.manage-card-action-open { flex: 1 1 auto; }

/* "View ↗" external link in top-right corner of hero.
   [R3] border instead of box-shadow.
   [P0/R5] Primary "Open ↗" affordance now lives in .manage-card-actions row
   below; this corner icon remains as secondary chrome at 28x28. */
.manage-card-view {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.92);
  color: var(--air-color-text-primary, #0b1020);
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 8px;
  text-decoration: none;
  font-size: 13px;
  font-weight: 600;
  transition: background 0.1s, transform 0.1s;
  z-index: 2;
}
.manage-card-view:hover {
  background: #ffffff;
  transform: scale(1.05);
}

/* "× Delete" button — super-admin only. Positioned top-right *next to* the
   view ↗ link, after share + comments slots. Stays subtle until hover;
   flips red on hover so the destructive intent is unmistakable.
   [R9] right:118px consolidated from formerly-duplicate declaration. */
.manage-card-delete {
  position: absolute;
  top: 10px;
  right: 118px; /* 28 (view) + 8 + 28 (comments) + 8 + 28 (share) + 8 + 10 */
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.92);
  color: var(--air-color-text-secondary, #6b6b6b);
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 8px;
  font-size: 18px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  transition: background 0.1s, color 0.1s, transform 0.1s;
  z-index: 2;
  padding: 0;
  font-family: inherit;
}
/* Card-corner action buttons (view ↗, share, delete ×). All three are 28×28
   on desktop, clustered top-right of the hero. On mobile we collapse to a
   single `⋯` overflow that opens a bottom sheet — see overflow rules below
   and the @media (max-width: 480px) block. */
.manage-card-delete:hover,
.manage-card-delete:focus-visible {
  background: var(--air-color-danger, #dc2626);
  color: #ffffff;
  transform: scale(1.05);
  outline: none;
}

/* Share button — sits to the left of comments. Visible to owner +
   super-admin. Subtle until hover; flips to text-primary on hover so it
   reads as a positive (sharing) action vs. the destructive red. */
.manage-card-share {
  position: absolute;
  top: 10px;
  right: 82px; /* 28 (view) + 8 + 28 (comments) + 8 + 10 */
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.92);
  color: var(--air-color-text-secondary, #6b6b6b);
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.1s, color 0.1s, transform 0.1s;
  z-index: 2;
  padding: 0;
}
.manage-card-share:hover,
.manage-card-share:focus-visible {
  background: var(--air-color-text-primary, #0b1020);
  color: #ffffff;
  transform: scale(1.05);
  outline: none;
}

/* Comments button — sits between view ↗ and share. Visible to everyone the
   server might let in (owner/editor/super-admin); the modal enforces the
   real permission check. Same hover treatment as Share. */
.manage-card-comments {
  position: absolute;
  top: 10px;
  right: 46px; /* 28 (view) + 8 + 10 */
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.92);
  color: var(--air-color-text-secondary, #6b6b6b);
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.1s, color 0.1s, transform 0.1s;
  z-index: 2;
  padding: 0;
}
.manage-card-comments:hover,
.manage-card-comments:focus-visible {
  background: var(--air-color-text-primary, #0b1020);
  color: #ffffff;
  transform: scale(1.05);
  outline: none;
}

/* Mobile overflow button — hidden on desktop. Replaces the cluster. */
.manage-card-overflow {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 44px; /* full tap target on mobile */
  height: 44px;
  display: none; /* shown via @media below */
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.92);
  color: var(--air-color-text-primary, #0b1020);
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 8px;
  font-size: 22px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  z-index: 3;
  padding: 0;
}
.manage-card-overflow:hover,
.manage-card-overflow:focus-visible {
  background: #ffffff;
  outline: none;
}

/* Use code-style for hero-lede inline code */
.create-hero-lede code {
  font-family: "Fira Code", ui-monospace, monospace;
  font-size: 12px;
  background: var(--air-color-surface, #ffffff);
  padding: 1px 6px;
  border-radius: 4px;
}

/* ── Delete confirmation modal ─────────────────────────────────────────────
   Flat surface (Carnegie rule 3), one primary action (rule 4), follows token
   system (rule 8). Backdrop dimming uses rgba directly because there's no
   --air-color-overlay token yet — add to air-design-tokens.css if a second
   modal needs one. */
.manage-modal-backdrop {
  position: fixed;
  inset: 0;
  background: var(--air-color-overlay, rgba(11, 16, 32, 0.55));
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 16px;
  /* fade in */
  animation: manage-modal-fade-in 0.15s ease;
}
.manage-modal-backdrop[hidden] {
  display: none;
}
@keyframes manage-modal-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.manage-modal {
  background: var(--air-color-surface, #ffffff);
  border-radius: 16px;
  padding: 28px 24px 20px 24px;
  max-width: 420px;
  width: 100%;
  box-sizing: border-box;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.25);
  animation: manage-modal-slide-in 0.18s ease;
  /* Explicit font-family — modal is appended to document.body via
     document.body.appendChild() and lives OUTSIDE `.air-app`, so it does
     NOT inherit the DM Sans body font set on `.air-app`. Without this,
     buttons/text inside the modal that use `font: inherit` fall through
     to the browser default (Times New Roman on most browsers), causing
     the serif-italic look that creeps in on tabs, .air-help text, etc.
     Kenneth flagged 2026-05-23: "Font style again not consistent". */
  font-family: var(--air-font-body, "DM Sans", system-ui, -apple-system, sans-serif);
  color: var(--air-color-text-primary, #0b1020);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
@keyframes manage-modal-slide-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.manage-modal-title {
  font-family: "Poppins", system-ui, sans-serif;
  font-weight: 700;
  font-size: 22px;
  letter-spacing: -0.018em;
  color: var(--air-color-text-primary, #0b1020);
  margin: 0 0 12px 0;
  line-height: 1.2;
}
.manage-modal-body {
  font-family: "DM Sans", system-ui, sans-serif;
  font-size: 15px;
  line-height: 1.5;
  color: var(--air-color-text-primary, #0b1020);
  margin: 0 0 12px 0;
}
.manage-modal-body strong {
  font-weight: 600;
}
.manage-modal-body-warning {
  color: var(--air-color-text-secondary, #6b6b6b);
  font-size: 13px;
  line-height: 1.45;
}
.manage-modal-body-warning strong {
  color: var(--air-color-danger-hover, #b91c1c);
  font-weight: 600;
}
/* Inline error — no box. Hairline top divider only (Carnegie rule 3: no
   nested cards). */
.manage-modal-error {
  color: var(--air-color-danger-hover, #b91c1c);
  border-top: 1px solid var(--air-color-danger-border, #fecaca);
  padding: 10px 0 0 0;
  font-size: 13px;
  font-family: "DM Sans", system-ui, sans-serif;
  margin: 12px 0 0 0;
}
.manage-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 16px;
}
/* Red primary button override for destructive confirm. Inherits .air-btn-primary
   sizing/shape, just swaps the color. */
.manage-btn-danger {
  background: var(--air-color-danger, #dc2626) !important;
  color: #ffffff !important;
  border-color: var(--air-color-danger, #dc2626) !important;
}
.manage-btn-danger:hover:not(:disabled) {
  background: var(--air-color-danger-hover, #b91c1c) !important;
  border-color: var(--air-color-danger-hover, #b91c1c) !important;
}
.manage-btn-danger:disabled {
  background: var(--air-color-danger-disabled, #fca5a5) !important;
  border-color: var(--air-color-danger-disabled, #fca5a5) !important;
  cursor: not-allowed;
}

/* Mobile tweaks — modal needs to clear bottom-fixed FAB + annotation dock
   (Carnegie rule 2), and we want the buttons stacked on tiny screens. */
@media (max-width: 480px) {
  .manage-modal {
    margin-bottom: var(--bottom-safe-area, 96px);
    /* Tighter padding on mobile — Kenneth 2026-05-24: comments+webhook
       modal was "kissing the top border" because the 28px top + 22px h2
       wrapping to 3 lines ate all the vertical headroom. */
    padding: 18px 18px 16px 18px;
  }
  .manage-modal-actions {
    flex-direction: column-reverse;
  }
  .manage-modal-actions .air-btn {
    width: 100%;
  }
  /* On phones the × button overlaps a thumb's natural grab zone; nudge it
     and the view ↗ icon a touch closer to the edge for tap accuracy. */
  .manage-card-delete {
    right: 44px;
  }
}

/* Compact-title variant for the Comments & Webhook modal. The product
   name can run very long (e.g. "Jio x Moca — Commercial Proposal
   (Version 5)"), wrapping the regular 22px title to 3 lines on phones
   and pushing tabs out of the safe area. Shrink to 17px on mobile and
   line-clamp to 2 lines so even pathological names stay bounded. */
.manage-modal-title-compact {
  margin: 0 0 6px 0;
  font-size: 18px;
  line-height: 1.25;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: break-word;
}
.manage-comments-subtitle {
  margin: 0 0 10px 0;
  font-size: 12.5px;
}
.manage-modal-body-compact {
  margin: 0 0 10px 0;
  font-size: 13.5px;
  line-height: 1.4;
  color: var(--air-color-text-secondary, #6b6b6b);
}
@media (max-width: 480px) {
  .manage-modal-title-compact {
    font-size: 17px;
  }
  /* Tighter tab strip on mobile — default 16px top margin + 14px tab
     vertical padding eats another ~50px we don't need. */
  .manage-comments-tabs {
    margin-top: 10px;
  }
  /* The webhook form fieldset legend + hint chain adds vertical bulk;
     compact them on mobile so the URL row + Subscriptions both fit
     above the fold. */
  .manage-webhook-form {
    gap: 10px;
  }
  .manage-webhook-subs-legend {
    margin-bottom: 2px;
  }
  .manage-webhook-subs-hint {
    margin: 0 0 6px 0;
  }
}

/* ── Share modal (Drive-style) ─────────────────────────────────────────────
   Wider variant of the base modal because we render a list of people with
   per-row role dropdowns; the 420px Delete modal is too cramped. */
.manage-modal-wide {
  max-width: 540px;
}
.manage-modal-subtitle {
  font-family: "DM Sans", system-ui, sans-serif;
  font-size: 13px;
  color: var(--air-color-text-secondary, #6b6b6b);
  margin: -4px 0 16px 0;
  word-break: break-all;
}
/* Inline mono slug — type-only, no chip chrome (Carnegie rule 3: no
   pill-inside-pill). Used in subtitle + delete-modal body + help text. */
.manage-modal-slug {
  font-family: "Fira Code", ui-monospace, monospace;
  color: var(--air-color-text-secondary, #6b6b6b);
  /* Mono fonts have wider em-square than DM Sans at the same nominal size,
     so inline mono inside body text looks oversized. 0.92em compensates
     visually so `*@acme.com` reads at the same height as surrounding DM Sans. */
  font-size: 0.92em;
}

/* Add-person row at top of dialog: email input + role dropdown + Add btn */
.manage-share-add {
  display: flex;
  gap: 8px;
  margin-bottom: 6px;
  align-items: stretch;
}
.manage-share-email-input {
  flex: 1 1 auto;
  min-width: 0;
  height: 40px;
  padding: 0 12px;
  font-size: 16px; /* mobile zoom safety — Carnegie rule 7 */
  font-family: "DM Sans", system-ui, sans-serif;
  border: 1px solid var(--air-color-border, #e7e5dd);
  border-radius: 8px;
  background: var(--air-color-surface, #ffffff);
  color: var(--air-color-text-primary, #0b1020);
}
.manage-share-email-input:focus {
  outline: none;
  border-color: var(--air-color-text-primary, #0b1020);
}
.manage-share-role-select {
  flex: 0 0 auto;
  height: 40px;
  min-height: 44px; /* tap target — Carnegie rule 7 */
  padding: 0 28px 0 12px;
  font-size: 16px; /* mobile zoom safety — Carnegie rule 7 */
  font-family: "DM Sans", system-ui, sans-serif;
  border: 1px solid var(--air-color-border, #e7e5dd);
  border-radius: 8px;
  background: var(--air-color-surface, #ffffff);
  color: var(--air-color-text-primary, #0b1020);
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 7' width='12' height='7'><path fill='none' stroke='%236b6b6b' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' d='M1 1l5 5 5-5'/></svg>");
  background-repeat: no-repeat;
  background-position: right 10px center;
}
.manage-share-add .air-btn-primary {
  flex: 0 0 auto;
  height: 40px;
}
.manage-share-add-help {
  font-family: "DM Sans", system-ui, sans-serif;
  font-size: 12px;
  color: var(--air-color-text-secondary, #6b6b6b);
  line-height: 1.5;
  margin: 0 0 18px 0;
}

/* Section labels ("People with access", "Domain wildcards") */
.manage-share-section-label {
  font-family: "Poppins", system-ui, sans-serif;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--air-color-text-secondary, #6b6b6b);
  margin: 8px 0 8px 0;
}
.manage-share-section-label-wild {
  margin-top: 18px;
}

/* People list — flat rows, hairline divider between rows (Carnegie rule 3:
   no nested cards). Each row: avatar + identity + role control. */
.manage-share-people,
.manage-share-wildcards {
  border-top: 1px solid var(--air-color-border, #e7e5dd);
  max-height: 280px;
  overflow-y: auto;
}
.manage-share-loading {
  padding: 16px 4px;
  font-family: "DM Sans", system-ui, sans-serif;
  font-size: 13px;
  color: var(--air-color-text-secondary, #6b6b6b);
}
.manage-share-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 4px;
  border-bottom: 1px solid var(--air-color-border, #e7e5dd);
}
.manage-share-row:last-child {
  border-bottom: none;
}
.manage-share-avatar {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border-radius: 9999px;
  background: linear-gradient(135deg, #0b1020 0%, #3530b6 100%);
  color: #ffffff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Poppins", system-ui, sans-serif;
  font-weight: 600;
  font-size: 15px;
  text-transform: uppercase;
}
.manage-share-avatar-wild {
  background: linear-gradient(135deg, #6b6b6b 0%, #1a2121 100%);
  font-size: 15px;
}
.manage-share-identity {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.manage-share-email {
  font-family: "DM Sans", system-ui, sans-serif;
  font-size: 15px;
  font-weight: 500;
  color: var(--air-color-text-primary, #0b1020);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.manage-share-you {
  font-family: "DM Sans", system-ui, sans-serif;
  font-size: 12px;
  font-weight: 500;
  color: var(--air-color-text-secondary, #6b6b6b);
  padding: 1px 7px;
  border-radius: 9999px;
  background: var(--air-color-canvas, #fafaf7);
  margin-left: 4px;
}
.manage-share-sub {
  font-family: "DM Sans", system-ui, sans-serif;
  font-size: 12px;
  color: var(--air-color-text-secondary, #6b6b6b);
}
.manage-share-role-existing {
  flex: 0 0 auto;
  min-width: 110px;
}
.manage-share-role-badge {
  flex: 0 0 auto;
  font-family: "DM Sans", system-ui, sans-serif;
  font-size: 12px;
  font-weight: 600;
  color: var(--air-color-text-secondary, #6b6b6b);
  padding: 6px 12px;
}
/* Owner row: no fill, no nested surface. Position + label only — Carnegie
   rules 3 (flat surfaces) + 6 (type as hierarchy, not boxes). Matches Drive
   parity better too. */
.manage-share-row-owner {
  border-bottom: 1px solid var(--air-color-border, #e7e5dd);
}

/* Share modal header: title + autosave status indicator side-by-side. The
   status reads "Saved · just now" / "Saving…" / "Save failed — …" via JS. */
.manage-share-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.manage-share-status {
  font-family: "DM Sans", system-ui, sans-serif;
  font-size: 12px;
  color: var(--air-color-text-secondary, #6b6b6b);
  min-height: 16px; /* keeps layout stable when empty */
}
.manage-share-status-saved   { color: var(--air-status-success, #17b26a); }
.manage-share-status-pending { color: var(--air-color-text-secondary, #6b6b6b); }
.manage-share-status-error   { color: var(--air-color-danger, #dc2626); }
.manage-share-status-idle    { color: transparent; } /* reserved space, no text */

/* Skeleton ghost rows — match real .manage-share-row dimensions. Carnegie
   rule 5: skeleton loaders that mirror real content, never raw "Loading…". */
.manage-share-skel {
  pointer-events: none;
}
.manage-share-skel-avatar {
  background: var(--air-color-canvas, #fafaf7) !important;
  animation: manage-skel-pulse 1.2s ease-in-out infinite;
}
.manage-share-skel-line {
  height: 10px;
  border-radius: 4px;
  background: var(--air-color-canvas, #fafaf7);
  animation: manage-skel-pulse 1.2s ease-in-out infinite;
}
.manage-share-skel-line-wide   { width: 60%; }
.manage-share-skel-line-narrow { width: 35%; margin-top: 6px; }
@keyframes manage-skel-pulse {
  0%, 100% { opacity: 0.7; }
  50%      { opacity: 0.4; }
}

/* Mobile (≤480px): hide the 3-icon cluster, show the single ⋯ overflow.
   Inside the share modal: stack the add-row vertically, simplify the
   per-row layout (the role select now also has min-height 44pt). */
@media (max-width: 480px) {
  /* Card-corner buttons: collapse 3 icons to 1 overflow */
  .manage-card-view,
  .manage-card-share,
  .manage-card-comments,
  .manage-card-delete {
    display: none;
  }
  .manage-card-overflow {
    display: flex;
  }

  /* Share modal mobile layout */
  .manage-share-add {
    flex-direction: column;
  }
  .manage-share-add .manage-share-email-input,
  .manage-share-add .manage-share-role-select,
  .manage-share-add .air-btn,
  .manage-share-add .air-btn-primary {
    width: 100%;
    height: 44px;
  }
  .manage-share-row {
    flex-wrap: wrap;
  }
  .manage-share-avatar {
    width: 32px;
    height: 32px;
    font-size: 14px;
  }
  .manage-share-role-existing,
  .manage-share-role-wild {
    width: 100%;
  }

  /* Modal body needs to clear the bottom-fixed annotation dock + FAB
     (Carnegie rule 2: bottom-fixed overlap unacceptable). */
  .manage-modal {
    margin-bottom: var(--bottom-safe-area, 96px);
    max-height: calc(100vh - var(--bottom-safe-area, 96px) - 32px);
    overflow-y: auto;
  }
}

/* ── Mobile bottom sheet (overflow menu) ─────────────────────────────────
   Opens from the ⋯ on each card. Full-width 44pt rows for tap accuracy.
   Reuses .manage-modal-backdrop for the dim + click-out-to-close behavior. */
.manage-sheet-backdrop {
  align-items: flex-end;
  padding: 0;
}
.manage-sheet {
  width: 100%;
  background: var(--air-color-surface, #ffffff);
  border-top-left-radius: 16px;
  border-top-right-radius: 16px;
  padding: 8px 0 calc(var(--bottom-safe-area, 96px) + 8px) 0;
  animation: manage-sheet-slide-in 0.18s ease;
  /* Same out-of-air-app cascade fix as .manage-modal — sheet is appended
     to document.body, so it needs explicit font + color or buttons inside
     fall back to browser-default serif. */
  font-family: var(--air-font-body, "DM Sans", system-ui, -apple-system, sans-serif);
  color: var(--air-color-text-primary, #0b1020);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
@keyframes manage-sheet-slide-in {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}
.manage-sheet-title {
  font-family: "Poppins", system-ui, sans-serif;
  font-weight: 600;
  font-size: 13px;
  color: var(--air-color-text-secondary, #6b6b6b);
  padding: 12px 20px 8px 20px;
  border-bottom: 1px solid var(--air-color-border, #e7e5dd);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.manage-sheet-row {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  min-height: 52px;
  padding: 0 20px;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--air-color-border, #e7e5dd);
  font-family: "DM Sans", system-ui, sans-serif;
  font-size: 16px;
  color: var(--air-color-text-primary, #0b1020);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.manage-sheet-row:active {
  background: var(--air-color-canvas, #fafaf7);
}
.manage-sheet-row-icon {
  flex: 0 0 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--air-color-text-secondary, #6b6b6b);
}
.manage-sheet-row-danger {
  color: var(--air-color-danger, #dc2626);
}
.manage-sheet-row-danger .manage-sheet-row-icon {
  color: var(--air-color-danger, #dc2626);
}
.manage-sheet-row-cancel {
  justify-content: center;
  border-bottom: none;
  border-top: 8px solid var(--air-color-canvas, #fafaf7);
  font-weight: 600;
  color: var(--air-color-text-primary, #0b1020);
}
/* ── Comments + Webhook modal ──────────────────────────────────────────────
   Owner-facing per-slug log of partner annotations + a webhook subscription
   form. Reuses .manage-modal/.manage-modal-wide/.manage-share-status for
   chrome consistency; only the panel internals are new here. */

.manage-modal-tall {
  max-height: 90vh;
  display: flex;
  flex-direction: column;
}

.manage-comments-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--air-color-border, #e5e5e0);
  margin: 16px 0 0;
}
.manage-comments-tab {
  background: transparent;
  border: none;
  padding: 10px 14px;
  font: inherit;
  font-weight: 600;
  color: var(--air-color-text-secondary, #6b6b6b);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color 0.1s, border-color 0.1s;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.manage-comments-tab:hover {
  color: var(--air-color-text-primary, #0b1020);
}
.manage-comments-tab.is-active {
  color: var(--air-color-text-primary, #0b1020);
  border-bottom-color: var(--air-color-text-primary, #0b1020);
}
.manage-comments-tab-count {
  background: var(--air-color-canvas, #fafaf7);
  color: var(--air-color-text-secondary, #6b6b6b);
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
}
.manage-comments-tab.is-active .manage-comments-tab-count {
  background: var(--air-color-text-primary, #0b1020);
  color: #ffffff;
}

.manage-comments-panel {
  /* `flex: 0 1 auto` (not `1 1 auto`) so each tab's panel sizes to its
     own content instead of stretching to fill any leftover vertical
     space inside `.manage-modal-tall`. Stretching made the Activity-log
     empty state float in a huge dead area when the modal was taller than
     the empty-state content — Kenneth flagged the inconsistency between
     tabs. The modal itself still grows or shrinks naturally per tab.
     `max-height: 60vh` (or 50vh on mobile, see media query below) still
     caps the Activity panel so a long comment list scrolls instead of
     pushing the Done button off-screen. */
  flex: 0 1 auto;
  overflow-y: auto;
  padding: 16px 0;
  min-height: 220px;
  max-height: 60vh;
  min-width: 0;
}

.manage-comments-empty {
  padding: 32px 16px;
  text-align: center;
  color: var(--air-color-text-secondary, #6b6b6b);
}
.manage-comments-empty p { margin: 6px 0; }
.manage-comments-empty-hint {
  font-size: 13px;
  color: var(--air-color-text-secondary, #6b6b6b);
}

.manage-comments-log {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.manage-comment-thread {
  border: 1px solid var(--air-color-border, #e5e5e0);
  border-radius: 10px;
  padding: 12px 14px;
  background: #ffffff;
}
.manage-comment-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;
}
.manage-comment-meta {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  font-size: 12px;
  color: var(--air-color-text-secondary, #6b6b6b);
}
.manage-comment-author {
  font-weight: 600;
  color: var(--air-color-text-primary, #0b1020);
}
.manage-comment-dot { color: #c0c0c0; }
.manage-comment-time { font-variant-numeric: tabular-nums; }
.manage-comment-kind {
  background: var(--air-color-canvas, #fafaf7);
  color: var(--air-color-text-secondary, #6b6b6b);
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.manage-comment-kind-component {
  background: rgba(53, 48, 182, 0.1);
  color: #3530b6;
}
.manage-comment-resolved {
  background: rgba(34, 139, 75, 0.1);
  color: #228b4b;
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
}
/* Sub-page badge (2026-05-29): shows which slide/section/tab the
 * comment was made on (e.g. "slide 12", "#analytics", "/admin").
 * Reviewers need this in the admin Comments log because the modal
 * lists every comment on the slug regardless of sub-page. Hover for
 * the full pagePath (title attribute). */
.manage-comment-page {
  background: rgba(53, 48, 182, 0.06);
  color: var(--air-color-text-secondary, #6b6b6b);
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  font-family: ui-monospace, Menlo, monospace;
  letter-spacing: 0;
  text-transform: none;
  white-space: nowrap;
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: help;
}
.manage-comment-link {
  flex: 0 0 24px;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  color: var(--air-color-text-secondary, #6b6b6b);
  text-decoration: none;
  font-size: 14px;
}
.manage-comment-link:hover {
  background: var(--air-color-canvas, #fafaf7);
  color: var(--air-color-text-primary, #0b1020);
}
.manage-comment-quote {
  margin: 6px 0;
  padding: 6px 10px;
  border-left: 3px solid var(--air-color-border, #e5e5e0);
  color: var(--air-color-text-secondary, #6b6b6b);
  font-style: italic;
  background: var(--air-color-canvas, #fafaf7);
  border-radius: 0 6px 6px 0;
  font-size: 13px;
}
.manage-comment-selector {
  margin: 6px 0;
  font-size: 12px;
  color: var(--air-color-text-secondary, #6b6b6b);
}
.manage-comment-selector code {
  background: var(--air-color-canvas, #fafaf7);
  padding: 1px 6px;
  border-radius: 4px;
}
.manage-comment-body {
  font-size: 14px;
  line-height: 1.5;
  color: var(--air-color-text-primary, #0b1020);
  white-space: pre-wrap;
  word-break: break-word;
}
.manage-comment-replies {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px dashed var(--air-color-border, #e5e5e0);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.manage-comment-reply {
  padding-left: 16px;
  border-left: 2px solid var(--air-color-border, #e5e5e0);
}

/* Webhook tab */
.manage-comments-webhook-body {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}
.manage-webhook-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  border: 1px solid var(--air-color-border, #e5e5e0);
  border-radius: 10px;
  background: #ffffff;
  min-width: 0;
}
/* .air-input is the global token primitive — declared without box-sizing in
   air-design-tokens.css. width:100% + padding:14px 18px + border:1px adds up
   to (container + 38px) and spills past the form's right edge on narrow
   viewports. Local override re-asserts border-box so the input visually
   nests inside its parent. Caught 2026-05-23 on partner.air3.com mobile. */
.manage-webhook-form .air-input,
.manage-webhook-form input[type="url"],
.manage-webhook-form input[type="text"] {
  box-sizing: border-box;
  max-width: 100%;
}
.manage-webhook-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--air-color-text-secondary, #6b6b6b);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.manage-webhook-label-row {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  text-transform: none;
  letter-spacing: 0;
  font-size: 14px;
  color: var(--air-color-text-primary, #0b1020);
  font-weight: 500;
  min-height: 44px;
  padding: 4px 0;
}
.manage-webhook-secret-state {
  font-size: 13px;
  color: var(--air-color-text-secondary, #6b6b6b);
}
.manage-webhook-status {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.manage-webhook-status-ok {
  background: rgba(34, 139, 75, 0.1);
  color: #228b4b;
}
.manage-webhook-status-warn {
  background: #fffbeb;
  color: #92400e;
}
.manage-webhook-status-idle {
  background: var(--air-color-canvas, #fafaf7);
  color: var(--air-color-text-secondary, #6b6b6b);
}
.manage-webhook-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 4px;
}
.manage-webhook-actions-hint {
  font-size: 12px;
  color: var(--air-color-text-secondary, #6b6b6b);
  margin-top: 2px;
  font-style: italic;
}

/* Inline URL+button row — the Add/Update button sits flush with the URL input
   per Kenneth's redesign so the primary action lives next to the field it
   commits, not in a separate action cluster below. */
.manage-webhook-url-row {
  display: flex;
  align-items: stretch;
  gap: 8px;
}
.manage-webhook-url-input {
  flex: 1 1 auto;
  min-width: 0;
}
.manage-webhook-url-save {
  flex: 0 0 auto;
  white-space: nowrap;
}

/* Secret state + Generate/Rotate button on one row. Status text on the left,
   small ghost button on the right. */
.manage-webhook-secret-status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.manage-webhook-secret-status .manage-webhook-secret-state {
  flex: 1 1 auto;
  min-width: 0;
}

/* Bottom actions: Send test event (with 🚨) and Remove webhook (text link)
   on the same level. Test on the left, remove on the right, baseline-aligned. */
.manage-webhook-bottom-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 8px;
}
.manage-webhook-test-emoji {
  margin-right: 4px;
  font-size: 13px;
  vertical-align: -1px;
}

/* Remove webhook — destructive demotion per Carnegie rule #4 (one primary
   action per screen). Update webhook stays filled-black; Rotate secret and
   Send test event are ghost; Remove drops to a text link so the user has
   to look for it. confirm() still gates the actual delete. */
.manage-webhook-remove-link {
  display: inline-block;
  margin-top: 0;
  padding: 4px 0;
  background: none;
  border: none;
  color: var(--air-color-danger, #dc2626);
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: rgba(220, 38, 38, 0.4);
  transition: color 0.12s ease, text-decoration-color 0.12s ease;
}
.manage-webhook-remove-link:hover,
.manage-webhook-remove-link:focus-visible {
  color: var(--air-color-danger-hover, #b91c1c);
  text-decoration-color: var(--air-color-danger-hover, #b91c1c);
  outline: none;
}

/* Discord/Slack auto-format hint — sits between the action row and the
   Payload reference details. Quiet, informational; not a callout box. */
.manage-webhook-flavor-hint {
  margin: 14px 0 0;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--air-color-text-secondary, #6b6b6b);
}
.manage-webhook-flavor-hint strong {
  color: var(--air-color-text-primary, #0b1020);
  font-weight: 600;
}

/* Subscriptions fieldset — checkbox-per-group inside the Webhook tab.
   Carnegie rule #3: no nested cards. We use only a top hairline and a
   small Poppins legend; checkboxes sit on flat surface. */
.manage-webhook-subs {
  border: none;
  border-top: 1px solid var(--air-color-border, #e7e5dd);
  padding: 14px 0 4px;
  margin: 14px 0 0;
}
.manage-webhook-subs:disabled { opacity: 0.55; }
.manage-webhook-subs-legend {
  font-family: "Poppins", system-ui, sans-serif;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--air-color-text-secondary, #6b6b6b);
  padding: 0;
}
.manage-webhook-subs-hint {
  font-size: 12.5px;
  color: var(--air-color-text-secondary, #6b6b6b);
  margin: 4px 0 10px;
}
.manage-webhook-sub-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 0;
  cursor: pointer;
  min-height: 44px;
  border-top: 1px solid var(--air-color-border-subtle, #f0eee8);
}
.manage-webhook-sub-row:first-of-type { border-top: none; }
.manage-webhook-sub-cbx {
  width: 18px;
  height: 18px;
  margin-top: 2px;
  flex: 0 0 auto;
  accent-color: var(--air-color-text-primary, #0b1020);
}
.manage-webhook-sub-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.manage-webhook-sub-label {
  font-weight: 600;
  font-size: 14px;
  color: var(--air-color-text-primary, #0b1020);
  line-height: 1.3;
}
.manage-webhook-sub-hint {
  font-size: 12.5px;
  color: var(--air-color-text-secondary, #6b6b6b);
  line-height: 1.45;
}
.manage-webhook-secret-reveal {
  padding: 12px 14px;
  border: 1px solid #fbbf24;
  background: #fffbeb;
  border-radius: 10px;
}
.manage-webhook-secret-label {
  font-size: 12px;
  font-weight: 600;
  color: #92400e;
  margin-bottom: 6px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.manage-webhook-secret-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.manage-webhook-secret-code {
  flex: 1 1 auto;
  background: #ffffff;
  padding: 6px 10px;
  border-radius: 6px;
  border: 1px solid #fcd34d;
  font-family: 'Fira Code', ui-monospace, SFMono-Regular, monospace;
  font-size: 12px;
  word-break: break-all;
}

/* Reuse-from-another-page banner. Shown on the empty state when the user
   has a webhook saved on a different slug. Visually distinct from the
   secret-reveal (amber) — uses a calmer "info" blue so it doesn't read as
   a warning, and a slim left border to keep it low-key. */
.manage-webhook-reuse {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 12px 10px 14px;
  border: 1px solid #bfdbfe;
  border-left: 3px solid #2563eb;
  background: #eff6ff;
  border-radius: 10px;
  flex-wrap: wrap;
}
.manage-webhook-reuse-body {
  min-width: 0;
  flex: 1 1 220px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.manage-webhook-reuse-title {
  font-size: 13px;
  font-weight: 600;
  color: #1e3a8a;
}
.manage-webhook-reuse-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  font-size: 12px;
  color: #475569;
  min-width: 0;
}
.manage-webhook-reuse-url {
  font-family: 'Fira Code', ui-monospace, SFMono-Regular, monospace;
  font-size: 11.5px;
  color: #1e293b;
  background: #ffffff;
  border: 1px solid #cbd5e1;
  padding: 2px 6px;
  border-radius: 5px;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.manage-webhook-reuse-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
@media (max-width: 520px) {
  .manage-webhook-reuse-actions {
    width: 100%;
    justify-content: flex-end;
  }
}
.manage-webhook-help {
  border: 1px solid var(--air-color-border, #e5e5e0);
  border-radius: 10px;
  padding: 10px 14px;
  background: var(--air-color-canvas, #fafaf7);
  min-width: 0;
}
.manage-webhook-help summary {
  cursor: pointer;
  font-weight: 600;
  font-size: 13px;
  color: var(--air-color-text-primary, #0b1020);
}
.manage-webhook-payload {
  margin: 10px 0 6px;
  padding: 10px;
  background: #ffffff;
  border: 1px solid var(--air-color-border, #e5e5e0);
  border-radius: 6px;
  font-family: 'Fira Code', ui-monospace, SFMono-Regular, monospace;
  font-size: 11.5px;
  line-height: 1.5;
  overflow-x: auto;
  max-width: 100%;
  min-width: 0;
  white-space: pre;
  color: var(--air-color-text-primary, #0b1020);
}
.manage-webhook-help-note {
  font-size: 12px;
  color: var(--air-color-text-secondary, #6b6b6b);
  margin: 0;
}

@media (max-width: 480px) {
  .manage-comments-panel { max-height: 50vh; }
  .manage-modal {
    padding: 20px 16px 16px;
    max-width: calc(100vw - 24px);
  }
  .manage-webhook-actions {
    flex-direction: column;
  }
  .manage-webhook-actions .air-btn {
    width: 100%;
    flex: none;
  }
  /* On 412px-class viewports the URL field eats most of the row; stack the
     Add/Update button beneath at full width so it doesn't pin to ~50px. */
  .manage-webhook-url-row {
    flex-direction: column;
    align-items: stretch;
  }
  .manage-webhook-url-save {
    width: 100%;
  }
  /* Keep test event + remove link on the same row (they fit), but if either
     wraps the flex-wrap handles it. */
  .manage-webhook-bottom-actions .air-btn {
    flex: 0 1 auto;
  }
  .manage-comment-thread { padding: 10px 12px; }
}

/* AIR Kit chrome (WhatsApp FAB + annotations dock) needs bottom clearance. */
.manage-app, body.manage-page {
  padding-bottom: max(var(--bottom-safe-area, 96px), env(safe-area-inset-bottom, 0px));
}

/* BD Researcher seed toggle (`.manage-card-bd-*`) removed from /manage —
   the control lives only on /carnegie/create. */
