/* -----------------------------------------------------------------------------
   form-builder.css - Form Builder admin console (Bootstrap 5.3 theme layer)

   Loaded AFTER bootstrap.min.css. Everything is scoped under body[data-fb-page]
   so nothing can leak to the other admin pages (they keep their own stylesheet).
   No Sass, no build step: Bootstrap's own CSS variables are overridden, plus
   the few components that hardcode a colour instead of reading a variable.

   Conventions
   - JS binds to data-fb-* attributes only, never to class names or DOM order.
   - Visibility is driven by state attributes, not by JS toggling classes:
       body[data-fb-auth]   checking | signed-out | denied | ok
       [data-fb-list]       loading | ready | empty | no-match
     An element carrying data-fb-show-auth / data-fb-show-list="a b" is shown
     only in those states. To preview a state, edit the attribute in Pinegrow.
   - The editor page adds machines on #fb-app: data-fb-editor, -fields, -publish,
     -poll, -webhook, -responses (plus -preview on .fb-preview and -drawer on the
     offcanvas), each opted into with data-fb-show-<machine> (see section 12).
   - Health colour lives on data-fb-health (checking | up | recovering | down
     | unknown); status colour lives on .fb-pill-* or, in the editor, on
     data-fb-status (section 12), so JS never needs a class name.

   Accessibility (WCAG 2.1 AA, measured with a contrast script, not eyeballed)
   - #1e6eff is 4.44:1 on white: fine for borders, focus and tints (3:1 needed)
     but NOT for text or as a fill behind white text. Text and button fills use
     #1559d6 (6.12:1).
   - --fb-text-faint (3.11:1) is decorative / non-text only. Meta text and
     placeholders use --fb-text-muted (5.85:1).
   - --fb-input-border exists because control boundaries need 3:1;
     --fb-border-strong (1.52:1) is for dividers and button outlines only,
     where the label, not the outline, identifies the control.
   - Pill and tint backgrounds are opaque, so contrast cannot shift on hover.
----------------------------------------------------------------------------- */

/* =============================================================================
   1. Tokens + Bootstrap variable overrides
   ========================================================================== */
body[data-fb-page] {
  /* surfaces + lines */
  --fb-bg: #f6f7f9;
  --fb-surface: #ffffff;
  --fb-surface-sunken: #f1f3f5;
  --fb-border: #e2e5e9;
  --fb-border-strong: #cdd2d9;
  --fb-input-border: #7d8794;

  /* text */
  --fb-text: #11161d;
  --fb-text-muted: #5b6672;
  --fb-text-faint: #8a93a0;

  /* brand accent + roles (tints are the plan's 8% alpha, flattened on white) */
  --fb-primary: #1e6eff;
  --fb-primary-strong: #1559d6;
  --fb-primary-hover: #1149b0;
  --fb-primary-active: #0e3d94;
  --fb-primary-tint: #edf3ff;
  --fb-primary-border: #b0ccff;
  --fb-success: #167a4a;
  --fb-success-tint: #ecf4f1;
  --fb-success-border: #add0c0;
  --fb-warning: #a2650a;
  --fb-warning-text: #96590a;
  --fb-warning-tint: #f8f3eb;
  --fb-warning-border: #dec9a9;
  --fb-danger: #c0392f;
  --fb-danger-tint: #faefee;
  --fb-danger-border: #e9bab6;

  --fb-ring: 0 0 0 3px rgba(30, 110, 255, 0.28);
  --fb-shadow-float: 0 8px 24px rgba(17, 22, 29, 0.12), 0 2px 6px rgba(17, 22, 29, 0.08);

  /* type: 11 / 12 / 13 / 14 / 16 / 18 / 20 px, weights 400 / 500 / 600 only */
  --fb-font: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --fb-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  --fb-fs-caption: 0.6875rem;
  --fb-fs-meta: 0.75rem;
  --fb-fs-label: 0.8125rem;
  --fb-fs-base: 0.875rem;
  --fb-fs-panel: 1rem;
  --fb-fs-form: 1.125rem;
  --fb-fs-page: 1.25rem;

  /* spacing 4 / 8 / 12 / 16 / 24 / 32, radii 6 / 8 / pill, density */
  --fb-sp-1: 4px;
  --fb-sp-2: 8px;
  --fb-sp-3: 12px;
  --fb-sp-4: 16px;
  --fb-sp-5: 24px;
  --fb-sp-6: 32px;
  --fb-radius-control: 6px;
  --fb-radius-panel: 8px;
  --fb-radius-pill: 999px;
  --fb-control-h: 2.25rem;
  --fb-control-h-sm: 1.875rem;
  --fb-row-h: 2.5rem;

  /* Bootstrap: base */
  --bs-body-font-family: var(--fb-font);
  --bs-body-font-size: var(--fb-fs-base);
  --bs-body-font-weight: 400;
  --bs-body-line-height: 1.5;
  --bs-body-color: var(--fb-text);
  --bs-body-color-rgb: 17, 22, 29;
  --bs-body-bg: var(--fb-bg);
  --bs-body-bg-rgb: 246, 247, 249;
  --bs-emphasis-color: var(--fb-text);
  --bs-emphasis-color-rgb: 17, 22, 29;
  --bs-heading-color: var(--fb-text);
  --bs-secondary-color: var(--fb-text-muted);
  --bs-secondary-color-rgb: 91, 102, 114;
  --bs-tertiary-color: var(--fb-text-muted);
  --bs-tertiary-color-rgb: 91, 102, 114;
  --bs-secondary-bg: var(--fb-surface-sunken);
  --bs-secondary-bg-rgb: 241, 243, 245;
  --bs-tertiary-bg: var(--fb-surface-sunken);
  --bs-tertiary-bg-rgb: 241, 243, 245;
  --bs-border-color: var(--fb-border);
  --bs-border-color-translucent: var(--fb-border);
  --bs-border-radius: var(--fb-radius-control);
  --bs-border-radius-sm: 4px;
  --bs-border-radius-lg: var(--fb-radius-panel);
  --bs-border-radius-xl: var(--fb-radius-panel);
  --bs-border-radius-xxl: var(--fb-radius-panel);
  --bs-border-radius-pill: var(--fb-radius-pill);
  --bs-box-shadow: none;
  --bs-box-shadow-sm: none;
  --bs-box-shadow-lg: var(--fb-shadow-float);
  --bs-code-color: var(--fb-text);
  --bs-focus-ring-color: rgba(30, 110, 255, 0.28);
  --bs-link-color: var(--fb-primary-strong);
  --bs-link-color-rgb: 21, 89, 214;
  --bs-link-hover-color: var(--fb-primary-hover);
  --bs-link-hover-color-rgb: 17, 73, 176;

  /* Bootstrap: roles (text-emphasis values chosen for >= 6:1 on their subtle bg) */
  --bs-primary: var(--fb-primary-strong);
  --bs-primary-rgb: 21, 89, 214;
  --bs-primary-text-emphasis: var(--fb-primary-hover);
  --bs-primary-bg-subtle: var(--fb-primary-tint);
  --bs-primary-border-subtle: var(--fb-primary-border);
  --bs-success: var(--fb-success);
  --bs-success-rgb: 22, 122, 74;
  --bs-success-text-emphasis: #0f5f3a;
  --bs-success-bg-subtle: var(--fb-success-tint);
  --bs-success-border-subtle: var(--fb-success-border);
  --bs-warning: var(--fb-warning);
  --bs-warning-rgb: 162, 101, 10;
  --bs-warning-text-emphasis: #7a4c06;
  --bs-warning-bg-subtle: var(--fb-warning-tint);
  --bs-warning-border-subtle: var(--fb-warning-border);
  --bs-danger: var(--fb-danger);
  --bs-danger-rgb: 192, 57, 47;
  --bs-danger-text-emphasis: #9b2c23;
  --bs-danger-bg-subtle: var(--fb-danger-tint);
  --bs-danger-border-subtle: var(--fb-danger-border);

  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* =============================================================================
   2. Base: type, links, focus, motion
   ========================================================================== */
body[data-fb-page] h1,
body[data-fb-page] h2,
body[data-fb-page] h3 {
  font-weight: 600;
  letter-spacing: -0.005em;
}

body[data-fb-page] code {
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--fb-surface-sunken);
  font-family: var(--fb-mono);
  font-size: 0.92em;
}

body[data-fb-page] :focus-visible {
  outline: 2px solid var(--fb-primary);
  outline-offset: 2px;
}

body[data-fb-page] .form-control:focus-visible,
body[data-fb-page] .form-select:focus-visible,
body[data-fb-page] .form-check-input:focus-visible {
  outline: 0;
}

.fb-skip {
  position: absolute;
  left: 8px;
  top: 8px;
  z-index: 2000;
  padding: 8px 12px;
  border: 1px solid var(--fb-border-strong);
  border-radius: var(--fb-radius-control);
  background: var(--fb-surface);
  color: var(--fb-text);
  font-weight: 500;
  text-decoration: none;
}

@media (prefers-reduced-motion: reduce) {
  body[data-fb-page] *,
  body[data-fb-page] *::before,
  body[data-fb-page] *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* =============================================================================
   3. State machines (see header). Hide everything not listed for the state.
   ========================================================================== */
body[data-fb-auth="checking"] [data-fb-show-auth]:not([data-fb-show-auth~="checking"]),
body[data-fb-auth="signed-out"] [data-fb-show-auth]:not([data-fb-show-auth~="signed-out"]),
body[data-fb-auth="denied"] [data-fb-show-auth]:not([data-fb-show-auth~="denied"]),
body[data-fb-auth="ok"] [data-fb-show-auth]:not([data-fb-show-auth~="ok"]),
[data-fb-list="loading"] [data-fb-show-list]:not([data-fb-show-list~="loading"]),
[data-fb-list="ready"] [data-fb-show-list]:not([data-fb-show-list~="ready"]),
[data-fb-list="empty"] [data-fb-show-list]:not([data-fb-show-list~="empty"]),
[data-fb-list="no-match"] [data-fb-show-list]:not([data-fb-show-list~="no-match"]) {
  display: none !important;
}

/* =============================================================================
   4. Shell: top bar, navigation, page frame
   ========================================================================== */
.fb-container {
  width: 100%;
  max-width: 1440px;
  margin-inline: auto;
  padding-inline: var(--fb-sp-4);
}

.fb-topbar {
  background: var(--fb-surface);
  border-bottom: 1px solid var(--fb-border);
}

body[data-fb-page] .fb-navbar {
  --bs-navbar-padding-y: 0;
  --bs-navbar-padding-x: 0;
  --bs-navbar-toggler-focus-width: 0;
  min-height: 3.25rem;
}

body[data-fb-page] .fb-navbar .navbar-brand {
  display: inline-flex;
  align-items: center;
  gap: var(--fb-sp-2);
  margin-right: var(--fb-sp-5);
  padding: 0;
  color: var(--fb-text);
  font-size: var(--fb-fs-panel);
  font-weight: 600;
  text-decoration: none;
}

.fb-brand-mark {
  display: inline-grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: var(--fb-radius-control);
  background: var(--fb-primary-strong);
  color: #fff;
  font-size: var(--fb-fs-meta);
  font-weight: 600;
  letter-spacing: 0.02em;
}

body[data-fb-page] .fb-navbar .navbar-nav {
  --bs-nav-link-padding-x: 10px;
  --bs-nav-link-padding-y: 6px;
  gap: 2px;
}

body[data-fb-page] .fb-navbar .nav-link {
  border-radius: var(--fb-radius-control);
  color: var(--fb-text-muted);
  font-size: var(--fb-fs-base);
  font-weight: 500;
}

body[data-fb-page] .fb-navbar .nav-link:hover {
  background: var(--fb-surface-sunken);
  color: var(--fb-text);
}

body[data-fb-page] .fb-navbar .nav-link[aria-current="page"] {
  background: var(--fb-primary-tint);
  color: var(--fb-primary-strong);
}

body[data-fb-page] .fb-navbar .navbar-toggler {
  padding: 6px 10px;
  border-color: var(--fb-border-strong);
  border-radius: var(--fb-radius-control);
}

.fb-user {
  display: flex;
  align-items: center;
  gap: var(--fb-sp-3);
  font-size: var(--fb-fs-label);
}

.fb-user-id {
  display: flex;
  flex-direction: column;
  line-height: 1.25;
  text-align: right;
}

.fb-user-name {
  font-weight: 500;
}

.fb-user-role {
  color: var(--fb-text-muted);
  font-size: var(--fb-fs-meta);
}

.fb-main {
  padding-block: var(--fb-sp-5) 3rem;
}

.fb-page-header {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--fb-sp-4);
  margin-bottom: var(--fb-sp-4);
}

.fb-page-title {
  margin: 0;
  font-size: var(--fb-fs-page);
  line-height: 1.3;
}

.fb-page-sub {
  margin: 2px 0 0;
  color: var(--fb-text-muted);
  font-size: var(--fb-fs-label);
}

/* =============================================================================
   5. Health strip
   ========================================================================== */
.fb-health {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px var(--fb-sp-2);
  margin-bottom: var(--fb-sp-4);
  padding: var(--fb-sp-2) var(--fb-sp-3);
  border: 1px solid var(--fb-border);
  border-radius: var(--fb-radius-panel);
  background: var(--fb-surface);
  font-size: var(--fb-fs-label);
}

.fb-health-dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--fb-text-faint);
}

.fb-health-label {
  font-weight: 500;
}

.fb-health-detail {
  color: var(--fb-text-muted);
}

.fb-health[data-fb-health="up"] .fb-health-dot { background: var(--fb-success); }
.fb-health[data-fb-health="recovering"] { border-color: var(--fb-warning-border); background: var(--fb-warning-tint); }
.fb-health[data-fb-health="recovering"] .fb-health-dot { background: var(--fb-warning); }
.fb-health[data-fb-health="down"] { border-color: var(--fb-danger-border); background: var(--fb-danger-tint); }
.fb-health[data-fb-health="down"] .fb-health-dot { background: var(--fb-danger); }

/* =============================================================================
   6. Buttons
   ========================================================================== */
body[data-fb-page] .btn {
  --bs-btn-padding-x: 12px;
  --bs-btn-padding-y: 0;
  --bs-btn-font-size: var(--fb-fs-base);
  --bs-btn-font-weight: 500;
  --bs-btn-line-height: 1.25;
  --bs-btn-border-radius: var(--fb-radius-control);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: var(--fb-control-h);
  text-decoration: none;
}

body[data-fb-page] .btn-sm {
  --bs-btn-padding-x: 10px;
  --bs-btn-font-size: var(--fb-fs-label);
  min-height: var(--fb-control-h-sm);
}

body[data-fb-page] .btn:focus-visible {
  box-shadow: none;
}

body[data-fb-page] .btn-primary {
  --bs-btn-color: #fff;
  --bs-btn-bg: var(--fb-primary-strong);
  --bs-btn-border-color: var(--fb-primary-strong);
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: var(--fb-primary-hover);
  --bs-btn-hover-border-color: var(--fb-primary-hover);
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: var(--fb-primary-active);
  --bs-btn-active-border-color: var(--fb-primary-active);
  --bs-btn-active-shadow: none;
  --bs-btn-disabled-color: #fff;
  --bs-btn-disabled-bg: var(--fb-primary-strong);
  --bs-btn-disabled-border-color: var(--fb-primary-strong);
}

body[data-fb-page] .btn-outline-secondary {
  --bs-btn-color: var(--fb-text);
  --bs-btn-bg: var(--fb-surface);
  --bs-btn-border-color: var(--fb-border-strong);
  --bs-btn-hover-color: var(--fb-text);
  --bs-btn-hover-bg: var(--fb-surface-sunken);
  --bs-btn-hover-border-color: var(--fb-border-strong);
  --bs-btn-active-color: var(--fb-text);
  --bs-btn-active-bg: var(--fb-border);
  --bs-btn-active-border-color: var(--fb-border-strong);
  --bs-btn-active-shadow: none;
  --bs-btn-disabled-color: var(--fb-text-muted);
  --bs-btn-disabled-border-color: var(--fb-border);
}

body[data-fb-page] .btn-link {
  --bs-btn-color: var(--fb-primary-strong);
  --bs-btn-hover-color: var(--fb-primary-hover);
  --bs-btn-active-color: var(--fb-primary-active);
  --bs-btn-padding-x: 4px;
  text-decoration: underline;
}

body[data-fb-page] .btn-close:focus {
  box-shadow: var(--fb-ring);
}

/* =============================================================================
   7. Inputs
   ========================================================================== */
body[data-fb-page] .form-label {
  margin-bottom: 4px;
  color: var(--fb-text);
  font-size: var(--fb-fs-label);
  font-weight: 500;
}

body[data-fb-page] .form-control,
body[data-fb-page] .form-select {
  min-height: var(--fb-control-h);
  padding: 0 10px;
  border: 1px solid var(--fb-input-border);
  border-radius: var(--fb-radius-control);
  background-color: var(--fb-surface);
  color: var(--fb-text);
  font-size: var(--fb-fs-base);
  line-height: 1.5;
}

body[data-fb-page] .form-select {
  padding-right: 2rem;
}

body[data-fb-page] textarea.form-control {
  min-height: 5rem;
  padding-block: 8px;
}

body[data-fb-page] .form-control::placeholder {
  color: var(--fb-text-muted);
  opacity: 1;
}

body[data-fb-page] .form-control:focus,
body[data-fb-page] .form-select:focus {
  border-color: var(--fb-primary);
  box-shadow: var(--fb-ring);
}

body[data-fb-page] .form-control.is-invalid,
body[data-fb-page] .form-select.is-invalid {
  border-color: var(--fb-danger);
  background-image: none;
  padding-right: 10px;
}

body[data-fb-page] .form-control.is-invalid:focus {
  box-shadow: 0 0 0 3px rgba(192, 57, 47, 0.24);
}

body[data-fb-page] .form-text {
  margin-top: 4px;
  color: var(--fb-text-muted);
  font-size: var(--fb-fs-meta);
}

body[data-fb-page] .invalid-feedback {
  margin-top: 4px;
  color: var(--fb-danger);
  font-size: var(--fb-fs-meta);
}

body[data-fb-page] .form-check-input {
  border: 1px solid var(--fb-input-border);
}

body[data-fb-page] .form-check-input:checked {
  border-color: var(--fb-primary-strong);
  background-color: var(--fb-primary-strong);
}

body[data-fb-page] .form-check-input:focus {
  border-color: var(--fb-primary);
  box-shadow: var(--fb-ring);
}

.fb-search {
  position: relative;
}

.fb-search-icon {
  position: absolute;
  top: 50%;
  left: 12px;
  transform: translateY(-50%);
  color: var(--fb-text-muted);
  pointer-events: none;
}

body[data-fb-page] .fb-search .form-control {
  padding-left: 34px;
}

/* =============================================================================
   8. Card, toolbar, table, pills
   ========================================================================== */
.fb-card {
  overflow: hidden;
  border: 1px solid var(--fb-border);
  border-radius: var(--fb-radius-panel);
  background: var(--fb-surface);
}

.fb-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--fb-sp-2);
  padding: var(--fb-sp-3) var(--fb-sp-4);
  border-bottom: 1px solid var(--fb-border);
}

.fb-toolbar .fb-search {
  flex: 1 1 15rem;
  max-width: 22.5rem;
}

.fb-toolbar .fb-filter {
  flex: 0 0 10rem;
}

body[data-fb-page] .fb-table {
  --bs-table-color: var(--fb-text);
  --bs-table-bg: transparent;
  --bs-table-border-color: var(--fb-border);
  --bs-table-hover-bg: var(--fb-bg);
  --bs-table-hover-color: var(--fb-text);
  margin: 0;
}

body[data-fb-page] .fb-table > :not(caption) > * > * {
  padding: var(--fb-sp-2) var(--fb-sp-4);
  vertical-align: middle;
}

body[data-fb-page] .fb-table thead th {
  background: var(--fb-surface-sunken);
  color: var(--fb-text-muted);
  font-size: var(--fb-fs-meta);
  font-weight: 600;
  white-space: nowrap;
}

body[data-fb-page] .fb-table tbody td {
  height: var(--fb-row-h);
}

body[data-fb-page] .fb-table tbody tr:last-child > * {
  border-bottom-width: 0;
}

.fb-num {
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.fb-form-link {
  color: var(--fb-text);
  font-weight: 500;
  text-decoration: none;
}

.fb-form-link:hover {
  color: var(--fb-primary-strong);
  text-decoration: underline;
}

.fb-subcopy {
  color: var(--fb-text-muted);
  font-family: var(--fb-mono);
  font-size: var(--fb-fs-meta);
}

.fb-url {
  display: inline-block;
  max-width: 20rem;
  overflow: hidden;
  font-size: var(--fb-fs-meta);
  text-overflow: ellipsis;
  vertical-align: bottom;
  white-space: nowrap;
}

.fb-muted {
  color: var(--fb-text-muted);
}

body[data-fb-page] .fb-pill {
  --fb-pill-bg: var(--fb-surface-sunken);
  --fb-pill-fg: var(--fb-text-muted);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 8px;
  border-radius: var(--fb-radius-pill);
  background: var(--fb-pill-bg);
  color: var(--fb-pill-fg);
  font-size: var(--fb-fs-meta);
  font-weight: 500;
  line-height: 1.5;
  white-space: nowrap;
}

.fb-pill::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

body[data-fb-page] .fb-pill-success { --fb-pill-bg: var(--fb-success-tint); --fb-pill-fg: var(--fb-success); }
body[data-fb-page] .fb-pill-warning { --fb-pill-bg: var(--fb-warning-tint); --fb-pill-fg: var(--fb-warning-text); }
body[data-fb-page] .fb-pill-danger  { --fb-pill-bg: var(--fb-danger-tint);  --fb-pill-fg: var(--fb-danger); }
body[data-fb-page] .fb-pill-primary { --fb-pill-bg: var(--fb-primary-tint); --fb-pill-fg: var(--fb-primary-strong); }

/* =============================================================================
   9. Empty and no-match states, skeleton
   ========================================================================== */
.fb-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--fb-sp-2);
  padding: 3rem var(--fb-sp-4);
  text-align: center;
}

.fb-empty-icon {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--fb-radius-panel);
  background: var(--fb-primary-tint);
  color: var(--fb-primary-strong);
  font-size: var(--fb-fs-form);
}

.fb-empty h2 {
  margin: var(--fb-sp-1) 0 0;
  font-size: var(--fb-fs-panel);
}

.fb-empty p {
  max-width: 42ch;
  margin: 0 0 var(--fb-sp-2);
  color: var(--fb-text-muted);
}

body[data-fb-page] .placeholder {
  min-height: 0.875rem;
  border-radius: 4px;
  background-color: var(--fb-border);
  opacity: 1;
}

body[data-fb-page] .placeholder-xs {
  min-height: 0.625rem;
}

/* Fixed skeleton widths: a percentage of a shrink-wrapped table cell collapses */
.fb-ph-xs { width: 2rem; }
.fb-ph-sm { width: 3.5rem; }
.fb-ph-md { width: 6rem; }
.fb-ph-lg { width: 11rem; }
.fb-ph-xl { width: 16rem; max-width: 100%; }

@media (prefers-reduced-motion: reduce) {
  body[data-fb-page] .placeholder-glow .placeholder {
    animation: none;
  }
}

/* =============================================================================
   10. Alerts, modal, toast, gate
   ========================================================================== */
body[data-fb-page] .fb-alert {
  --bs-alert-padding-x: var(--fb-sp-3);
  --bs-alert-padding-y: var(--fb-sp-2);
  --bs-alert-margin-bottom: var(--fb-sp-4);
  --bs-alert-border-radius: var(--fb-radius-panel);
  display: flex;
  align-items: flex-start;
  gap: var(--fb-sp-2);
  font-size: var(--fb-fs-base);
}

.fb-alert .fa {
  margin-top: 3px;
}

body[data-fb-page] .modal {
  --bs-modal-border-radius: var(--fb-radius-panel);
  --bs-modal-border-color: var(--fb-border);
  --bs-modal-box-shadow: var(--fb-shadow-float);
  --bs-modal-padding: var(--fb-sp-4);
  --bs-modal-header-padding: var(--fb-sp-3) var(--fb-sp-4);
  --bs-modal-header-border-color: var(--fb-border);
  --bs-modal-footer-border-color: var(--fb-border);
  --bs-modal-footer-gap: var(--fb-sp-2);
  --bs-modal-title-line-height: 1.4;
}

body[data-fb-page] .modal-title {
  font-size: var(--fb-fs-panel);
  font-weight: 600;
}

body[data-fb-page] .modal-footer {
  padding: var(--fb-sp-3) var(--fb-sp-4);
}

body[data-fb-page] .modal-backdrop {
  --bs-backdrop-bg: #11161d;
  --bs-backdrop-opacity: 0.45;
}

body[data-fb-page] .toast {
  --bs-toast-padding-x: var(--fb-sp-3);
  --bs-toast-padding-y: 10px;
  --bs-toast-font-size: var(--fb-fs-base);
  --bs-toast-bg: var(--fb-surface);
  --bs-toast-border-color: var(--fb-border-strong);
  --bs-toast-border-radius: var(--fb-radius-panel);
  --bs-toast-box-shadow: var(--fb-shadow-float);
}

.fb-toast-icon {
  margin-top: 3px;
  color: var(--fb-success);
}

.fb-gate {
  display: grid;
  justify-items: center;
  padding: 3rem 0;
}

.fb-gate-card {
  width: 100%;
  max-width: 27.5rem;
  padding: var(--fb-sp-5);
}

.fb-gate-card h1,
.fb-gate-card h2 {
  margin: 0 0 var(--fb-sp-2);
  font-size: var(--fb-fs-form);
}

.fb-gate-card p {
  margin: 0 0 var(--fb-sp-4);
  color: var(--fb-text-muted);
}

/* =============================================================================
   11. Responsive + input modality
   ========================================================================== */
@media (min-width: 768px) {
  .fb-container {
    padding-inline: var(--fb-sp-5);
  }
}

@media (max-width: 991.98px) {
  body[data-fb-page] .fb-navbar .navbar-collapse {
    padding-block: var(--fb-sp-2) var(--fb-sp-3);
    border-top: 1px solid var(--fb-border);
  }

  .fb-user {
    justify-content: space-between;
    margin-top: var(--fb-sp-2);
    padding-top: var(--fb-sp-3);
    border-top: 1px solid var(--fb-border);
  }

  .fb-user-id {
    text-align: left;
  }
}

@media (max-width: 767.98px) {
  .fb-main {
    padding-block: var(--fb-sp-4) 2rem;
  }

  .fb-toolbar .fb-search {
    flex-basis: 100%;
    max-width: none;
  }

  .fb-toolbar .fb-filter {
    flex: 1 1 auto;
  }

  body[data-fb-page] .fb-table > :not(caption) > * > * {
    padding-inline: var(--fb-sp-3);
  }
}

@media (pointer: coarse) {
  body[data-fb-page] .btn,
  body[data-fb-page] .btn-sm,
  body[data-fb-page] .form-control,
  body[data-fb-page] .form-select {
    min-height: 2.75rem;
  }

  body[data-fb-page] .fb-navbar .nav-link {
    padding-block: 10px;
  }
}

@media (forced-colors: active) {
  .fb-pill,
  .fb-health {
    border: 1px solid CanvasText;
  }
}

/* =============================================================================
   EDITOR (admin-form-editor.html) - Phase 3
   Appended to the shared stylesheet on purpose: one stylesheet keeps the list
   and editor pages from drifting apart. Everything above is unchanged.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   12. Editor state machines. Same pattern as section 3: the machine attribute
   sits on #fb-app (drawer: on the offcanvas, preview: on .fb-preview) and
   elements opt in with data-fb-show-<machine>="a b".
   -------------------------------------------------------------------------- */
[data-fb-editor="loading"] [data-fb-show-editor]:not([data-fb-show-editor~="loading"]),
[data-fb-editor="ready"] [data-fb-show-editor]:not([data-fb-show-editor~="ready"]),
[data-fb-editor="not-found"] [data-fb-show-editor]:not([data-fb-show-editor~="not-found"]),
[data-fb-editor="error"] [data-fb-show-editor]:not([data-fb-show-editor~="error"]),
[data-fb-fields="empty"] [data-fb-show-fields]:not([data-fb-show-fields~="empty"]),
[data-fb-fields="ready"] [data-fb-show-fields]:not([data-fb-show-fields~="ready"]),
[data-fb-publish="live"] [data-fb-show-publish]:not([data-fb-show-publish~="live"]),
[data-fb-publish="not-live"] [data-fb-show-publish]:not([data-fb-show-publish~="not-live"]),
[data-fb-poll="on"] [data-fb-show-poll]:not([data-fb-show-poll~="on"]),
[data-fb-poll="off"] [data-fb-show-poll]:not([data-fb-show-poll~="off"]),
[data-fb-webhook="on"] [data-fb-show-webhook]:not([data-fb-show-webhook~="on"]),
[data-fb-webhook="off"] [data-fb-show-webhook]:not([data-fb-show-webhook~="off"]),
[data-fb-responses="loading"] [data-fb-show-responses]:not([data-fb-show-responses~="loading"]),
[data-fb-responses="ready"] [data-fb-show-responses]:not([data-fb-show-responses~="ready"]),
[data-fb-responses="empty"] [data-fb-show-responses]:not([data-fb-show-responses~="empty"]),
[data-fb-preview="loading"] [data-fb-show-preview]:not([data-fb-show-preview~="loading"]),
[data-fb-preview="ready"] [data-fb-show-preview]:not([data-fb-show-preview~="ready"]),
[data-fb-preview="error"] [data-fb-show-preview]:not([data-fb-show-preview~="error"]),
[data-fb-drawer="loading"] [data-fb-show-drawer]:not([data-fb-show-drawer~="loading"]),
[data-fb-drawer="ready"] [data-fb-show-drawer]:not([data-fb-show-drawer~="ready"]),
[data-fb-drawer="error"] [data-fb-show-drawer]:not([data-fb-show-drawer~="error"]) {
  display: none !important;
}

/* Status colour comes from the attribute, so JS never has to know a class name.
   Mirrors the dispatch mapping of the previous console (failed reads as warning). */
body[data-fb-page] .fb-pill[data-fb-status="active"],
body[data-fb-page] .fb-pill[data-fb-status="success"] {
  --fb-pill-bg: var(--fb-success-tint);
  --fb-pill-fg: var(--fb-success);
}

body[data-fb-page] .fb-pill[data-fb-status="draft"],
body[data-fb-page] .fb-pill[data-fb-status="pending"],
body[data-fb-page] .fb-pill[data-fb-status="sending"],
body[data-fb-page] .fb-pill[data-fb-status="failed"] {
  --fb-pill-bg: var(--fb-warning-tint);
  --fb-pill-fg: var(--fb-warning-text);
}

/* -----------------------------------------------------------------------------
   13. Editor shell: sticky action bar, tabs, banners, load states
   -------------------------------------------------------------------------- */
.fb-editor {
  --fb-head-h: 7.15rem; /* measured height of the sticky bar + tabs, offsets the sticky preview */
}

.fb-editor-loading {
  display: grid;
  gap: var(--fb-sp-4);
}

.fb-editor-head {
  background: var(--fb-bg);
  border-bottom: 1px solid var(--fb-border);
}

.fb-editor-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--fb-sp-2) var(--fb-sp-3);
  padding-block: var(--fb-sp-3);
}

.fb-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px 4px 4px;
  border-radius: var(--fb-radius-control);
  color: var(--fb-text-muted);
  font-weight: 500;
  text-decoration: none;
}

.fb-back:hover {
  background: var(--fb-surface-sunken);
  color: var(--fb-text);
}

.fb-editor-id {
  flex: 1 1 14rem;
  min-width: 0;
}

.fb-editor-title {
  margin: 0;
  overflow: hidden;
  font-size: var(--fb-fs-form);
  line-height: 1.3;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fb-editor-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px var(--fb-sp-2);
  margin-top: 2px;
  color: var(--fb-text-muted);
  font-size: var(--fb-fs-meta);
}

.fb-editor-actions {
  display: flex;
  gap: var(--fb-sp-2);
  margin-left: auto;
}

body[data-fb-page] .fb-tabs {
  --bs-nav-tabs-border-width: 0;
  --bs-nav-link-padding-x: 14px;
  --bs-nav-link-padding-y: 10px;
  --bs-nav-link-color: var(--fb-text-muted);
  --bs-nav-link-hover-color: var(--fb-text);
  --bs-nav-tabs-link-active-color: var(--fb-primary-strong);
  --bs-nav-tabs-link-active-bg: transparent;
  --bs-nav-tabs-link-active-border-color: transparent;
  --bs-nav-tabs-link-hover-border-color: transparent;
  flex-wrap: nowrap;
  gap: 2px;
  overflow-x: auto;
  overflow-y: hidden;
  border-bottom: 0;
  scrollbar-width: none;
}

body[data-fb-page] .fb-tabs .nav-link {
  margin-bottom: -1px;
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  font-size: var(--fb-fs-base);
  font-weight: 500;
  white-space: nowrap;
}

body[data-fb-page] .fb-tabs .nav-link:hover {
  border-bottom-color: var(--fb-border-strong);
}

body[data-fb-page] .fb-tabs .nav-link.active {
  border-bottom-color: var(--fb-primary);
}

/* The tab strip scrolls, which would clip an outset ring, so draw it inside. */
body[data-fb-page] .fb-tabs .nav-link:focus-visible {
  outline-offset: -2px;
}

.fb-tab-count {
  display: inline-block;
  margin-left: 4px;
  padding: 0 6px;
  border-radius: var(--fb-radius-pill);
  background: var(--fb-surface-sunken);
  color: var(--fb-text-muted);
  font-size: var(--fb-fs-caption);
  font-weight: 500;
  line-height: 1.6;
}

.fb-tabs .nav-link.active .fb-tab-count {
  background: var(--fb-primary-tint);
  color: var(--fb-primary-strong);
}

.fb-editor-banners > .fb-alert {
  --bs-alert-margin-bottom: 0;
  margin-top: var(--fb-sp-4);
}

.fb-tab-content {
  padding-top: var(--fb-sp-4);
}

/* -----------------------------------------------------------------------------
   14. Panels (Settings, Automation) and small layout helpers
   -------------------------------------------------------------------------- */
.fb-settings {
  display: grid;
  max-width: 46rem;
  gap: var(--fb-sp-4);
}

.fb-settings > [data-fb-show-webhook] {
  display: grid;
  gap: var(--fb-sp-4);
}

.fb-settings .fb-health {
  margin-bottom: 0;
}

.fb-panel-head {
  padding: var(--fb-sp-3) var(--fb-sp-4);
  border-bottom: 1px solid var(--fb-border);
}

.fb-panel-title {
  margin: 0;
  font-size: var(--fb-fs-panel);
}

.fb-panel-body {
  padding: var(--fb-sp-4);
}

.fb-rule {
  margin: var(--fb-sp-4) 0;
  border: 0;
  border-top: 1px solid var(--fb-border);
  opacity: 1;
}

.fb-switch-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--fb-sp-4);
}

.fb-switch-row > :first-child {
  min-width: 0;
}

.fb-switch-row p {
  margin: 2px 0 0;
}

/* An action button beside a long description must not shrink or wrap. */
.fb-switch-row > .btn {
  flex: none;
  white-space: nowrap;
}

label.fb-switch-row {
  cursor: pointer;
}

/* A 44 by 24px switch: WCAG 2.2 target size needs at least 24px, and it needs more label room
   than Bootstrap's 2.5em padding gives it. */
body[data-fb-page] .form-switch {
  padding-left: 3.375rem;
}

body[data-fb-page] .form-switch .form-check-input {
  width: 2.75rem;
  height: 1.5rem;
  margin-left: -3.375rem;
}

/* Bootstrap's off-state knob is 25% black, about 1.8:1 on the track. The control-border grey
   (#7d8794, the same as the switch's own border) is 3.4:1 and keeps its shape when focused. */
body[data-fb-page] .form-switch .form-check-input:not(:checked) {
  --bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%237d8794'/%3e%3c/svg%3e");
}

/* In a switch row the switch stands alone on the right, so drop the label room. */
body[data-fb-page] .fb-switch-row .form-check {
  flex: none;
  min-height: 0;
  margin: 0;
  padding-left: 0;
}

body[data-fb-page] .fb-switch-row .form-check-input {
  float: none;
  margin: 0;
}

.fb-actions-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--fb-sp-2);
  margin-top: var(--fb-sp-4);
}

.fb-copy-row {
  display: flex;
  gap: var(--fb-sp-2);
}

.fb-copy-row .form-control {
  flex: 1 1 auto;
  min-width: 0;
}

.fb-copy-row-narrow {
  width: 100%;
  max-width: 32rem;
}

body[data-fb-page] .fb-mono-input {
  font-family: var(--fb-mono);
  font-size: var(--fb-fs-label);
}

body[data-fb-page] .form-control[readonly] {
  background-color: var(--fb-surface-sunken);
}

body[data-fb-page] .input-group-text {
  border-color: var(--fb-input-border);
  background: var(--fb-surface-sunken);
  color: var(--fb-text-muted);
  font-size: var(--fb-fs-label);
}

body[data-fb-page] .fb-locked-hint {
  color: var(--fb-warning-text);
  font-size: var(--fb-fs-meta);
}

/* Danger buttons: Bootstrap hardcodes its own red, so theme both variants. */
body[data-fb-page] .btn-danger {
  --bs-btn-color: #fff;
  --bs-btn-bg: var(--fb-danger);
  --bs-btn-border-color: var(--fb-danger);
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: #a5322a;
  --bs-btn-hover-border-color: #a5322a;
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: #8f2a23;
  --bs-btn-active-border-color: #8f2a23;
  --bs-btn-active-shadow: none;
  --bs-btn-disabled-color: #fff;
  --bs-btn-disabled-bg: var(--fb-danger);
  --bs-btn-disabled-border-color: var(--fb-danger);
}

body[data-fb-page] .btn-outline-danger {
  --bs-btn-color: var(--fb-danger);
  --bs-btn-bg: var(--fb-surface);
  --bs-btn-border-color: var(--fb-danger-border);
  --bs-btn-hover-color: #9b2c23;
  --bs-btn-hover-bg: var(--fb-danger-tint);
  --bs-btn-hover-border-color: var(--fb-danger);
  --bs-btn-active-color: #9b2c23;
  --bs-btn-active-bg: var(--fb-danger-border);
  --bs-btn-active-border-color: var(--fb-danger);
  --bs-btn-active-shadow: none;
  --bs-btn-disabled-color: var(--fb-danger);
  --bs-btn-disabled-border-color: var(--fb-danger-border);
}

body[data-fb-page] .fb-danger-link {
  --bs-btn-color: var(--fb-danger);
  --bs-btn-hover-color: #9b2c23;
  --bs-btn-active-color: #8f2a23;
}

.fb-danger-zone {
  border-color: var(--fb-danger-border);
}

.fb-danger-zone .fb-panel-head {
  border-color: var(--fb-danger-border);
  background: var(--fb-danger-tint);
}

.fb-danger-zone .fb-panel-title {
  color: #9b2c23;
}

/* -----------------------------------------------------------------------------
   15. Build tab: field list, option chips, live preview
   -------------------------------------------------------------------------- */
.fb-build {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
  gap: var(--fb-sp-4);
}

.fb-fields-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--fb-sp-2);
  margin-bottom: var(--fb-sp-2);
}

.fb-fields-toolbar-actions {
  display: flex;
  gap: var(--fb-sp-2);
}

.fb-field-list {
  display: grid;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.fb-field-row {
  border: 1px solid var(--fb-border);
  border-radius: var(--fb-radius-control);
  background: var(--fb-surface);
}

.fb-field-row[data-fb-open="true"] {
  border-color: var(--fb-primary);
}

.fb-field-head {
  display: flex;
  align-items: center;
  gap: 4px;
  min-height: 2.375rem;
  padding-right: 6px;
}

/* Two-by-three dot grid drawn in CSS: no icon font needed, and hidden on touch
   where drag is off and the move buttons are the way to reorder. */
.fb-grip {
  flex: none;
  width: 10px;
  height: 15px;
  margin: 0 6px 0 10px;
  color: var(--fb-text-faint);
  background-image: radial-gradient(circle, currentColor 1.15px, transparent 1.5px);
  background-size: 5px 5px;
  cursor: grab;
}

.fb-field-toggle {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  align-self: stretch;
  gap: var(--fb-sp-2);
  min-width: 0;
  padding: 0 4px;
  border: 0;
  border-radius: var(--fb-radius-control);
  background: none;
  color: var(--fb-text);
  text-align: left;
}

.fb-field-toggle:hover {
  background: var(--fb-bg);
}

.fb-field-label {
  overflow: hidden;
  font-weight: 500;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fb-type-tag {
  flex: none;
  padding: 1px 6px;
  border-radius: 4px;
  background: var(--fb-surface-sunken);
  color: var(--fb-text-muted);
  font-family: var(--fb-mono);
  font-size: var(--fb-fs-caption);
}

.fb-req {
  flex: none;
  color: var(--fb-danger);
  font-size: 0.5625rem;
}

/* The expand chevron leads the label so it never reads as a third move arrow. */
.fb-chevron {
  order: -1;
  flex: none;
  width: 0.75rem;
  color: var(--fb-text-muted);
  font-size: var(--fb-fs-meta);
  transform: rotate(-90deg);
  transition: transform 0.15s ease;
}

.fb-field-row[data-fb-open="true"] .fb-chevron {
  transform: none;
}

.fb-field-actions {
  display: flex;
  flex: none;
  gap: 2px;
}

.fb-icon-btn {
  display: inline-grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  padding: 0;
  border: 0;
  border-radius: var(--fb-radius-control);
  background: transparent;
  color: var(--fb-text-muted);
  font-size: var(--fb-fs-meta);
}

.fb-icon-btn:hover {
  background: var(--fb-surface-sunken);
  color: var(--fb-text);
}

.fb-icon-btn:disabled {
  opacity: 0.4;
}

.fb-field-body {
  padding: var(--fb-sp-3);
  border-top: 1px solid var(--fb-border);
}

.fb-field-foot {
  display: flex;
  justify-content: flex-end;
  margin-top: var(--fb-sp-2);
}

.fb-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}

.fb-chip {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 2px 4px 2px 10px;
  border-radius: var(--fb-radius-pill);
  background: var(--fb-primary-tint);
  color: var(--fb-primary-strong);
  font-size: var(--fb-fs-meta);
  font-weight: 500;
  line-height: 1.25rem;
}

.fb-chip-remove {
  display: grid;
  place-items: center;
  width: 1.25rem;
  height: 1.25rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  font-size: 0.625rem;
}

.fb-chip-remove:hover {
  background: rgba(21, 89, 214, 0.14);
}

body[data-fb-page] .fb-chip-input {
  flex: 1 1 8rem;
  width: auto;
  min-width: 8rem;
  max-width: 14rem;
  min-height: 2rem;
}

.fb-build-preview .collapse:not(.show) {
  margin-top: 0;
}

.fb-preview {
  overflow: hidden;
  border: 1px solid var(--fb-border);
  border-radius: var(--fb-radius-panel);
  background: var(--fb-surface);
}

.fb-preview-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--fb-sp-2) var(--fb-sp-3);
  border-bottom: 1px solid var(--fb-border);
}

.fb-preview-label {
  margin: 0;
  font-size: var(--fb-fs-label);
}

body[data-fb-page] .fb-preview-bar .btn.active {
  border-color: var(--fb-primary-border);
  background: var(--fb-primary-tint);
  color: var(--fb-primary-strong);
}

.fb-preview-stage {
  padding: var(--fb-sp-3);
  background: var(--fb-surface-sunken);
}

.fb-preview-frame {
  display: block;
  width: 100%;
  height: clamp(20rem, calc(100vh - 16rem), 40rem);
  margin-inline: auto;
  border: 1px solid var(--fb-border);
  border-radius: var(--fb-radius-control);
  background: #fff;
}

.fb-preview[data-fb-device="mobile"] .fb-preview-frame {
  max-width: 390px;
}

.fb-preview-skeleton {
  padding: var(--fb-sp-4);
  border: 1px solid var(--fb-border);
  border-radius: var(--fb-radius-control);
  background: #fff;
}

.fb-preview-note {
  margin: 0;
  padding: var(--fb-sp-2) var(--fb-sp-3);
  border-top: 1px solid var(--fb-border);
  color: var(--fb-text-muted);
  font-size: var(--fb-fs-meta);
}

/* -----------------------------------------------------------------------------
   16. Poll status, progress
   -------------------------------------------------------------------------- */
.fb-poll-rows {
  display: grid;
  gap: var(--fb-sp-3);
  margin: var(--fb-sp-3) 0 0;
  padding: 0;
  list-style: none;
}

.fb-poll-row-top {
  display: flex;
  justify-content: space-between;
  gap: var(--fb-sp-2);
  margin-bottom: 4px;
}

body[data-fb-page] .progress {
  --bs-progress-height: 8px;
  --bs-progress-bg: var(--fb-surface-sunken);
  --bs-progress-bar-bg: var(--fb-primary-strong);
  --bs-progress-border-radius: var(--fb-radius-pill);
  --bs-progress-font-size: 0;
}

/* -----------------------------------------------------------------------------
   17. Responses: toolbar, columns menu, sticky-column table
   -------------------------------------------------------------------------- */
body[data-fb-page] .dropdown-menu {
  --bs-dropdown-bg: var(--fb-surface);
  --bs-dropdown-border-color: var(--fb-border);
  --bs-dropdown-border-radius: var(--fb-radius-panel);
  --bs-dropdown-box-shadow: var(--fb-shadow-float);
  --bs-dropdown-padding-x: 6px;
  --bs-dropdown-padding-y: 6px;
  --bs-dropdown-font-size: var(--fb-fs-base);
  --bs-dropdown-color: var(--fb-text);
  --bs-dropdown-link-color: var(--fb-text);
  --bs-dropdown-link-hover-color: var(--fb-text);
  --bs-dropdown-link-hover-bg: var(--fb-surface-sunken);
  --bs-dropdown-link-active-color: var(--fb-text);
  --bs-dropdown-link-active-bg: var(--fb-surface-sunken);
  --bs-dropdown-header-color: var(--fb-text-muted);
}

.fb-columns-menu {
  min-width: 14rem;
  max-height: 20rem;
  overflow-y: auto;
}

.fb-columns-menu .dropdown-header {
  padding: 6px 10px;
  font-size: var(--fb-fs-meta);
  font-weight: 600;
}

.fb-columns-menu .dropdown-item {
  display: flex;
  align-items: center;
  gap: var(--fb-sp-2);
  margin: 0;
  padding: 6px 10px;
  border-radius: var(--fb-radius-control);
  cursor: pointer;
}

.fb-columns-menu .form-check-input {
  float: none;
  margin: 0;
}

body[data-fb-page] .fb-table-responses {
  min-width: 60rem;
  border-collapse: separate;
  border-spacing: 0;
}

body[data-fb-page] .fb-table-responses td {
  white-space: nowrap;
}

/* Pinned columns only where there is room to keep reading beside them. */
@media (min-width: 768px) {
  body[data-fb-page] .fb-table-responses .fb-col-check,
  body[data-fb-page] .fb-table-responses .fb-col-when {
    position: sticky;
    z-index: 2;
    background-color: var(--fb-surface);
  }
}

body[data-fb-page] .fb-table-responses thead .fb-col-check,
body[data-fb-page] .fb-table-responses thead .fb-col-when {
  background-color: var(--fb-surface-sunken);
}

body[data-fb-page] .fb-table-responses .fb-col-check {
  left: 0;
  width: 2.75rem;
  min-width: 2.75rem;
}

body[data-fb-page] .fb-table-responses .fb-col-when {
  left: 2.75rem;
  min-width: 11.5rem;
  border-right: 1px solid var(--fb-border);
}

.fb-linkbtn {
  padding: 0;
  border: 0;
  background: none;
  color: var(--fb-primary-strong);
  font: inherit;
  font-weight: 500;
}

.fb-linkbtn:hover {
  color: var(--fb-primary-hover);
  text-decoration: underline;
}

.fb-cell-clip {
  display: inline-block;
  max-width: 16rem;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: bottom;
  white-space: nowrap;
}

.fb-cell-file {
  color: var(--fb-primary-strong);
  text-decoration: none;
  white-space: nowrap;
}

.fb-cell-file:hover {
  text-decoration: underline;
}

.fb-table-note {
  margin: 0;
  padding: var(--fb-sp-2) var(--fb-sp-4);
  border-top: 1px solid var(--fb-border);
  color: var(--fb-text-muted);
  font-size: var(--fb-fs-meta);
}

/* -----------------------------------------------------------------------------
   18. Response drawer (Bootstrap offcanvas)
   -------------------------------------------------------------------------- */
body[data-fb-page] .fb-drawer {
  --bs-offcanvas-width: min(30rem, 100vw);
  --bs-offcanvas-bg: var(--fb-surface);
  --bs-offcanvas-color: var(--fb-text);
  --bs-offcanvas-border-color: var(--fb-border);
  --bs-offcanvas-box-shadow: var(--fb-shadow-float);
  --bs-offcanvas-padding-x: var(--fb-sp-4);
  --bs-offcanvas-padding-y: var(--fb-sp-3);
}

body[data-fb-page] .offcanvas-backdrop {
  --bs-backdrop-bg: #11161d;
  --bs-backdrop-opacity: 0.45;
}

.fb-drawer .offcanvas-header {
  align-items: flex-start;
  border-bottom: 1px solid var(--fb-border);
}

.fb-drawer .offcanvas-title {
  font-size: var(--fb-fs-panel);
  font-weight: 600;
}

.fb-drawer-sub {
  margin: 2px 0 0;
  color: var(--fb-text-muted);
  font-size: var(--fb-fs-meta);
}

.fb-drawer-h {
  margin: var(--fb-sp-5) 0 var(--fb-sp-2);
  color: var(--fb-text-muted);
  font-size: var(--fb-fs-label);
  font-weight: 600;
}

.fb-drawer-h:first-child {
  margin-top: 0;
}

.fb-dl {
  margin: 0;
}

.fb-dl-row {
  padding: var(--fb-sp-2) 0;
  border-bottom: 1px solid var(--fb-border);
}

.fb-dl-row dt {
  margin-bottom: 2px;
  color: var(--fb-text-muted);
  font-size: var(--fb-fs-meta);
  font-weight: 500;
}

.fb-dl-row dd {
  margin: 0;
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}

.fb-drawer-status {
  display: flex;
  align-items: center;
  gap: var(--fb-sp-2);
  margin-bottom: var(--fb-sp-2);
}

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

.fb-dispatch-row {
  display: flex;
  align-items: center;
  gap: var(--fb-sp-2);
  padding: 6px 0;
  border-bottom: 1px solid var(--fb-border);
  font-size: var(--fb-fs-label);
}

.fb-drawer-foot {
  display: flex;
  justify-content: flex-end;
  padding: var(--fb-sp-3) var(--fb-sp-4);
  border-top: 1px solid var(--fb-border);
}

/* -----------------------------------------------------------------------------
   19. Editor responsive + input modality
   -------------------------------------------------------------------------- */
@media (min-width: 768px) {
  .fb-editor-head {
    position: sticky;
    top: 0;
    z-index: 1020;
  }
}

@media (min-width: 1200px) {
  .fb-build {
    grid-template-columns: minmax(0, 1fr) minmax(0, 27rem);
  }

  .fb-build-preview {
    position: sticky;
    top: calc(var(--fb-head-h) + var(--fb-sp-4));
  }
}

@media (max-width: 575.98px) {
  .fb-editor-actions {
    flex: 1 1 100%;
    justify-content: flex-end;
  }

  .fb-switch-row {
    align-items: flex-start;
  }

  .fb-copy-row {
    flex-wrap: wrap;
  }

  .fb-copy-row .form-control {
    flex-basis: 100%;
  }
}

@media (pointer: coarse) {
  .fb-grip {
    display: none;
  }

  .fb-field-head {
    min-height: 2.75rem;
  }

  .fb-icon-btn {
    width: 2.75rem;
    height: 2.75rem;
  }

  .fb-chip-remove {
    width: 1.75rem;
    height: 1.75rem;
  }

  .fb-linkbtn {
    min-height: 2.75rem;
  }

  body[data-fb-page] .fb-tabs .nav-link {
    min-height: 2.75rem;
  }

  body[data-fb-page] .fb-chip-input {
    min-height: 2.75rem;
  }
}

@media (forced-colors: active) {
  .fb-chip,
  .fb-field-row {
    border: 1px solid CanvasText;
  }
}

/* =============================================================================
   20. Drag reorder (SortableJS). Extends section 15: the grip starts a drag, the
   row that was picked up gets a primary border, and the gap it will land in shows
   as a dashed outline. The move buttons stay the keyboard and touch path.
   ========================================================================== */
.fb-grip {
  touch-action: none;
}

.fb-field-row.fb-drag-chosen {
  border-color: var(--fb-primary);
}

.fb-field-row.fb-drag-chosen .fb-grip {
  cursor: grabbing;
}

.fb-field-row.fb-drag-ghost {
  border-style: dashed;
  border-color: var(--fb-primary);
  background: var(--fb-primary-tint);
}

.fb-field-row.fb-drag-ghost > * {
  visibility: hidden;
}

/* The row as it floats: the browser's drag image for a mouse, Sortable's own copy
   for touch. That copy lives outside the list, so it must not draw a list marker. */
.fb-field-row.fb-drag-active {
  border-color: var(--fb-primary);
  list-style: none;
  opacity: 0.95;
}

@media (forced-colors: active) {
  .fb-field-row.fb-drag-ghost {
    border: 2px dashed Highlight;
  }
}
