/* ============================================================
   @bubbleye-ai/copilot-ui — bundled stylesheet

   Every class in this file is prefixed with `copilot-` so a
   consumer's global stylesheet can't accidentally collide. Import
   ONCE in your app root:

       import "@bubbleye-ai/copilot-ui/styles.css";

   ============================================================ */

/* ---- StandardSpinner ----------------------------------------- */
.copilot-spinner {
  width: 20px;
  height: 20px;
  border: 2px solid #e3f2fd;
  border-top: 2px solid #007bff;
  border-radius: 50%;
  animation: copilot-spin 1s linear infinite;
  box-sizing: border-box;
}

.copilot-spinner-block {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  color: #007bff;
}

.copilot-spinner-block span {
  font-size: 0.9rem;
  font-weight: 500;
}

@keyframes copilot-spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* ---- TargetBadge --------------------------------------------- */
.copilot-target-badge {
  width: 30px;
  height: 30px;
  border-radius: 6px;
  border: 1px solid #ced4da;
  background: #f8f9fa;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  flex: 0 0 auto;
}

/* ---- StatusToggle -------------------------------------------- */
.permission-toggle {
  position: relative;
  display: inline-block;
  width: 44px;
  height: 24px;
}

.permission-toggle input { opacity: 0; width: 0; height: 0; }

.toggle-slider {
  position: absolute;
  cursor: pointer;
  top: 0; left: 0; right: 0; bottom: 0;
  background-color: #d1d5db;
  transition: 0.3s;
  border-radius: 24px;
}

.toggle-slider:before {
  position: absolute;
  content: "";
  height: 18px;
  width: 18px;
  left: 3px;
  bottom: 3px;
  background-color: white;
  transition: 0.3s;
  border-radius: 50%;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.permission-toggle input:checked + .toggle-slider { background-color: #10b981; }
.permission-toggle input:checked + .toggle-slider:before { transform: translateX(20px); }
.permission-toggle input:disabled + .toggle-slider { opacity: 0.5; cursor: not-allowed; }

/* Compact variant — used by panel status cells so the toggle doesn't
   dominate the row. Same colours/behaviour, ~30% smaller. */
.permission-toggle.permission-toggle--sm { width: 30px; height: 16px; }
.permission-toggle--sm .toggle-slider { border-radius: 16px; }
.permission-toggle--sm .toggle-slider:before {
  height: 12px; width: 12px; left: 2px; bottom: 2px;
}
.permission-toggle--sm input:checked + .toggle-slider:before {
  transform: translateX(14px);
}

.bubbleye-tag-cloud-stage {
  position: relative;
  width: 100%;
  height: 100%;
  min-height: inherit;
  overflow: hidden;
  user-select: none;
}

.bubbleye-tag-cloud-item {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: default;
  transition:
    transform 0.25s cubic-bezier(0.16, 1, 0.3, 1),
    filter 0.22s ease,
    opacity 0.2s ease;
}

.bubbleye-tag-cloud-item:hover {
  transform: scale(1.1);
  filter: brightness(1.3) drop-shadow(0 0 10px rgba(15, 23, 42, 0.15));
  z-index: 999;
}

.bubbleye-tag-cloud-item-inner {
  display: flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  line-height: 1;
}

.bubbleye-tag-cloud-tooltip {
  position: absolute;
  bottom: 100%;
  left: 50%;
  margin-bottom: 8px;
  padding: 6px 10px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 6px;
  background: rgba(15, 23, 42, 0.98);
  box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.35);
  color: #cbd5e1;
  font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px;
  line-height: 1.45;
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, 4px);
  transition: opacity 0.15s ease, transform 0.15s ease;
  white-space: pre;
  z-index: 1000;
}

.bubbleye-tag-cloud-item:hover .bubbleye-tag-cloud-tooltip {
  opacity: 1;
  transform: translate(-50%, 0);
}

/* ── CalendarTimestamp (mini calendar chip) ──────────────────────────
 * Blue spine with the month reading upward; day digits on white; soft
 * shadow. Theme via:
 *   --copilot-cal-accent  spine background   (default #0d6efd)
 *   --copilot-cal-day     day digit color    (default #1e40af)
 */
.cal-ts {
  display: inline-flex;
  align-items: center;
  vertical-align: middle;
  gap: 5px;
  white-space: nowrap;
}
/* The time is PLAIN text: several copilots carry a legacy global
 * `time { }` chip rule (gray background, 600 weight) that this <time>
 * element would inherit - neutralize it here so the iconic form always
 * renders the time at standard size/weight with no background. */
time.cal-ts-time {
  background: none;
  padding: 0;
  border-radius: 0;
  font-weight: 400;
  font-size: inherit;
  color: inherit;
}
.cal-chip {
  display: inline-flex;
  align-items: stretch;
  height: 20px;
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 1px 2px rgba(16, 44, 84, 0.18);
  flex: none;
}
.cal-chip-mon {
  writing-mode: vertical-rl;
  transform: rotate(180deg); /* month reads upward */
  display: flex;
  align-items: center;
  justify-content: center;
  width: 11px;
  background: var(--copilot-cal-accent, #0d6efd);
  color: #fff;
  font-size: 7.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.cal-chip-day {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 15px;
  padding: 0 4px;
  background: #fff;
  color: var(--copilot-cal-day, #1e40af);
  font-size: 12.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* variant="extendedCalendar": the year sits under the day, like a
 * wall-calendar page. Theme via --copilot-cal-year (default #7a8bb5). */
.cal-chip--year {
  height: 26px;
}
.cal-chip--year .cal-chip-day {
  flex-direction: column;
  gap: 1px;
  padding: 0 3px;
  line-height: 1;
}
.cal-chip-yr {
  font-size: 7px;
  letter-spacing: 0.04em;
  color: var(--copilot-cal-year, #7a8bb5);
}
/* AdvancedFilters — the panel's own stylesheet.
 * Shipped as the package export "@bubbleye-ai/copilot-ui/advancedFilters.css".
 * Moved out of each copilot's App.css on 2026-09-04; leaving the CSS
 * behind is exactly how mintegral ended up without the spinner rule. */

/* Advanced Filters (Headless Multi-Select) */
.advanced-filters {
  border-radius: 8px;
  background: #fff;
  margin-bottom: 12px;
}

.advanced-filters-header {
  display: none;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.advanced-filters-title {
  font-weight: 600;
  color: #343a40;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
}

.advanced-filters-count {
  background: #e9ecef;
  color: #495057;
  border-radius: 999px;
  padding: 2px 8px;
  font-size: 11px;
  font-weight: 600;
}

.advanced-filters-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.advanced-filters-toggle,
.advanced-filters-clear {
  border: 1px solid #ced4da;
  background: #f8f9fa;
  color: #495057;
  padding: 4px 10px;
  border-radius: 6px;
  cursor: pointer;
}

.advanced-filters-toggle:hover,
.advanced-filters-clear:hover {
  background: #e9ecef;
}

.advanced-filters-bar {
  display: flex;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
  margin-top: 10px;
}

.advanced-filter {
  flex: auto;
  border-radius: 8px;
  padding: 0;
  background: #fdfdff;
  position: relative;
}

.advanced-filter-top {
  display: flex;
  align-items: center;
}

.advanced-filter-label {
  flex: 1;
  font-weight: 600;
  color: #495057;
  margin-bottom: 6px;
}

.advanced-filter-controls {
  display: flex;
  align-items: center;
}

.advanced-filter-mode {
  display: inline-flex;
  border: 1px solid #ced4da;
  border-radius: 6px;
  overflow: hidden;
  margin-bottom: 3px;
}

.advanced-filter-clear {
  border: 1px solid #ced4da;
  background: #f8f9fa;
  color: #6c757d;
  padding: 4px 6px;
  border-radius: 50%;
  font-size: 11px;
  cursor: pointer;
  margin-left: 6px;
}

.advanced-filter-clear:hover {
  background: #e9ecef;
  color: #343a40;
}

.advanced-filter-mode-btn {
  padding: 4px 8px;
  font-size: 11px;
  border: none;
  background: #f8f9fa;
  color: #6c757d;
  cursor: pointer;
}

.advanced-filter-include-btn::after,
.advanced-filter-exclude-btn::after {
  font-family: "Font Awesome 6 Free";
  font-weight: 900;
  display: inline-block;
}

.advanced-filter-include-btn::after {
  content: "\f067";
}

.advanced-filter-exclude-btn::after {
  content: "\f068";
}

.advanced-filter-mode-btn.active {
  color: #fff;
}

.advanced-filter-include-btn.active {
  background: #999;
}

.advanced-filter-exclude-btn.active {
  background: #dc3545;
}

.advanced-filter-trigger {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 8px;
  border: 1px solid #ced4da;
  border-radius: 6px;
  background: #fff;
  color: #495057;
  cursor: pointer;
}

/* The trigger reads its ticked values ("EN, FR +2"): long ones ellipsize,
   the count never does, and the chevron keeps its place. */
.advanced-filter-trigger-values {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: left;
}

.advanced-filter-trigger-more {
  flex: none;
  margin-left: 4px;
  font-weight: 400;
  margin-right: 4px;
  background: #3f6ea8;
  color: #fff !important;
  padding: 0 4px;
  font-size: 0.9em;
  border-radius: 4px;
}

.advanced-filter-panel {
  margin-top: 8px;
  border: 1px solid #dee2e6;
  border-radius: 6px;
  background: #fff;
  padding: 8px;
  box-shadow: 0 6px 14px rgba(0, 0, 0, 0.08);
  position: absolute;
  left: 0;
  right: 0;
  z-index: 11;
}

.advanced-filter-search {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid #ced4da;
  border-radius: 6px;
  margin-bottom: 8px;
  /* No global border-box reset in this stylesheet — without this the
     width:100% + padding + border overflows the dropdown panel on the right. */
  box-sizing: border-box;
}

.advanced-filter-options {
  max-height: 160px;
  overflow-y: auto;
  display: grid;
  gap: 3px;
}

.advanced-filter-option {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.9em;
  color: #495057;
}

.advanced-filter-empty {
  color: #6c757d;
  text-align: center;
  padding: 8px 0;
}

.advanced-filters-result {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
}

.advanced-filters-quick-search {
  display: flex;
  align-items: center;
  gap: 4px;
  height: 30px;
  padding: 0 10px;
  border: 1px solid #dee2e6;
  border-radius: 6px;
  min-width: 220px;
  box-sizing: border-box;
  cursor: text;
}

.advanced-filters-quick-search.is-tokenized {
  flex-wrap: wrap;
  height: auto;
  min-height: 30px;
}

.advanced-filters-quick-search-input {
  flex: 1 1 90px;
  width: 100%;
  height: 30px;
  border: 0;
  outline: none;
  padding: 0;
  font: inherit;
  background: transparent;
}

.advanced-filters-quick-search.is-tokenized .advanced-filters-quick-search-input {
  width: auto;
  min-width: 90px;
  padding: 2px 0;
}

.advanced-filters-quick-search-token {
  padding: 1px 6px;
  border-radius: 999px;
  background: #eef2ff;
  color: #334155;
  font-size: 11px;
}

.advanced-filters-quick-search-addon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  color: #6c757d;
  font-size: 12px;
  flex: 0 0 auto;
}

/* A filter column holding a selection gets a blue border so an active
   filter is visible without opening its panel. */
.filter-selected {
  border-color: #007bff;
}

/* A column restored from the consumer's remembered selection, until the user
   touches it: it has to be obvious which filters the user did NOT just set. */
.advanced-filter-trigger.filter-restored {
  border-color: #0b5ed7;
  box-shadow: inset 0 0 0 1px #0b5ed7;
  background: #eaf2ff;
  color: #0a3d91;
  font-weight: 600;
}

/* ...and the sentence that says so, above the bar (a collapsed bar hides the
   triggers, never the reason the list is short). */
.advanced-filters-restored {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  margin-top: 2px;
  border: 1px solid #9ec5fe;
  border-left: 4px solid #0b5ed7;
  border-radius: 6px;
  background: #eaf2ff;
  color: #0a3d91;
  font-size: 13px;
}

.advanced-filters-restored-clear {
  margin-left: auto;
  flex: none;
  padding: 5px 12px;
  border: 1px solid #0b5ed7;
  border-radius: 6px;
  background: #fff;
  color: #0b5ed7;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

.advanced-filters-restored-clear:hover {
  background: #dbe9ff;
}

/* A filter column whose authoritative option list is still loading: a
   spinner, never a partial list built from the rows already loaded. */
.advanced-filter-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 8px;
  color: #6c757d;
  font-size: 12px;
}
/*
 * meta-port.css
 * Ported from MetaAssetManager/ProductionMetaUploader/presentation/web/src/App.css
 * Subset: global base, progress-header, header-logo, header-flow, flow-cta,
 *         flow-landing, user-menu, panel-buttons, progress-step, .btn, .app
 * Adapted for Google Creative Copilot (slice-2).
 */

/* â”€â”€â”€ Base â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

body {
  margin: 0;
  font-family: 'Manrope', sans-serif;
  font-size: 12px;
  background: #f8f9fa;
}

body.admin {
  background: #c9ccd0;
}

/* Admin-only content (raw/diagnostic error strings, admin controls) is
   hidden from standard users entirely and revealed only for admins, who
   get the `admin` body class from useCurrentUser. Scoping the hide to
   `body:not(.admin)` leaves the element's natural/author display intact
   for admins (no display:revert guesswork). Fails closed: until
   /api/auth/me resolves, body has no `admin` class so nothing leaks. */
body:not(.admin) .admin-only {
  display: none !important;
}

.admin-only:not(.user-management-flow .admin-only) {
  border: dashed 2px fuchsia !important;
  background: #ffccff !important;
  color: purple !important;
}

/* Demo mode (presentation/recording) hides the loud admin-only raw-error
   boxes so an admin can screen-share a clean UI. Keyed off the `demo`
   body class set by DemoModeContext; orthogonal to the `admin` class. */
body.demo .admin-only {
  display: none !important;
}

p { margin:0; }

.admin-route-shell {
  max-width: calc(100vw - 50px);
  margin: 0 auto;
  padding: 24px;
}

.admin-route-shell__header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 24px;
  flex-wrap: wrap;
}

.admin-route-shell__title {
  margin: 0;
  color: #495057;
  font-size: 28px;
  font-weight: 700;
}

.admin-route-shell__subtitle {
  margin: 8px 0 0;
  color: #6c757d;
  font-size: 13px;
}

.admin-route-shell__nav {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.admin-route-shell__nav-link {
  color: #495057;
  text-decoration: none;
  border: 1px solid #dee2e6;
  border-radius: 999px;
  padding: 8px 14px;
  background: #fff;
  font-size: 13px;
  font-weight: 600;
}

.admin-route-shell__nav-link.active {
  background: #e7f1ff;
  border-color: #9ec5fe;
  color: #0d6efd;
}

.section-container {
  background: #fff;
  border: 1px solid #dee2e6;
  border-radius: 8px;
  padding: 18px;
}

.user-management-content {
}

.table-container {
  overflow: auto;
  height: 100%;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
}

.user-management-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  zoom: .8;
}

.user-management-table th {
  background: #f9fafb;
  padding: 12px 8px;
  text-align: left;
  font-weight: 600;
  color: #374151;
  border-bottom: 1px solid #e5e7eb;
  position: sticky;
  top: 0;
  z-index: 10;
}

.user-management-table td {
  padding: 12px 8px;
  border-bottom: 1px solid #f3f4f6;
  vertical-align: top;
}

.user-management-table tbody tr:hover {
  background: #f9fafb;
}

.user-cell {
  min-width: 120px;
}

.user-cell .user-id {
  font-size: 11px;
  color: #6b7280;
  font-family: monospace;
  margin-top: 4px;
}

/* "View as" lives in the User column, under the id: it is about that person,
   not about the row's actions. The wrapper is a block so the button lands
   BELOW the id (.user-id is inline) without making every id a block. */
.user-cell .user-cell-view-as {
  margin-top: 6px;
}

/* â”€â”€â”€ App shell â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.app {
  height: calc(100vh - 58px);
  padding-top: 58px; /* Space for fixed header */
  display: flex;
  flex-direction: column;
}

/* â”€â”€â”€ Progress / App Header â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

/* ─── Read-only mode pill ─────────────────────────────────────────────────
   Floating overlay on the header, NOT a layout bar: fixed + no height
   contribution, so the app never shifts when it appears. Drops below the
   view-as bar when both are on screen. */
.read-only-bar {
  position: fixed;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 30;              /* over .progress-header (20), under ViewAsBar (9999) */
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 16px;
  border-radius: 999px;
  background: linear-gradient(180deg, #fff8e6 0%, #fdefc8 100%);
  border: 1px solid #e8c76a;
  color: #7a5300;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .2px;
  white-space: nowrap;
  box-shadow: 0 2px 10px rgba(122, 83, 0, .18);
  pointer-events: none;     /* purely informational — never eats a header click */
}


/* Dark admin header — keep the pill legible. */
.admin .read-only-bar {
  background: linear-gradient(180deg, #4a3c17 0%, #3a2f12 100%);
  border-color: #8a6d22;
  color: #ffd980;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .4);
}

.progress-header {
  background: white;
  border-bottom: 1px solid #e9ecef;
  padding: 8px 24px;
  display: flex;
  align-items: center;
  gap: 16px;
  min-height: 60px;
  z-index: 20;
  position: fixed;
  top: 0;
  width: 100%;
  box-sizing: border-box;
}

/* â”€â”€â”€ View-as (support delegation) banner â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.view-as-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 38px;
  z-index: 30; /* above .progress-header (20) */
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 16px;
  background: #7c3aed; /* violet â€” distinct from any normal app chrome */
  color: #fff;
  font-size: 13px;
  font-weight: 500;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
}
.view-as-bar__text {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.view-as-bar__by {
  opacity: 0.85;
}
.view-as-bar__stop {
  flex: none;
  background: rgba(255, 255, 255, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.45);
  color: #fff;
  border-radius: 6px;
  padding: 3px 12px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}
.view-as-bar__stop:hover {
  background: rgba(255, 255, 255, 0.3);
}

/* When delegated, drop the header + page content by the 38px banner height. */
body.view-as-active .progress-header {
  top: 38px;
}
body.view-as-active .app {
  padding-top: 96px; /* 58 + 38 */
  height: calc(100vh - 96px);
}

.admin .progress-header {
  background-color: #333;
  border-bottom-color: #444;
}

.admin .progress-header img {
  filter: brightness(0) invert(1);
}

/* Temporary brand swap â€” keep the wordmark legible against the dark
   admin header background. Revert when the legacy logo comes back. */
.admin .header-wordmark { color: #ffffff !important; }

#header-logo {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-right: 24px;
  position: relative;
}

.header-logo-title {
  margin: 0;
  font-size: 20px;
  font-weight: 600;
  color: #212529;
}

.header-logo-image {
  height: 42px;
  width: auto;
  display: block;
}

.header-logo-subtitle {
  color: #6c757d;
  font-size: 14px;
}

.maintenance-spinner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  color: #007bff;
}

.spinner {
  width: 20px;
  height: 20px;
  border: 2px solid #e3f2fd;
  border-top: 2px solid #007bff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.maintenance-spinner span {
  font-size: 0.9rem;
  font-weight: 500;
}

.header-logo-badge {
  color: #007bff;
  font-size: 11px;
  font-weight: 500;
  background: #e7f3ff;
  padding: 2px 6px;
  border-radius: 3px;
  border: 1px solid #b3d9ff;
}

.header-logo-badge-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.header-flow-toggle {
  border: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.header-flow-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 160px;
  white-space: nowrap;
  background: #fff;
  border: 1px solid #dee2e6;
  border-radius: 10px;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.12);
  padding: 6px;
  z-index: 40;
}

.header-flow-menu-item {
  width: 100%;
  justify-content: flex-start;
  background: transparent;
  border: none;
  color: #212529;
  padding: 8px 10px;
  border-radius: 8px;
  font-size: 13px;
}

.header-flow-menu-item:hover {
  background: #f1f3f5;
}

/* â”€â”€â”€ Progress Steps â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

#progress-steps {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.progress-step {
  display: flex;
  align-items: center;
  padding: 8px 12px;
  border-radius: 6px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
  position: relative;
}

.progress-step.completed {
  background: #d4edda;
  color: #155724;
}

.progress-step.active {
  background: #007bff;
  color: white;
}

.progress-step.pending {
  background: #f8f9fa;
  color: #6c757d;
  cursor: not-allowed;
}

.progress-step:hover:not(.pending) {
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.progress-step-spacer {
  width: 18px;
  height: 1px;
  background: #dee2e6;
  margin: 0 6px;
}

.progress-step.clickable {
  cursor: pointer;
}

.progress-step.blocked {
  cursor: not-allowed;
}

.progress-step-active-dot {
  width: 8px;
  height: 8px;
  background: currentColor;
  border-radius: 50%;
}

/* â”€â”€â”€ Panel Buttons (right side of header) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.panel-buttons {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-right: 60px;
}

.panel-button {
  position: relative;
  align-items: center;
  display: flex;
  padding: 8px 12px;
  font-size: 14px;
  font-weight: 500;
  border: 1px solid #dee2e6;
  border-radius: 6px;
  cursor: pointer;
  width: 44px;
  height: 36px;
  transition: width 0.25s ease-out, filter 0.35s ease;
  box-shadow: rgba(0, 0, 0, 0.1) 0px 2px 4px;
  background-color: white;
  justify-content: center;
}

.panel-button.hasCrown {
  width: 55px;
}

.panel-button.hasCrown .fa-crown {
  margin-left: 3px;
}

.panel-button .fa-solid,
.user-menu .fa-solid {
  color: #666;
}

.panel-button:hover,
.panel-button:focus-visible {
  width: 120px;
  gap: 5px;
  justify-content: flex-start;
  filter: brightness(90%) contrast(105%);
}

.panel-button.hasCrown:hover,
.panel-button.hasCrown:focus-visible {
  width: 135px;
}

.panel-button span:not(.panel-button-count) {
  white-space: nowrap;
  opacity: 0;
  transform: translateX(-10px);
  transition: opacity 0.3s ease, transform 0.3s ease;
  width: 0;
  overflow: hidden;
}

.panel-button-count {
  line-height: 22px;
  position: absolute;
  top: -6px;
  right: -6px;
  background-color: #2c6cd5;
  color: #fff;
  border-radius: 50%;
  width: 24px;
  height: 24px;
  font-size: 10px;
  font-weight: 700;
  border: 2px solid white;
  opacity: 0.9;
  text-align: center;
}

.panel-button:hover span:not(.panel-button-count),
.panel-button:focus-visible span:not(.panel-button-count) {
  opacity: 1;
  transform: translateX(0);
  width: auto;
}

/* â”€â”€â”€ User Menu â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.user-menu {
  position: absolute;
  right: 20px;
  display: inline-flex;
  align-items: center;
}

.user-menu .icon-button {
  width: 46px;
  height: 46px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.user-menu .icon-button.btn-sm {
  width: 40px;
  height: 40px;
}

.user-menu .icon-button div {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.user-menu-dropdown {
  position: absolute;
  top: 50px;
  right: 0;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  min-width: 200px;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
  padding: 8px;
  z-index: 20;
}

.user-menu-dropdown .btn {
  display: flex;
  width: 100%;
  gap: 8px;
  margin-top: 6px;
  text-align: left;
}

.user-menu-username {
  color: #374151;
  padding: 6px;
  margin-bottom: 8px;
  border-bottom: 1px solid #f1f3f5;
  word-break: break-word;
}

.user-menu-identity-row {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.user-menu-tenant-name {
  display: block;
  margin-top: 4px;
  color: #6b7280;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.25;
}

.admin-badge {
  margin-left: 6px;
  padding: 1px 6px;
  font-size: 10px;
  font-weight: 700;
  border-radius: 8px;
  vertical-align: middle;
  display: inline-flex;
  align-items: center;
  line-height: 1.2;
}

.user-menu-logout {
  width: 100%;
}

.user-menu-section { border-top:1px solid #e2e8f0; margin-top:4px; padding-top:4px; }
.user-menu-section-label { font-size:10.5px; font-weight:800; letter-spacing:.5px; color:#94a3b8;
  text-transform:uppercase; padding:8px 14px 4px; }
.user-menu-hint { font-size:11px; color:#94a3b8; padding:2px 14px 8px; }

.user-menu-account-row {
  display: flex;
  align-items: stretch;
  width: 100%;
  border-left: solid 4px transparent;
  border-radius: 0;
}

.user-menu-account-row.active {
  background: #e0f0ff;
  border-left: solid 4px #007bff;
  border-radius: 0;
}

.user-menu-account-switch {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  border: none;
  background: transparent;
  text-align: left;
  cursor: pointer;
  padding: 8px 8px 8px 10px;
  font-family: inherit;
  font-size: 13px;
  color: #212529;
}

.user-menu-account-switch[aria-current="true"] {
  cursor: default;
}

.user-menu-account-row.active .user-menu-account-name {
  font-weight: 700;
}

.user-menu-provider-line {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 2px;
  font-size: 11px;
  color: #64748b;
}

.user-menu-provider-status {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  white-space: nowrap;
}

.user-menu-provider-status.ok i {
  color: #16a34a;
}

.user-menu-provider-status.missing i {
  color: #dc2626;
}

.user-menu-provider-dot {
  color: #94a3b8;
}

.user-menu-account-settings {
  flex: 0 0 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  color: #64748b;
  cursor: pointer;
  padding: 0;
}

.user-menu-account-settings:hover {
  background: #e2e8f0;
  color: #1a73e8;
}

.avatar-upload-container {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 16px;
}

.avatar-preview {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  border: 1px solid #dee2e6;
  background: #f8f9fa center/cover no-repeat;
  flex: 0 0 auto;
}

/* â”€â”€â”€ Buttons â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.btn {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.35s ease;
}

.btn:hover {
  filter: brightness(90%) contrast(105%);
}

.btn-sm {
  padding: 4px 6px !important;
  font-size: unset;
}

.btn-primary {
  background: #007bff;
  color: white;
}

.btn-primary:hover:not(:disabled) {
  background: #0056b3;
}

.btn-secondary {
  background: #6c757d;
  color: white;
}

.btn-secondary:hover:not(:disabled) {
  background: #545b62;
}

.btn-outline {
  border: solid 1px #ccc;
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn.btn-round {
  border-radius: 50%;
}

/* Segmented button group â€” joins adjacent .btn into one control
   (e.g. "+ Local Files" + "N recently uploaded"). */
.btn-group {
  display: inline-flex;
  align-items: stretch;
}
.btn-group > .btn {
  border-radius: 0;
}
.btn-group > .btn:first-child {
  border-top-left-radius: 4px;
  border-bottom-left-radius: 4px;
}
.btn-group > .btn:last-child {
  border-top-right-radius: 4px;
  border-bottom-right-radius: 4px;
}
.btn-group > .btn:not(:first-child) {
  margin-left: -1px;
}
.btn-group > .btn:hover:not(:disabled) {
  position: relative;
  z-index: 1;
}

/* â”€â”€â”€ Flow Canvas â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.flow-canvas {
  flex: 1;
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-behavior: smooth;
  scroll-snap-type: x mandatory;
  padding: 24px;
  gap: 24px;
  /* Allow programmatic scroll without CSS override */
  -webkit-overflow-scrolling: touch;
}

/* Workflow Mode Toggle */
.workflow-mode-toggle-container {
  position: fixed;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  background: #14161a;
  border: 1px solid #2b3038;
  border-radius: 20px 20px 0 0;
  box-shadow: 0 8px 20px rgba(0,0,0,0.45);
  z-index: 1050;
}

.workflow-mode-toggle {
  border: none;
  background: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font: inherit;
  padding: 8px 20px;
  border-radius: 6px;
  transition: background-color 0.2s ease;
  color: #e6f6ff;
  height: 36px;
}

.workflow-mode-toggle:hover {
  background: rgba(255,255,255,0.06);
}

.workflow-mode-label {
  font-size: 14px;
  font-weight: 500;
  transition: color 0.2s ease, font-weight 0.2s ease;
  white-space: nowrap;
  color: #bfe7ff;
}

.workflow-mode-label.active {
  font-weight: 600;
  color: #7dd3fc;
}

.workflow-mode-switch-track {
  width: 40px;
  height: 20px;
  border-radius: 999px;
  background: #2b3038;
  border: 1px solid #3a414c;
  position: relative;
  transition: background-color 0.2s ease, border-color 0.2s ease;
}

.workflow-mode-switch-thumb {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #f8fafc;
  position: absolute;
  top: 1px;
  left: 1px;
  transition: transform 0.2s ease, background-color 0.2s ease;
}

/* Automated mode active state */
.workFlow-mode .workflow-mode-switch-track {
  background: #0f2a2d;
  border-color: #1e3a3f;
}

.workFlow-mode .workflow-mode-switch-thumb {
  background: #22d3ee;
  transform: translateX(20px);
}

body.workFlow-mode #root {
  --workflow-border-angle: 0deg;
  box-sizing: border-box;
  min-height: 100vh;
  overflow: hidden;
  position: relative;
}

@property --workflow-border-angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

body.workFlow-mode #root::before {
  animation: workflow-mode-border-angle 8s linear infinite;
  background: conic-gradient(
    from var(--workflow-border-angle),
    red,
    #ff7f00,
    #ff0,
    #0f0,
    #00f,
    indigo,
    #9400d3,
    red
  );
  content: "";
  inset: 0;
  pointer-events: none;
  position: absolute;
}

body.workFlow-mode .app {
  background: #c9ccd0;
  position: relative;
  z-index: 1;
}

body.workFlow-mode .app.flow-create {
  background: #f8f9fa;
  border-radius: 15px;
  box-shadow: inset 1px 1px 10px 10px #ccc;
  height: calc(100vh - 74px);
  margin: 8px;
}

body.workFlow-mode .app.flow-create .progress-header {
  top: 7px;
  width: calc(100% - 16px);
  border-radius: 15px 15px 0 0;
}

@keyframes workflow-mode-border-angle {
  from {
    --workflow-border-angle: 0deg;
  }
  to {
    --workflow-border-angle: 360deg;
  }
}

.workflow-mode-badge {
  position: absolute;
  top: -2px;
  right: -2px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: #22d3ee;
  border: 2px solid #14161a;
  animation: pulse 2s infinite;
}

.workflows-panel-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 16px 12px;
}

.workflows-table th,
.workflows-table td {
  vertical-align: top;
}

.workflow-expand-button {
  align-items: center;
  background: transparent;
  border: 0;
  color: #888;
  cursor: pointer;
  display: inline-flex;
  height: 24px;
  justify-content: center;
  padding: 0;
  width: 24px;
}

.muted-small {
  color: #6c757d;
  font-size: 11px;
  line-height: 1.35;
}

.workflow-type-badge {
  display: inline-flex;
  align-items: center;
  border-radius: 999px;
  padding: 2px 8px;
  font-size: 10px;
  font-weight: 700;
  line-height: 1.4;
  white-space: nowrap;
}

.workflow-type-badge--upload {
  background: #2c7be5;
  color: #fff;
}

.workflow-status-pill {
  border: 1px solid #cbd5e1;
  border-radius: 999px;
  background: #f8fafc;
  color: #475569;
  cursor: pointer;
  font: inherit;
  font-size: 11px;
  font-weight: 700;
  padding: 2px 8px;
}

.workflow-status-pill--active {
  border-color: #86efac;
  background: #dcfce7;
  color: #166534;
}

.workflow-row-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.workflow-runs-table {
  display: grid;
  gap: 8px;
}

.workflow-detail {
  display: grid;
  gap: 14px;
}

.workflow-detail-section {
  display: grid;
  gap: 8px;
}

.workflow-detail-section-header {
  align-items: center;
  display: flex;
  gap: 8px;
  justify-content: space-between;
}

.workflow-detail-section-header h4 {
  font-size: 13px;
  margin: 0;
}

.workflow-detail-header-actions {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: flex-end;
}

.workflow-config-list {
  margin: 0;
  padding-left: 18px;
}

.workflow-config-list li {
  font-size: 12px;
  line-height: 1.55;
}

.workflow-config-form {
  align-items: end;
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}

.workflow-config-form label,
.workflow-file-type-field {
  color: #555;
  display: grid;
  font-size: 12px;
  gap: 4px;
}

.workflow-inline-field {
  align-items: center;
  display: flex;
  gap: 6px;
}

.workflow-inline-field input {
  max-width: 90px;
}

.workflow-file-type-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.workflow-config-folder-item {
  align-items: center;
  display: flex;
  gap: 6px;
}

.workflow-aspect-ratio-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.workflow-aspect-ratio-badge {
  align-items: center;
  background: #fff;
  border: 1px solid #cbd5e1;
  border-radius: 999px;
  color: #334155;
  cursor: pointer;
  display: inline-flex;
  font-size: 12px;
  font-weight: 700;
  gap: 6px;
  line-height: 1.2;
  padding: 6px 10px;
}

.workflow-aspect-ratio-badge:hover {
  border-color: #60a5fa;
  color: #1d4ed8;
}

.workflow-aspect-ratio-badge--active {
  background: #eff6ff;
  border-color: #2563eb;
  color: #1d4ed8;
}

.workflow-checkbox-field {
  align-items: center;
  display: flex !important;
  gap: 6px !important;
}

.workflow-config-actions {
  align-items: center;
  display: flex;
  gap: 8px;
}

.workflow-past-runs table {
  margin-top: 0;
}

.workflows-panel .table-row-selected {
  background: rgba(40, 167, 69, 0.1);
}

.workflow-editor-card {
  border-top: 1px solid rgba(15, 23, 42, 0.12);
  display: grid;
  gap: 10px;
  margin: 0 16px 16px;
  padding-top: 12px;
}

.workflow-files-rules {
  display: grid;
  gap: 16px;
}

.workflow-files-rules__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

.workflow-files-rules__grid--three {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.workflow-files-inline-filters {
  align-items: end;
  display: grid;
  gap: 14px;
  grid-template-columns: minmax(260px, 1fr) minmax(260px, auto);
}

.workflow-files-inline-filter-field {
  align-items: center;
  display: grid;
  gap: 8px;
  grid-template-columns: max-content minmax(120px, 1fr) max-content;
  min-width: 0;
}

.workflow-files-inline-filter-field:first-child {
  grid-template-columns: max-content minmax(180px, 1fr);
}

.workflow-files-inline-filter-field > span:first-child {
  color: #334155;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}

.workflow-files-rules .form-field {
  display: grid;
  gap: 6px;
  min-width: 0;
}

.workflow-files-rules .form-field > span {
  color: #334155;
  font-size: 12px;
  font-weight: 700;
}

.workflow-files-rules__types {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.workflow-file-type-chip {
  align-items: center;
  background: #fff;
  border: 1px solid #cbd5e1;
  border-radius: 999px;
  color: #334155;
  cursor: pointer;
  display: inline-flex;
  font-size: 13px;
  font-weight: 700;
  gap: 8px;
  padding: 8px 13px;
}

.workflow-file-type-chip:hover {
  border-color: #60a5fa;
  color: #1d4ed8;
}

.workflow-file-type-chip--selected {
  background: #eff6ff;
  border-color: #2563eb;
  color: #1d4ed8;
}

.workflow-files-summary,
.workflow-preview-card {
  align-items: flex-start;
  border-radius: 8px;
  color: #475569;
  display: flex;
  gap: 10px;
  padding: 10px 12px;
}

.workflow-files-summary {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
}

.workflow-preview-card {
  background: #fffbe6;
  border: 1px solid #f1c40f;
  display: flex;
  font-size: 12px;
  line-height: 1.45;
  flex-direction: column;
}

.upload-recap-summary {
  color: #475569;
  font-size: 13px;
  line-height: 1.5;
  margin: 10px 0;
}

.workflow-preview-file-list {
  display: grid;
  gap: 4px;
  list-style: none;
  margin: 2px 0 0;
  padding: 0;
}

.workflow-preview-section {
  display: grid;
  gap: 4px;
  margin-top: 8px;
}

.workflow-preview-section-title {
  color: #334155;
  font-size: 12px;
  font-weight: 700;
}

.workflow-preview-file-row {
  align-items: center;
  display: grid;
  gap: 8px;
  grid-template-columns: 16px minmax(0, 1fr);
  min-width: 0;
}

.workflow-preview-file-row > i {
  color: #334155;
  font-size: 13px;
  justify-self: center;
}

.workflow-preview-file-name {
  min-width: 0;
}

/* Long, space-less filenames must wrap, not push a horizontal scrollbar
   into the recap columns (which only scroll vertically). */
.workflow-preview-file-list file {
  word-break: break-all;
}

.workflow-preview-file-reason {
  grid-column: 2;
  min-width: 0;
  font-size: 12px;
  line-height: 1.35;
  overflow-wrap: anywhere;
}

.workflow-preview-file-row--selectable {
  grid-template-columns: 16px 16px minmax(0, 1fr);
}

.workflow-preview-file-reason--error {
  color: #c92a2a;
}

.workflow-preview-file-row--dropped {
  opacity: 0.62;
}

/* â”€â”€â”€ Upload-only recap: two full-height, independently-scrolling columns â”€â”€ */
/* !important overrides the broad `.step-body > *:not(.data-table)` rule that
   forces flex-shrink:0 on step children â€” the columns must fill the body. */
.upload-recap-columns {
  display: flex;
  gap: 16px;
  flex: 1 1 auto !important;
  min-height: 0;
}

.upload-recap-col {
  flex: 1 1 0;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  background: #fff;
  overflow: hidden;
}

.upload-recap-col-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border-bottom: 1px solid #e9ecef;
  background: #f8f9fa;
  border-radius: 8px 8px 0 0;
  font-size: 13px;
  font-weight: 700;
  color: #334155;
}

.upload-recap-col-header > i {
  color: #5f6368;
}

.upload-recap-col-count {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
  color: #5f6368;
  font-weight: 600;
}

.upload-recap-col-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 10px 14px;
}

/* One light-yellow card per skip reason, stacked vertically. */
.upload-recap-skip-group {
  margin-bottom: 10px;
}

.upload-recap-skip-group:last-child {
  margin-bottom: 0;
}

.upload-recap-skip-group > .workflow-preview-file-reason {
  font-weight: 700;
  margin-bottom: 2px;
}

.upload-button-icon {
  margin-right: 6px;
}

.workflow-simulation-modal {
  max-width: 520px;
  width: min(520px, calc(100vw - 32px));
}

.workflow-simulation-file-list {
  display: grid;
  gap: 8px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.workflow-simulation-file-row {
  align-items: center;
  display: grid;
  gap: 8px;
  grid-template-columns: 18px minmax(0, 1fr);
}

.workflow-simulation-file-row > i {
  color: #334155;
  font-size: 14px;
  justify-self: center;
}

.workflow-trigger-rules {
  display: grid;
  gap: 16px;
}

.workflow-trigger-form {
  align-items: start;
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.workflow-trigger-name-field {
  grid-column: 1 / -1;
}

.workflow-trigger-schedule-row {
  align-items: end;
  display: grid;
  gap: 14px;
  grid-column: 1 / -1;
  grid-template-columns: minmax(160px, 220px) minmax(190px, 1fr);
}

.workflow-trigger-schedule-row .form-field,
.workflow-trigger-name-field {
  display: grid;
  gap: 6px;
}

.workflow-trigger-schedule-row .form-field > span,
.workflow-trigger-name-field > span {
  color: #334155;
  font-size: 12px;
  font-weight: 700;
}

.workflow-trigger-checkboxes {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 18px;
  grid-column: 1 / -1;
}

.workflow-checkbox-row {
  align-items: center;
  color: #334155;
  display: inline-flex;
  font-size: 13px;
  font-weight: 700;
  gap: 7px;
}

@media (max-width: 900px) {
  .workflow-files-inline-filters,
  .workflow-files-rules__grid,
  .workflow-files-rules__grid--three {
    grid-template-columns: 1fr;
  }

  .workflow-files-inline-filter-field,
  .workflow-files-inline-filter-field:first-child {
    align-items: start;
    grid-template-columns: 1fr;
  }

  .workflow-trigger-form,
  .workflow-trigger-schedule-row {
    grid-template-columns: 1fr;
  }
}

.flow-canvas::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

.flow-canvas::-webkit-scrollbar-thumb {
  background: #555;
  border-radius: 10px;
}

.flow-canvas::-webkit-scrollbar-thumb:hover {
  background: #333;
}

/* â”€â”€â”€ Step Column (infinite-canvas column wrapper) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

/*
 * Each revealed step occupies its own column in the horizontal canvas.
 * The inner .wizard-step card fills the column completely.
 * Matches Meta's .step-column pattern from FlowCanvas / StepColumn.tsx.
 */
.step-column {
  /* Flex item of .flow-canvas: shrink 0, else sibling columns overflow the
     row and the browser shrinks every one down to min-width. */
  flex: 0 0 70%;
  min-width: 1100px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  display: flex;
  flex-direction: column;
  min-height: 200px;
  max-height: calc(100vh - 130px);
  opacity: 0.7;
  transition: opacity 0.3s ease;
  scroll-snap-align: center;
  overflow: hidden;
}

.step-column.active {
  opacity: 1 !important;
  box-shadow: 0 4px 16px rgba(0, 123, 255, 0.2);
  border: 2px solid #007bff;
}

.flow-canvas .step-column:not(.active) {
  opacity: .5 !important;
  transform: scale(0.9);
}

.flow-monitor .step-column {
  max-height: calc(100vh - 80px);
}

.step-column.completed {
}

/* (`.wizard-step` middle container removed â€” step components now emit
 *  .step-header / .step-body / .step-footer as direct children of
 *  .step-column, matching MetaAssetManager's StepColumn structure.)
 */

/* â”€â”€â”€ Flow Landing (Home page) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.flow-landing {
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.flow-landing-inner {
  display: flex;
  gap: 32px;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
}

/* â”€â”€â”€ Flow CTA Buttons (round home buttons) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.flow-cta {
  width: 220px;
  height: 220px;
  border-radius: 999px;
  border: 2px solid #dee2e6;
  background: #ffffff;
  color: #212529;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 24px;
  text-align: center;
  cursor: pointer;
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
  font-family: inherit;
  font-size: inherit;
  box-sizing: border-box;
}

.flow-cta:hover:not(:disabled) {
  transform: translateY(-4px);
  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15);
  border-color: #007bff;
}

.flow-cta:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.flow-cta-title {
  font-size: 20px;
  font-weight: 700;
}

.flow-cta-desc {
  color: #6c757d;
  line-height: 1.4;
  font-size: 12px;
}

/* Badge shown on disabled CTA */
.flow-cta-badge {
  display: inline-block;
  margin-top: 4px;
  font-size: 10px;
  font-weight: 600;
  color: #6c757d;
  background: #f1f3f5;
  border: 1px solid #dee2e6;
  border-radius: 999px;
  padding: 2px 8px;
  letter-spacing: 0.03em;
}

/* â”€â”€â”€ App root wrapper â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

#root > * {
  /* Ensure the outermost app element accounts for the fixed header */
}

/* â”€â”€â”€ Global base reset for all form elements â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

button, input, select, textarea {
  font-family: 'Manrope', sans-serif;
}

/* â”€â”€â”€ Form controls â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.form-group {
  margin-bottom: 16px;
}

.form-sm {
  padding: 4px 6px !important;
  font-size: unset;
}

.form-label {
  display: block;
  margin-bottom: 6px;
  font-weight: 500;
  font-size: 14px;
  color: #495057;
}

.form-control {
  flex: 1;
  padding: 8px 12px;
  border: 1px solid #ced4da;
  border-radius: 4px;
  background: white;
  /* Include padding+border in the width so `width:100%` inputs (e.g. the stacked
     Notifications fields) don't overflow their container. */
  box-sizing: border-box;
}

/* Native <select> — swap the OS-default arrow for a consistent 12px chevron so
   it matches the custom TargetSelect dropdown (same size, colour, position)
   across the app instead of each browser rendering its own. */
select.form-control {
  appearance: none;
  -webkit-appearance: none;
  background-color: #fff;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512' fill='%236c757d'%3E%3Cpath d='M201.4 374.6c12.5 12.5 32.8 12.5 45.3 0l160-160c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L224 306.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l160 160z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 9px;
  padding-right: 30px;
}

/* `.form-sm`'s `padding: … !important` beats the rule above, leaving no
   room for the chevron — compact selects rendered with no arrow at all. */
select.form-control.form-sm {
  padding-right: 30px !important;
}

.form-control:focus {
  outline: none;
  border-color: #007bff;
  box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}

/* â”€â”€â”€ Setup wizard layout â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.setup-flow {
  width: 75vw;
  min-width: 680px;
  max-width: 1200px;
  margin: 24px auto;
  padding: 24px;
  background: white;
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
}

.setup-header {
  display: grid;
  grid-template-columns: 1fr auto auto;
  grid-template-areas:
    "title button dashboard"
    "tagline tagline tagline";
  align-items: center;
  gap: 8px 16px;
  margin-bottom: 16px;
}
.setup-header h1 { grid-area: title; margin: 0; }
.setup-header p  { grid-area: tagline; margin: 0; }

.setup-close-button {
  grid-area: dashboard;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}

/* â”€â”€â”€ <time> chip â€” Meta port â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
/* formatTimestamp() wraps the UTC label in <time dateTime=ISO>; this rule
 * gives that wrapper Meta's monospace-ish chip appearance so dates pop
 * out of surrounding text consistently across surfaces. */
time {
  background-color: #e9ecef;
  color: #495057;
  padding: 2px 4px;
  border-radius: 4px;
  font-size: inherit;
  font-weight: 600;
}

/* â”€â”€â”€ Target badge (3-letter product chip) â€” Meta port â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
/* Same dimensions + typography as Meta's .target-badge so the JobsPanel
 * column lines up identically. The colour is set inline by TargetBadge
 * via stringToHslColor on the target's stable id-or-name key. */
.target-badge {
  width: 30px;
  height: 30px;
  border-radius: 6px;
  border: 1px solid #ced4da;
  background: #f8f9fa;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  flex: 0 0 auto;
}

.setup-layout {
  display: grid;
  min-height: 400px;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: 20px;
  align-items: start;
}

.setup-nav {
  position: sticky;
  top: 88px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px;
  border: 1px solid #e9ecef;
  border-radius: 10px;
  background: #f8f9fa;
}

.setup-nav-link {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  text-align: left;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: #495057;
  padding: 9px 10px;
  font-size: 13px;
  cursor: pointer;
  text-decoration: none;
}

.setup-nav-link:hover {
  background: #eef2f6;
}

.setup-nav-link.active {
  border-left: solid 4px #0d6efd;
  color: #0d6efd;
  border-radius: unset;
  font-weight: 600;
  transform: translateX(-12px);
  width: 100%;
  /*background: #e7f1fb;*/
}

/* Per-step status icon at the start of each setup-nav link.
   Direct port of unityCreativeCopilot App.css Â§setup-nav. Driven by
   completion booleans computed in SetupFlow.tsx + a spinner when
   the relevant API call is in flight. */
.setup-nav-icon {
  width: 12px;
  font-size: 9px;
  margin-right: 6px;
}

.setup-nav-icon.complete {
  color: #198754;
}

.setup-nav-icon.incomplete {
  color: #6c757d;
}

.setup-content {
  min-width: 0;
}

.setup-step {
  border: 1px solid #e9ecef;
  border-radius: 10px;
  padding: 20px;
  background: #fdfdfd;
}

.setup-step.complete {
  border-color: #28a745;
}

.setup-step-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}

.setup-step-header h2 {
  margin: 0;
  font-size: 18px;
}

.setup-step p {
  /* The description owns its own bottom gap so following content doesn't have
     to add ad-hoc margin-top (which was inconsistent step-to-step). */
  margin: 0 0 12px 0;
  color: #6c757d;
  font-size: 14px;
}

/* Readonly field row: value + Edit button, left-aligned with a gap so the
   Edit sits just after the value (the base rule was missing, so they had no
   gap; some instances already inline justify-content/gap assuming flex). */
.setup-field-readonly {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
}

/* Label owns a small gap below it, so it doesn't sit flush on the field
   value / input beneath. */
.setup-field-label {
  margin-bottom: 6px;
}

/* Existing-mappings table: scroll horizontally rather than break the layout,
   and act as a query container so the row actions can collapse to icon-only
   when the area is narrow. */
.setup-mappings-scroll {
  overflow-x: auto;
  container-type: inline-size;
}
@container (max-width: 560px) {
  .mapping-action-label {
    display: none;
  }
}

/* Step 2 app picker: the trigger is capped by its (fixed-width) column and
   truncates long app names, but the open dropdown grows to show them in full
   (same treatment as the side-panel Target/User filters). */
.setup-app-select .target-select-box__menu {
  right: auto;
  min-width: 100%;
  width: max-content;
  max-width: 360px;
}

.setup-substep {
  border-radius: 10px;
  padding: 20px;
  background: rgba(0, 0, 0, 0.03);
}

.setup-substep:not(:last-child) {
  margin-bottom: 20px;
}

.setup-step-header h3 {
  margin: 0;
  font-size: 16px;
}

.setup-substep .setup-step-header h3 {
  flex: 1;
}

.setup-extraction-target-grid {
  display: grid;
  grid-template-columns: minmax(260px, 0.95fr) minmax(0, 1.35fr);
  gap: 16px;
  align-items: start;
  margin-top: 10px;
}

.setup-extraction-panel {
  border: 1px solid #e9ecef;
  border-radius: 10px;
  padding: 14px;
  background: #fff;
  min-width: 0;
}

/* Per-target summary tile flips to a green border once the target
   has at least one saved rule (Step4FilenameProcessingSummary). */
.setup-extraction-panel.complete {
  border-color: #28a745;
}

.setup-extraction-status {
  margin-top: 4px;
  color: #6c757d;
  font-size: 13px;
}

.setup-extraction-status-error {
  color: #dc3545;
}

.setup-extraction-summary-loading {
  margin-top: 4px;
  color: #6c757d;
  font-size: 13px;
}

.setup-extraction-summary-mode {
  color: #495057;
  font-size: 13px;
  line-height: 1.5;
  margin-bottom: 6px;
}

/* Tick / empty ring sit in a fixed-width column so the feature lines align
   whether or not each is configured. */
.setup-extraction-covered,
.setup-extraction-uncovered {
  display: inline-block;
  width: 14px;
  text-align: center;
}

.setup-extraction-covered {
  color: #28a745;
}

.setup-extraction-uncovered {
  color: #adb5bd;
}

.setup-extraction-summary-line {
  color: #495057;
  font-size: 13px;
  line-height: 1.5;
}

.setup-extraction-summary-line + .setup-extraction-summary-line {
  margin-top: 4px;
}

.setup-extraction-summary-actions {
  margin-top: 10px;
  display: flex;
  align-items: end;
  gap: 10px;
  flex-wrap: wrap;
}

.setup-extraction-summary-error {
  margin-top: 12px;
}

.setup-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
}

.setup-actions-spread {
  justify-content: space-between;
}

/* Step nav footer (Skip / Continue / Finish) â€” lives OUTSIDE the .setup-step
   card and is right-aligned. */
.setup-step-footer {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  justify-content: flex-end;
  margin-top: 12px;
}

@media (max-width: 900px) {
  .setup-extraction-target-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 640px) {
  .setup-substep {
    padding: 16px;
  }
}

.setup-badge {
  padding: 4px 10px;
  border-radius: 999px;
  background: #f1f3f5;
  font-weight: 600;
  color: #495057;
}

.setup-badge.success {
  background: #d4edda;
  color: #155724;
}

.setup-muted {
  color: #6c757d;
  /*font-size: 13px;*/
  /*margin-top: 8px;*/
}

.setup-error {
  color: #c92a2a;
  margin-top: 8px;
  font-size: 13px;
}

/* Step 3 "How shall we group files into creative sets?" chips â€”
   verbatim port of google's `.agu-grouping-chip` palette. AppLovin's
   wizard uses `csu-` prefix; visuals must match google's. */
.csu-grouping-chips {
  display: flex; gap: 8px; flex-wrap: wrap;
  margin-bottom: 14px;
}
.csu-grouping-chip {
  border: 1px solid #d0d7de;
  background: white;
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 13px; font-weight: 500;
  cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  font-family: inherit;
  color: #212529;
}
.csu-grouping-chip:hover { border-color: #1a73e8; }
.csu-grouping-chip.is-selected {
  background: #e8f0fe;
  border-color: #1a73e8;
  color: #1a73e8;
  font-weight: 600;
}
.csu-grouping-chip--language.is-selected {
  background: #e9ecef;
  border-color: #6c757d;
  color: #495057;
}
.csu-grouping-chip--language.is-selected .csu-grouping-check {
  background: #6c757d;
  border-color: #6c757d;
}
.csu-grouping-chip--category.is-selected {
  background: #faf0fc;
  border-color: #c026d3;
  color: #c026d3;
}
.csu-grouping-chip--category.is-selected .csu-grouping-check {
  background: #c026d3;
  border-color: #c026d3;
}
.csu-grouping-chip--concept.is-selected {
  background: #fffbe6;
  border-color: #f1c40f;
  color: #b8860b;
}
.csu-grouping-chip--concept.is-selected .csu-grouping-check {
  background: #d4a90c;
  border-color: #d4a90c;
}
.csu-grouping-chip[disabled],
.csu-grouping-chip.is-disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.csu-grouping-chip[disabled]:hover,
.csu-grouping-chip.is-disabled:hover {
  border-color: #d0d7de;
}
.csu-grouping-check {
  width: 14px; height: 14px; border-radius: 50%;
  border: 1.5px solid #d0d7de;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 9px;
}
.csu-grouping-chip.is-selected .csu-grouping-check {
  border-color: #1a73e8;
  background: #1a73e8;
  color: white;
}

.reuse-kind-button-group {
  display: inline-flex;
  align-items: center;
  margin: 0 6px;
  vertical-align: middle;
}

.reuse-kind-button {
  border: 1px solid #c9d4e5;
  border-left: 0;
  background: #fff;
  color: #344054;
  padding: 4px 11px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.35;
  cursor: pointer;
}

.reuse-kind-button:first-child {
  border-left: 1px solid #c9d4e5;
  border-top-left-radius: 50px;
  border-bottom-left-radius: 50px;
}

.reuse-kind-button:last-child {
  border-top-right-radius: 50px;
  border-bottom-right-radius: 50px;
}

.reuse-kind-button:hover {
  background: #eef5ff;
}

.reuse-kind-button.is-selected {
  background: #1565c0;
  border-color: #1565c0;
  color: #fff;
}

/* One notification field: label, its description, the control, then a slot for
   a message. The description is grey body text rather than `alert alert-info` —
   a filled, coloured box has to mean something is happening, or the one that
   does gets lost among the ones that never change. */
.setup-field-list {
  display: grid;
  gap: 20px;
}

.setup-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.setup-field-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 600;
  color: #495057;
}

/* Scoped to `.setup-field` so it outranks `.setup-step p`, which is a class
   plus a type and would otherwise win every property here. */
.setup-field .setup-field-help {
  margin: -2px 0 2px;
  font-size: 12.5px;
  line-height: 1.5;
  color: #6c757d;
}

/* Sized for what it holds: a Slack id is eleven characters, not a paragraph.
   `flex: none` because `.form-control` carries `flex: 1`, which in this column
   container would stretch the input's HEIGHT rather than its width. */
.setup-field-input {
  flex: none;
  max-width: 320px;
  /* `.form-control` is content-box here (unlike the meta copilot, which resets
     globally), so without this the padding and border push the field to 346. */
  box-sizing: border-box;
}

.setup-field-input:disabled {
  background: #f8f9fa;
  cursor: not-allowed;
}

/* Amber, not red: notifications are optional, so a channel we cannot reach is
   worth telling someone about without dressing it up as a broken setup. */
.setup-delivery-warning {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 9px 12px;
  border: 1px solid #f0d9a8;
  border-radius: 6px;
  background: #fdf6e7;
  color: #7a4e0c;
  font-size: 13px;
  line-height: 1.5;
}

.setup-delivery-dot {
  flex: none;
  width: 7px;
  height: 7px;
  margin-top: 6px;
  border-radius: 50%;
  background: #d08700;
}

.setup-inline {
  display: flex;
  gap: 8px;
  flex: 1;
  min-width: 280px;
}

.setup-inline input {
  flex: 1;
  padding: 8px 10px;
  border-radius: 6px;
  border: 1px solid #ced4da;
  font-size: 13px;
}

.setup-table {
  margin-top: 12px;
  border: 1px solid #e2e2e2;
  border-radius: 10px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.setup-grid {
  display: grid;
  gap: 12px;
  align-items: center;
}

.setup-table-header {
  font-weight: 600;
  color: #3d3d3d;
  /* Own the gap BELOW (to the table), not above — a section header groups
     with the table under it. (Was margin-top:16, which pushed it down from
     the content above and left it stuck to the table below.) */
  margin-bottom: 12px;
}

/* â”€â”€â”€ Create-flow step layout â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.step-header {
  padding: 20px 24px;
  border-bottom: 1px solid #e9ecef;
  background: #f8f9fa;
  border-radius: 10px 10px 0 0;
  flex-shrink: 0;
  /* Sticky to match Meta â€” keeps the title pinned at the top of the
     step-column when the column itself happens to scroll vertically
     (rare in our horizontal-canvas layout, but matches one-to-one). */
  position: sticky;
  top: 0;
  z-index: 10;
  /* Clicking the header navigates to that step (StepColumn intercepts
     the click â€” see CreatePage.tsx#handleClick). The cursor cue is
     set on the *non-active* step only; the active step doesn't need
     it (you're already there). */
  cursor: pointer;
}
/* Status pill in the header â€” absolute-positioned in the top-right
   corner so it doesn't push the title or description. */
.step-status {
  position: absolute;
  top: 15px;
  right: 20px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.4px;
  padding: 3px 8px;
  border-radius: 4px;
  text-transform: uppercase;
}
.step-status.completed { background: #d4edda; color: #155724; }
.step-status.active    { background: #cce5ff; color: #0066cc; }
.step-status.pending   { background: #f1f3f5; color: #6c757d; }
/* Universal body-inner wrapper â€” every step body now contains
   <flex-col-min-h0> > <step-body-inner> > content, matching Meta. */
.step-body-inner,
.modal-inner {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
}
.step-body-inner.scrollable,
.scrollable {
  overflow-y: auto;
}
.step-column.active > .step-header {
  cursor: default;
}
.step-column:not(.active) .step-header:hover {
  background: #eef0f3;
}

.step-title {
  font-size: 18px;
  font-weight: 600;
  color: #212529;
  margin: 0 0 4px 0;
}

.step-description {
  font-size: 14px;
  color: #6c757d;
  margin: 0;
}

.step-body {
  flex: 1 1 auto;
  padding: 20px 24px;
  overflow: auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.step-footer {
  flex-shrink: 0;
  background: #f8f9fa;
  border-top: 1px solid #e9ecef;
  border-radius: 0 0 10px 10px;
  padding: 14px 24px;
  display: flex;
  gap: 8px;
  align-items: center;
}

/* â”€â”€â”€ Section label inside step â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.step-section-label {
  display: block;
  font-weight: 600;
  font-size: 13px;
  color: #495057;
  margin-bottom: 6px;
}

/* â”€â”€â”€ Data table (SelectedFilesTable etc.) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.data-table {
  width: 100%;
  border-collapse: collapse;
  /* Shared by 21 tables across the app, so it sets the rhythm everywhere --
     and it is the whole gap under a table that is followed by something
     carrying no margin of its own, like the rotations "Load 10 older". */
  margin-bottom: 12px;
}

.step-body .data-table {
  width: 100%;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  margin-bottom: 0 !important;
}

.data-table thead {
  position: sticky;
  top: 0;
  z-index: 10;
  background: #f8f9fa;
}

.step-body .data-table tbody {
}

.step-body > *:not(.data-table):not(.monitor-overview-step) {
  flex-shrink: 0;
  margin-bottom: 16px;
}

.step-body > *:last-child:not(.data-table) {
  margin-bottom: 0;
}

.step-body > .form-group,
.step-body > .error-panel {
  flex-shrink: 0;
}

.text-assets-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 16px;
}

@media (max-width: 900px) {
  .text-assets-grid {
    grid-template-columns: 1fr;
  }
}

.data-table th {
  background: #f8f9fa;
  padding: 6px 8px;
  text-align: left;
  font-weight: 600;
  color: #495057;
  border-bottom: 2px solid #dee2e6;
  white-space: nowrap;
  vertical-align: top;
}

.data-table td {
  padding: 6px 8px;
  border-bottom: 1px solid #dee2e6;
  line-height: 1.3;
  color: #212529;
}

.data-table-wrap {
  border: 1px solid #dee2e6;
  border-radius: 6px;
  overflow: hidden;
}

/* Inside a flex .step-body, the wrap + inner table-wrapper take all
 * remaining vertical space and only the table BODY scrolls â€” keeps
 * the wizard's filter row + footer pinned. Mirrors Meta's pattern
 * (.step-body .data-table { flex:1; min-height:0; overflow-y:auto }). */
.step-body .data-table-wrap {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.step-body .data-table-wrap .table-wrapper {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}

/* Step bodies that host a data table as their main content (e.g.
 * Step 2 Campaigns) suppress their own scroll so ONLY the inner
 * .table-wrapper scrolls. Without this the outer body and the inner
 * wrapper compete: the body grows past the viewport, the inner
 * wrapper's flex bound never bites, and the user scrolls the toolbar
 * out of view. Other steps (Step 3 text, Step 4 review) keep the
 * default body-scroll because they have no table to host. */
.step-body.step-body--table-host {
  overflow: hidden;
}

/* Inactive entities (PAUSED / REMOVED campaigns, ad groups, etc.).
 * Verbatim from Meta's App.css â€” used in the campaign-selection
 * table to mute paused/removed rows without hiding them. */
.off {
  /*color: #999;*/
  opacity: 0.5;
}
/*tr.off td {
  opacity: 0.3;
}*/

/* Test campaigns in the Step-2 selection table: gray diagonal-stripe
 * background + a floating "plug" badge next to the checkbox so they
 * stand out as throwaway test containers. */
.data-table tr.test td {
  background-image: repeating-linear-gradient(
    45deg,
    rgba(108, 117, 125, 0.10),
    rgba(108, 117, 125, 0.10) 6px,
    transparent 6px,
    transparent 12px
  );
}
.test-campaign-icon {
  position: absolute;
  top: 2px;
  right: 2px;
  font-size: 9px;
  color: #6c757d;
  pointer-events: none;
}

/* â”€â”€â”€ Auth health banner â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.auth-health-banner {
  background: #fff3cd;
  border-bottom: 1px solid #ffc107;
  padding: 10px 24px;
  font-size: 13px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.auth-health-banner-item {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* â”€â”€â”€ Jobs panel (Meta-ported, yellow background, resizable) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

/* Panel shell. The root <section> uses `.side-panel.jobs-panel` so it
   participates in the parent `.panels` flex container (declared in
   queues-panel.css). The Jobs panel only needs to add the yellow
   background that Meta uses to distinguish it from the Queues panel. */
.jobs-panel {
  background: #FAF3E0;             /* Meta's exact yellow: #FAF3E0 */
  min-width: 320px;
}

/* (Legacy `.jp-drag-handle` kept for any callers still using it; the
   root resize handle now uses `.side-panel-drag-handle` which is
   defined in queues-panel.css and shared by both panels.) */
.jp-drag-handle {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 8px;
  cursor: col-resize;
  z-index: 1002;
  transition: background-color ease 0.2s;
}
.jp-drag-handle:hover {
  background: inherit;
  filter: brightness(0.8);
}

/* Header â€” matches Meta's .side-panel-header */
.jp-header {
  padding: 10px 20px;
  border-bottom: 1px solid #e9ecef;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
}

/* Narrow window: the AppHeader's step chips wrap and it takes a third of
   the height it does when wide, so the panel below has that much less to
   work with. Its own header gives some back — the title and the close
   button are the same size either way, only the air around them
   changes. */
@media (max-width: 900px) {
  .jp-header {
    padding-top: 6px;
    padding-bottom: 6px;
  }
}

/* Title â€” matches Meta's .side-panel-title */
.jp-title {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #495057;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Tabs â€” matches Meta's .side-panel-tabs */
.jp-tabs {
  display: flex;
  border-bottom: 1px solid #999;
  gap: 2px;
  padding: 0 16px;
  flex-shrink: 0;
}

.jp-tab {
  flex: 1;
  padding: 12px 10px;
  border: none;
  background: transparent;
  color: #6c757d;
  font-weight: 500;
  font-size: 13px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border-bottom: 3px solid transparent;
  transition: color 0.15s, border-bottom-color 0.15s;
}

.jp-tab--active {
  color: #998800;
  border-bottom-color: #ccbb00;
  font-weight: 600;
}

/* Body â€” matches Meta's .side-panel-body */
.jp-body {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

.jp-body-inner {
  padding: 16px;
}

/* Empty state */
.jp-empty {
  color: #6c757d;
  font-style: italic;
  font-size: 13px;
  margin: 0;
}

/* Footer â€” matches Meta's panel footer */
.jp-footer {
  padding: 12px 16px;
  border-top: 1px solid #e9ecef;
  background: rgba(255, 255, 255, 0.6);
  flex-shrink: 0;
  font-size: 12px;
  color: #6c757d;
  text-align: center;
}

/* Job card */
.jp-card {
  border: 1px solid #e5d9a0;
  border-radius: 6px;
  padding: 0;
  margin-bottom: 10px;
  font-size: 13px;
  background: rgba(255, 255, 255, 0.65);
  overflow: hidden;
}

.jp-card-summary {
  cursor: pointer;
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 8px 12px;
  list-style: none;
  user-select: none;
}
.jp-card-summary::-webkit-details-marker { display: none; }

.jp-card-id {
  font-size: 11px;
  color: #888;
  font-family: monospace;
}

.jp-card-title {
  flex: 1;
  font-weight: 500;
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.jp-card-time {
  font-size: 12px;
  color: #777;
  white-space: nowrap;
}

/* Card body (shown when <details> open) */
.jp-card-body {
  border-top: 1px solid #e5d9a0;
  padding: 8px 12px;
}

/* Status bar inside card */
.jp-card-status-bar {
  display: flex;
  align-items: center;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 600;
  color: #fff;
  margin-bottom: 8px;
}

.jp-card-no-steps {
  color: #777;
  font-size: 12px;
  margin: 0;
}

/* Steps list */
.jp-steps-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* â”€â”€â”€ Generic step circles + File Transfer Progress (Meta port) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
/* Faithful port of Meta Creative Copilot's job-detail Progress section.
 * Source: ProductionMetaUploader/presentation/web/src/components/ui/
 *         JobsPanel.tsx + App.css. Class names preserved verbatim so
 *         future ports can copy markup unchanged. */

.job-step-indicator {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
}

ul.upload-progress {
  margin: 5px 0;
  padding: 0;
  font-size: 0.9em;
  list-style: none;
}

ul.upload-progress li {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 4px;
}

.upload-progress-label {
  flex: 1;
  min-width: 0;
  word-break: break-all;
}

.upload-progress-label.skipped {
  text-decoration: line-through;
}

.upload-progress-meta {
  display: block;
  margin-top: 2px;
  font-size: 0.85em;
  color: #6c757d;
}

.upload-progress-bars {
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: flex-end;
  /* One block height for both states, with the contents centred as a GROUP.
     Two 7px tracks against two 18px Reused badges made a reused row 40px where
     a transferring one was 18, and the list changed rhythm exactly where the
     reused rows began. Sizing each track's own slot instead would even the
     rows out but push the pair of bars apart. */
  min-height: 32px;
  justify-content: center;
}

.upload-progress-bar {
  display: inline-block;
  width: 70px;
  height: 7px;
  background: #e0e0e0;
  border-radius: 5px;
  overflow: hidden;
}

/* Group heading inside the transfer list. Not a row: no icon, no bars, and
   it must not pick up the flex layout the li rows use. */
ul.upload-progress li.upload-progress-group {
  display: block;
  margin: 10px 0 4px;
  padding-top: 6px;
  border-top: 1px solid #dee2e6;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: #6c757d;
}

.upload-progress-reused-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 70px;
  height: 14px;
  box-sizing: border-box;
  border: 1px solid #badbcc;
  border-radius: 4px;
  background: #d1e7dd;
  color: #0f5132;
  font-size: 10px;
  font-weight: 600;
  line-height: 1;
}

.upload-progress-fill {
  display: block;
  height: 100%;
  background: #0d6efd;
}

.download-progress-fill {
  background: lightblue;
}

/* Single step row */
.jp-step-row {
  display: flex;
  gap: 8px;
  font-size: 12px;
  padding: 2px 0;
  align-items: flex-start;
}

.jp-step-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: inline-block;
  margin-top: 3px;
  flex-shrink: 0;
}

.green-circle {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: rgb(40, 167, 69);
  display: inline-block;
}

.red-circle {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: rgb(220, 53, 69);
  display: inline-block;
}

.yellow-circle {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: rgb(255, 193, 7);
  display: inline-block;
}

.gray-circle {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: rgb(108, 117, 125);
  display: inline-block;
}

.monitoring-count-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  margin-left: 6px;
  padding: 0 5px;
  border-radius: 999px;
  background: rgb(220, 53, 69);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
}

.jp-step-name {
  flex: 1;
  font-family: monospace;
}

.jp-step-status {
  font-weight: 600;
}

.jp-step-detail {
  color: #777;
}

/* Result details */
.jp-result-details {
  margin-top: 8px;
  border-top: 1px solid #e5d9a0;
  padding-top: 6px;
}

.jp-result-summary {
  cursor: pointer;
  font-size: 11px;
  color: #6c757d;
  list-style: none;
  user-select: none;
}
.jp-result-summary::-webkit-details-marker { display: none; }

.jp-result-pre {
  margin: 6px 0 0;
  font-size: 11px;
  line-height: 1.35;
  white-space: pre-wrap;
  word-break: break-word;
  background: #f8f9fa;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  padding: 8px;
  max-height: 200px;
  overflow-y: auto;
}

/* â”€â”€â”€ Job card type label (mirrors Meta's .side-panel-job-card type area) â”€â”€ */

.jp-card-type {
  font-size: 11px;
  color: #6c757d;
  white-space: nowrap;
  display: flex;
  align-items: center;
}

/* â”€â”€â”€ Job detail pane (expanded card body) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

/* Loading / error states */
.jp-detail-loading,
.jp-detail-error {
  padding: 8px 0;
  font-size: 12px;
  color: #6c757d;
}
.jp-detail-error { color: #dc3545; }

/* Body wrapper */
/* The ONE place section spacing is decided. Sections used to stack three
   mechanisms — this gap, a margin-bottom on every section, and an inline
   marginTop on three of them — so neighbours sat 21px or 33px apart with
   nothing saying which, and the last section left dead space below the
   list. `gap` cannot double up and cannot trail, so the others are gone.
   Top padding matches the sections' own 12px so the outer frame and the
   cards inside it share one rhythm. */
.jp-detail-body {
  padding: 12px 0 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.job-detail-section {
  padding: 12px 16px;
  border-radius: 6px;
  background: rgba(255,255,255,0.5);
}

.job-detail-section label {
  display: block;
  margin-bottom: 10px;
  padding: 5px 10px;
  background: #eee;
  text-transform: uppercase;
}

/* Section heading (e.g. "Progress") */
.jp-detail-section-label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #888;
  margin-top: 4px;
}

/* Single key-value row â€” mirrors Meta's detail rows */
.jp-detail-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 12px;
}
.jp-detail-label {
  flex-shrink: 0;
  width: 100px;
  font-weight: 600;
  color: #495057;
}
.jp-detail-value {
  flex: 1;
  color: #212529;
}
.jp-detail-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 10px;
  background: #e9ecef;
  color: #495057;
  font-size: 10px;
  font-weight: 600;
  text-transform: capitalize;
}
.jp-detail-code {
  font-family: monospace;
  font-size: 11px;
  background: #f0f0f0;
  border-radius: 3px;
  padding: 1px 5px;
  color: #495057;
}

/* Files list */
/* jp-detail-row carries no vertical spacing of its own, which only shows when
   a section stacks several — Job ID + Scheduled, and the set_pause target.
   Adjacent-sibling so single-row sections, which is every other one, are
   untouched: one rule, one spacing, no section-specific exception. */
.jp-detail-row + .jp-detail-row {
  margin-top: 7px;
}
.jp-detail-file-list {
  flex: 1;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.jp-detail-file-chip {
  display: inline-flex;
  align-items: center;
  background: #e8f4f8;
  border: 1px solid #b8dde9;
  border-radius: 4px;
  padding: 2px 6px;
  font-size: 11px;
  color: #0d6986;
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.jp-detail-file-chip--more {
  background: #f0f0f0;
  border-color: #ccc;
  color: #6c757d;
}

/* The "+X more" chip is a <button> (it expands/collapses the full
   file list); inherit the chip typography and read as clickable. */
button.jp-detail-file-chip--more {
  cursor: pointer;
  font-family: inherit;
}

button.jp-detail-file-chip--more:hover {
  background: #e2e2e2;
  color: #495057;
}

/* Destinations list */
.jp-detail-dest-list {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.jp-detail-dest {
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: rgba(255,255,255,0.5);
  border: 1px solid #e5d9a0;
  border-radius: 4px;
  padding: 4px 8px;
  font-size: 11px;
}
.jp-detail-dest-campaign {
  font-weight: 600;
  color: #344054;
}
.jp-detail-dest-adgroup {
  color: #6c757d;
  padding-left: 4px;
}

/* â”€â”€â”€ Setup / Loading â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.setup-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  background: #f8f9fa;
  color: #495057;
  font-size: 14px;
}

/* â”€â”€â”€ Tooltip â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.tooltip {
  position: absolute;
  top: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  background: #333;
  color: #fff;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 11px;
  white-space: nowrap;
  pointer-events: none;
}

.tooltip-tip {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 4px solid transparent;
  border-bottom-color: #333;
}

/* Hover-revealed help tooltip: same dark chip as .tooltip but wraps to a
   readable paragraph and only appears on hover/focus of the trigger. */
.help-tip {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.help-tip .tooltip {
  display: none;
  white-space: normal;
  width: max-content;
  max-width: 260px;
  text-align: left;
  line-height: 1.45;
  z-index: 30;
}
.help-tip:hover .tooltip,
.help-tip:focus-within .tooltip {
  display: block;
}

/* â”€â”€â”€ Concept Extraction / Naming Convention (Step 4) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
/* Ported from MetaAssetManager concept-extraction.css */

/* The quiet half of the panel-foot row: going back is available, never the
   thing being offered. */
.extraction-back-link {
  border: 0;
  background: none;
  padding: 6px 0;
  font-size: 13px;
  color: #6c757d;
  cursor: pointer;
}
.extraction-back-link:hover { color: #343a40; text-decoration: underline; }

/* Moves to the next sub-step. Tinted like the tab it takes you to; the accent
   laid over a filled grey button read as noise. */
.extraction-next-substep {
  border: 1px solid;
  border-radius: 6px;
  padding: 6px 14px;
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background .12s ease;
}
.extraction-next-substep.category {
  color: #8c14a3;
  background: #fbeefd;
  border-color: #eec5f5;
}
.extraction-next-substep.category:hover { background: #f6dcfb; }
/* Last sub-step: ends the product rather than moving to another property,
   so it takes the completion green, not a property accent. */
.extraction-next-substep.done {
  color: #155724;
  background: #d4edda;
  border-color: #b7e0c4;
}
.extraction-next-substep.done:hover { background: #c7e6d1; }

/* The (i) that reveals the block above's details. A quiet glyph the size of the
   text it follows, not a filled button. #868e96 rather than #adb5bd: at 3.5:1
   it clears WCAG 1.4.11 for a control, where #adb5bd measured 2.05:1, and the
   padding takes the hit area past the bare 14px glyph. */
/* Click-to-insert macro chips above the Custom rules list. Same vocabulary as
   the Macro reference table below them; the chips are the usable form of it. */
.manual-rule-macro-chip {
  font-family: "SFMono-Regular", ui-monospace, Consolas, monospace;
  font-size: 12px;
  padding: 3px 9px;
  border-radius: 999px;
  border: 1px solid #ced4da;
  background: #fff;
  color: #495057;
  cursor: pointer;
  transition: background .12s ease, border-color .12s ease;
}
.manual-rule-macro-chip:hover { background: #f1f3f5; }
.manual-rule-macro-chip:focus-visible { outline: 2px solid #0b6b63; outline-offset: 1px; }

.extraction-info-toggle {
  border: 0;
  background: none;
  padding: 5px;
  margin-left: 1px;
  font-size: 14px;
  line-height: 1;
  vertical-align: -1px;
  color: #868e96;
  cursor: pointer;
  transition: color .12s ease;
}
.extraction-info-toggle:hover,
.extraction-info-toggle:focus-visible { color: #6c757d; }
.extraction-info-toggle.open { color: #6c757d; }

/* Instructions revealed by an (i). A card rather than bare bullets, carrying
   the live property's accent on its left edge. White, not #fbfcfd: the
   algorithms panel is #fbfcfd, and an identical background turned the card
   there into a flat outline. */
.extraction-instructions {
  margin: 0 0 8px;
  padding: 10px 14px 10px 12px;
  list-style: none;
  border: 1px solid #e9ecef;
  border-left-width: 3px;
  border-radius: 8px;
  background: #fff;
  color: #6c757d;
  font-size: 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.extraction-instructions li.extraction-instructions-caption {
  padding-left: 14px;
  font-size: 10px;
  letter-spacing: .08em;
  text-transform: uppercase;
  font-weight: 700;
  color: #212529;
}
/* Beats `.extraction-instructions li::before` on specificity — as a plain class
   rule it tied and lost, and the caption kept its dot. */
.extraction-instructions li.extraction-instructions-caption::before {
  content: none;
  display: none;
}
/* Block, not flex: these items carry inline markup (<em>, <code>), and as flex
   children every one of those became its own item spaced by the gap. The dot
   hangs beside the text instead. */
.extraction-instructions li {
  display: block;
  position: relative;
  padding-left: 14px;
}
.extraction-instructions li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: .55em;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: currentColor;
  opacity: .45;
}

/* Examples grid â€” two columns (images | videos) */
.concept-examples-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-top: 12px;
}

@media (max-width: 680px) {
  .concept-examples-grid {
    grid-template-columns: 1fr;
  }
}

/* Playables is the 3rd category in a 2-column grid — span it full width so it
   sits on its own row cleanly instead of orphaning next to an empty cell.
   Scoped to the token grid (.concept-examples) so the algo grids are untouched. */
.concept-examples > .concept-examples-grid > .concept-column:nth-child(3) {
  grid-column: 1 / -1;
}

.concept-column {
  display: flex;
  flex-direction: column;
  gap: 8px;
  /* Let the grid track shrink below its content so long, unbreakable preview
     filenames don't force the column (and the whole section) to overflow. */
  min-width: 0;
}

/* Long candidate-preview filenames must wrap inside the card, not overflow it. */
.concept-candidate-preview {
  overflow-wrap: anywhere;
  word-break: break-word;
}
/* First-load placeholders for a sample column. Same box as a real token row so
   the column does not jump when the files arrive. */
.concept-sample-skeletons { display: flex; flex-direction: column; gap: 8px; }
.concept-skeleton-row { pointer-events: none; }
.concept-skeleton-row .concept-tokens { padding-right: 0; }
.skeleton-chip,
.skeleton-line {
  display: block;
  height: 20px;
  border-radius: 5px;
  background: linear-gradient(90deg, #f1f3f5 25%, #e9ecef 37%, #f1f3f5 63%);
  background-size: 400% 100%;
  animation: skeleton-sheen 1.4s ease infinite;
}
.skeleton-line { height: 10px; width: 78%; margin-top: 8px; border-radius: 4px; }
@keyframes skeleton-sheen { from { background-position: 100% 50%; } to { background-position: 0 50%; } }
@media (prefers-reduced-motion: reduce) {
  .skeleton-chip, .skeleton-line { animation: none; }
}

.concept-column-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid #e9ecef;
  padding-bottom: 6px;
  margin-bottom: 4px;
}

.concept-column-header h4 {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: #212529;
}

.concept-clear-restart-button {
  background: transparent;
  border: 1px solid #ced4da;
  border-radius: 4px;
  padding: 2px 8px;
  font-size: 11px;
  color: #6c757d;
  cursor: pointer;
}
.concept-clear-restart-button:hover {
  background: #f1f3f5;
  border-color: #adb5bd;
}

/* Token rows */
.concept-token-row {
  border: 1px solid #e9ecef;
  border-radius: 6px;
  /* The room for the absolutely-positioned SKIP is reserved on the token line
     below, not here: as row padding it also shortened the filename line, which
     shares no space with the button. */
  padding: 8px 10px;
  background: #fff;
  position: relative;
}
.concept-token-row.saved   { border-color: #28a745; }
.concept-token-row.unsaved { border-color: #ffc107; }

.concept-tokens {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  align-items: center;
  padding-right: 58px;
}

/* Individual token chips */
.concept-token {
  padding: 3px 8px;
  border: 1px solid #ced4da;
  border-radius: 4px;
  background: #fff;
  cursor: pointer;
  font-size: 12px;
  font-family: monospace;
  color: #212529;
  transition: background 0.1s, border-color 0.1s;
}
.concept-token:hover {
  background: #e9ecef;
  border-color: #adb5bd;
}
/* CONCEPT selection â€” gold */
.concept-token.selected {
  background: #ffd700;
  border-color: #c8a200;
  color: #212529;
  font-weight: 600;
}
/* CATEGORY selection â€” fuchsia/violet */
.concept-token.selected-category {
  background: #e040fb;
  border-color: #ab00d6;
  color: #fff;
  font-weight: 600;
}

.concept-extension {
  font-size: 11px;
  color: #adb5bd;
  font-family: monospace;
  margin-left: 2px;
}

.concept-filename-full {
  margin-top: 4px;
  font-size: 11px;
  color: #6c757d;
  font-family: monospace;
  word-break: break-all;
}

/* Saved / unsaved badges */
.concept-status-badge {
  font-size: 10px;
  font-weight: 700;
  padding: 2px 6px;
  border-radius: 10px;
  margin-left: 4px;
}
.concept-status-badge.saved,
.concept-status-badge.active  { background: #d4edda; color: #155724; }
.concept-status-badge.unsaved { background: #fff3cd; color: #856404; }

/* Skip button */
.concept-skip-button {
  position: absolute;
  top: 8px;
  right: 8px;
  background: transparent;
  border: 1px solid #ced4da;
  border-radius: 4px;
  padding: 2px 6px;
  font-size: 10px;
  cursor: pointer;
  color: #6c757d;
}
.concept-skip-button:hover { background: #f1f3f5; }

/* Action bar below the examples grid */
.concept-examples-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
}

/* Progress summary */

.concept-help {
  color: #6c757d;
  font-size: 12px;
}

/* "Generated patterns" phase — a distinct, always-present block that separates
   the labelling grids (identify) from the pattern-picking step. Shows a
   placeholder before rules exist, the algo cards after. */
.concept-patterns-section {
  margin-top: 12px;
  padding: 16px;
  border: 1px solid #e9ecef;
  border-radius: 8px;
  background: #fbfcfd;
}
.concept-patterns-section > h4 {
  margin: 0 0 4px;
  font-size: 15px;
  color: #212529;
}
/* Candidate algo cards */
.concept-candidates,
.category-candidates {
  margin-top: 16px;
}

.concept-candidate,
.category-candidate {
  border: 1px solid #ced4da;
  border-radius: 8px;
  padding: 12px;
  background: #fff;
  margin-bottom: 8px;
}
.concept-candidate.active  { border-color: #f1c40f; background: #fffbea; }
.category-candidate.active { border-color: #c026d3; background: #fdf4ff; }

.concept-candidate-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

.concept-candidate-stats {
  font-size: 11px;
  color: #6c757d;
}

.concept-candidate-preview h5 {
  margin: 0 0 4px;
  font-size: 12px;
  color: #495057;
}

.concept-preview-examples {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.concept-preview-example {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
}

.concept-preview-filename {
  font-family: monospace;
  color: #6c757d;
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.concept-preview-arrow { color: #adb5bd; }

.concept-preview-concept  { color: goldenrod; font-weight: 600; }
.concept-preview-category { color: #c026d3; font-weight: 600; }

/* Accent helpers (ported from Meta) */
.concept-accent {
  /* darkgoldenrod (~4.9:1 on white) — plain goldenrod (#DAA520, ~2.9:1) fails
     WCAG AA for this small accent text. The filled chips are unaffected. */
  color: #b8860b !important;
}

.category-accent {
  color: #c026d3 !important;
}

.btn-concept-accent {
  color: #1f1f1f;
  background-color: gold;
  border-color: #f1c40f;
}

.btn-concept-accent:hover,
.btn-concept-accent:focus {
  color: #1f1f1f;
  background-color: #f3c401;
  border-color: #e0b400;
}

.btn-category-accent {
  color: #fff;
  background-color: #d946ef;
  border-color: #c026d3;
}

.btn-category-accent:hover,
.btn-category-accent:focus {
  color: #fff;
  background-color: #c026d3;
  border-color: #a21caf;
}

.btn-algo-selected,
.btn-algo-selected:disabled {
  opacity: 1;
  box-shadow: inset 0 0 0 2px rgba(31, 31, 31, 0.18);
}

/* Static legal footer (in index.html) â€” visible only to anonymous
   visitors / OAuth verification crawlers. Once the user is signed
   in, useCurrentUser adds `authed` to <body> and we hide it. */
body.authed #legal-footer { display: none; }

/* ---- AGU Step 4 â€” grouping chips + plan-preview table ---- */
.agu-grouping-chips {
  display: flex; gap: 8px; flex-wrap: wrap;
  margin-bottom: 14px;
}
.agu-grouping-chip {
  border: 1px solid #d0d7de;
  background: white;
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 13px; font-weight: 500;
  cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  font-family: inherit;
  color: #212529;
}
.agu-grouping-chip:hover { border-color: #1a73e8; }
.agu-grouping-chip.is-selected {
  background: #e8f0fe;
  border-color: #1a73e8;
  color: #1a73e8;
  font-weight: 600;
}
/* Per-kind accent on the grouping chips when selected â€” matches the
   badge palette so it reads as the same "language / category /
   concept" thread across the entire step. The unselected chip stays
   neutral; only the .is-selected variant takes the kind colour. */
.agu-grouping-chip--language.is-selected {
  background: #e9ecef;
  border-color: #6c757d;
  color: #495057;
}
.agu-grouping-chip--language.is-selected .agu-grouping-check {
  background: #6c757d;
  border-color: #6c757d;
}
.agu-grouping-chip--category.is-selected {
  background: #faf0fc;
  border-color: #c026d3;
  color: #c026d3;
}
.agu-grouping-chip--category.is-selected .agu-grouping-check {
  background: #c026d3;
  border-color: #c026d3;
}
.agu-grouping-chip--concept.is-selected {
  background: #fffbe6;
  border-color: #f1c40f;
  color: #b8860b;
}
.agu-grouping-chip--concept.is-selected .agu-grouping-check {
  background: #d4a90c;
  border-color: #d4a90c;
}
.agu-grouping-chip[disabled],
.agu-grouping-chip.is-disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.agu-grouping-chip[disabled]:hover,
.agu-grouping-chip.is-disabled:hover {
  border-color: #d0d7de;
}
.agu-grouping-check {
  width: 14px; height: 14px; border-radius: 50%;
  border: 1.5px solid #d0d7de;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 9px;
}
.agu-grouping-chip.is-selected .agu-grouping-check {
  border-color: #1a73e8;
  background: #1a73e8;
  color: white;
}
/* AGU Step 4 layout â€” pin the chip row + section headings; only the
   table wraps scroll. The step-body normally has overflow:auto, but
   we override it for this step so the wrap's flex-grow + min-height:0
   actually constrains height instead of letting content push siblings
   (and the footer) off-screen. */
.step-body.agu-step-review {
  overflow: hidden;
}
.agu-preview-table-wrap {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  border: 1px solid #eef0f3;
  border-radius: 6px;
  margin-top: 6px;
}
/* Unfilled ("These files won't be usedâ€¦") wrap doesn't claim equal
   priority â€” capped at ~30% of the viewport and scrolls internally
   if it overflows. */
.agu-preview-table-wrap--unfilled {
  flex: 0 1 auto;
  max-height: 30vh;
}
.agu-preview-unfilled-heading {
  margin-top: 14px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.3px;
  color: #6c757d;
  text-transform: uppercase;
}
.agu-preview-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
  /* Auto-fit: each column shrinks/grows around its actual content
     without artificial minimums. */
  table-layout: auto;
}
.agu-preview-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: #f8f9fa;
}
.agu-preview-table th,
.agu-preview-table td {
  text-align: left;
  padding: 8px 10px;
  /* Thinner / lighter row separator. */
  border-bottom: 1px solid #f1f3f5;
  vertical-align: top;
  /* No min-width â€” columns fit their content. */
  min-width: 0;
}
/* Per-campaign tree block inside an Ad-groups cell. */
.tree {
  margin-bottom: 20px;
}
.tree:last-child {
  margin-bottom: 0;
}
/* The boundary between buckets is heavier than the boundary between
   sub-rows of the same bucket so the eye can scan one bucket at a
   time. The class is added to the LAST sub-row of every bucket. */
.agu-preview-table tr.agu-bucket-last-row > td {
  border-bottom: 2px solid #adb5bd;
}
.agu-preview-table th {
  background: #f8f9fa;
  font-size: 11px; font-weight: 700;
  color: #6c757d; text-transform: uppercase; letter-spacing: .4px;
}
.agu-count-badge {
  display: inline-block; background: #eef2ff; color: #4338ca;
  font-size: 11px; font-weight: 700;
  padding: 2px 6px; border-radius: 10px;
  margin-left: 6px;
}
.agu-bucket-chip {
  display: inline-block;
  font-size: 9px; font-weight: 700; letter-spacing: .5px;
  background: #eef2ff; color: #4338ca;
  border-radius: 3px; padding: 1px 5px;
  margin-right: 4px;
  text-transform: uppercase;
}
.agu-bucket-chip--warn {
  background: #fee; color: #c92a2a;
}
.agu-preview-dest {
  margin-bottom: 6px;
}
.agu-preview-dest-name {
  color: #212529;
  font-weight: 500;
}
.agu-attr-badges {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  margin-top: 2px;
}
.agu-attr-badge {
  font-family: inherit;
  font-size: 10px; font-weight: 600;
  padding: 1px 6px;
  border-radius: 999px;
  border: 1px solid #d0d7de;
  background: white;
  cursor: pointer;
  color: #495057;
  line-height: 1.5;
  text-transform: uppercase;
  letter-spacing: .3px;
}
.agu-attr-badge:hover {
  border-color: #1a73e8;
  color: #1a73e8;
}
/* Per-kind accent palette. Every state (empty / inferred / manual)
   stays in the kind's colour family â€” language=gray,
   category=fucsia, concept=gold â€” so a "No Lang" badge still reads
   as a language signal at a glance instead of a generic red error. */

/* Language â€” gray */
.agu-attr-badge--language.agu-attr-badge--empty {
  background: #f8f9fa; border-color: #dee2e6; color: #6c757d;
  font-weight: 500;
}
/*.agu-attr-badge--language.agu-attr-badge--inferred {
  background: #f1f3f5; border-color: #ced4da; color: #495057;
}*/
.agu-attr-badge--language {
  background: #6c757d; border-color: #495057; color: white;
}

/* Category â€” fucsia (.category-accent) */
.agu-attr-badge--category.agu-attr-badge--empty {
  background: #fdf4fe; border-color: #f0d4f7; color: #c026d3;
  font-weight: 500;
}
/*.agu-attr-badge--category.agu-attr-badge--inferred {
  background: #faf0fc; border-color: #e9b6f3; color: #c026d3;
}*/
.agu-attr-badge--category {
  background: #d946ef; border-color: #c026d3; color: white;
}

/* Concept â€” gold (.concept-accent) */
.agu-attr-badge--concept.agu-attr-badge--empty {
  background: #fffdf2; border-color: #f8e58c; color: #b8860b;
  font-weight: 500;
}
/*.agu-attr-badge--concept.agu-attr-badge--inferred {
  background: #fffbe6; border-color: #f1c40f; color: #b8860b;
}*/
.agu-attr-badge--concept {
  background: #f1c40f; border-color: #d4a90c; color: #1f1f1f;
}
/* Read-only variant used to annotate files in the preview matrix â€”
   non-clickable; visual style matches the inferred (light) accent. */
.agu-attr-badge--readonly {
  cursor: default;
  opacity: 0.95;
}
.agu-attr-badge--readonly:hover {
  border-color: inherit;
  color: inherit;
}

/* ── Dispatch board ────────────────────────────────────────────────
   File groups on the left, creative-set groups on the right, the links
   drawn as curves between them. Class names are google-copilot's AGU
   board verbatim (by way of mintegral) so the three read as one UI. */
.agu-board-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; }
.agu-board {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 160px minmax(0, 1fr);
  padding: 2px 10px 12px 2px;
}
.agu-board-wires {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; overflow: visible;
}
.agu-board-wire { fill: none; stroke: #868e96; stroke-width: 2.2; transition: opacity .15s; }
.agu-board-wire.is-manual { stroke: #1a73e8; stroke-width: 3; }
.agu-board-wire.is-faded { opacity: .15; }
.agu-board-wire.is-dragging { stroke-dasharray: 6 4; }
.agu-board-unlink {
  position: absolute; transform: translate(-50%, -50%); z-index: 2;
  width: 20px; height: 20px; padding: 0; border-radius: 50%;
  border: 1.5px solid #868e96; background: #fff; color: #495057;
  font-size: 12px; line-height: 1; cursor: pointer;
}
.agu-board-unlink:hover { border-color: #c92a2a; color: #c92a2a; }
.agu-board-col { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.agu-board-col-title {
  font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .4px; color: #6c757d;
}
.agu-board-col-title .muted { color: #868e96; font-weight: 500; }
.agu-board-card {
  position: relative; border: 1px solid #dee2e6; border-radius: 8px;
  padding: 10px 12px; background: #fff; font-size: 12px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
}
/* A bucket with nothing on the other side: the board's way of saying
   "this one won't be used", in place of the old warning table. */
.agu-board-card.is-unlinked { border-color: #f59f00; background: #fff9db; }
.agu-board-card--dest.is-idle { opacity: .6; }
.agu-board-card-head {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  font-size: 13px; margin-bottom: 6px;
}
.agu-board-keys { display: inline-flex; gap: 4px; }
.agu-board-kinds { display: inline-flex; gap: 8px; color: #868e96; font-size: 11px; }
.agu-board-send {
  margin-left: auto; border: 1px solid #ced4da; background: #fff;
  border-radius: 999px; padding: 2px 10px; font: inherit; font-size: 11px; cursor: pointer;
}
.agu-board-send[aria-expanded="true"] { border-color: #1a73e8; color: #1a73e8; }
.agu-board-menu {
  position: absolute; right: 8px; top: 38px; z-index: 5; width: 240px;
  background: #fff; border: 1px solid #ced4da; border-radius: 8px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .12); padding: 6px;
}
.agu-board-menu-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 8px; border-radius: 6px; cursor: pointer;
}
.agu-board-menu-row:hover { background: #f1f3f5; }
.agu-board-warn { color: #b35900; font-weight: 600; font-size: 11px; margin: -2px 0 4px; }
.agu-board-file {
  display: flex; align-items: center; gap: 6px; min-width: 0;
  color: #495057; margin: 2px 0; font-size: 11px;
}
.agu-board-file file { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.agu-board-file.is-left-out file { text-decoration: line-through; color: #adb5bd; }
.agu-board-leave-out,
.agu-board-more {
  border: 0; background: none; padding: 0; font: inherit; font-size: 11px; cursor: pointer;
}
.agu-board-leave-out { margin-left: auto; color: #1a73e8; }
.agu-board-more { color: #868e96; }
/* The wire's endpoints. The curve is measured between these two dots, so
   they must keep their size and their place on the card's edge. */
.agu-board-port {
  position: absolute; top: 50%; width: 12px; height: 12px; margin-top: -6px;
  border-radius: 50%; background: #fff; border: 2px solid #868e96;
  cursor: crosshair; touch-action: none;
}
[data-port-out] > .agu-board-port { right: -7px; }
[data-port-in] > .agu-board-port { left: -7px; cursor: default; }
.agu-board-recv {
  margin-top: 8px; padding-top: 6px; border-top: 1px dashed #dee2e6;
  color: #495057; font-size: 11px;
}
.agu-preview-file {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 2px;
}
.agu-preview-file-name {
  color: #495057;
}
.agu-attr-badges--file {
  display: inline-flex;
  gap: 4px;
  flex-wrap: wrap;
  margin-top: 0;
}
.agu-preview-campaign {
  color: #495057;
  font-size: 12px;
  vertical-align: top;
  /* No width constraint â€” the column auto-sizes to its widest entry. */
}

/* Tree layout for the Ad-groups column (variant A): each campaign
   becomes a parent line, its ad groups are indented children
   connected by a dashed L-shape. Same shape used in the picker
   mockup the user approved. */
.agu-tree-campaign {
  font-weight: 600;
  color: #212529;
  display: flex;
  align-items: center;
  gap: 4px;
}
.agu-tree-campaign + .agu-tree-campaign,
.agu-tree-children + .agu-tree-campaign {
  margin-top: 8px;
}
.agu-tree-children {
  padding-left: 14px;
  position: relative;
  margin-top: 2px;
}
.agu-tree-children::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 8px;
  left: 6px;
  border-left: 1.5px dashed #adb5bd;
}
.agu-tree-ag {
  position: relative;
  padding-left: 14px;
  margin: 3px 0;
}
.agu-tree-ag::before {
  content: "";
  position: absolute;
  top: 9px;
  left: 0;
  width: 12px;
  border-top: 1.5px dashed #adb5bd;
}
.agu-attr-input {
  font-family: inherit;
  font-size: 11px;
  padding: 1px 6px;
  border-radius: 999px;
  border: 1px solid #1a73e8;
  background: white;
  color: #212529;
  outline: none;
}
.agu-attr-input:focus {
  box-shadow: 0 0 0 2px rgba(26,115,232,0.2);
}
.agu-preview-files div {
  color: #495057;
  margin-bottom: 2px;
}
.agu-preview-files i {
  color: #6c757d; margin-right: 4px; font-size: 10px;
}

/* ---- Auth gate (interim Login screen) ---- */
.auth-gate {
  height: calc(100vh - 160px);
  background: #f8f9fa;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.auth-gate-card {
  width: min(720px, 100%);
  background: white;
  border-radius: 12px;
  padding: 32px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.auth-gate-logo {
  width: min(400px, 100%);
  height: auto;
  display: block;
  margin: 0 auto 8px;
}
.auth-gate-card h1 {
  margin: 0;
  font-size: 22px;
}
.auth-gate-card p {
  margin: 0;
  color: #6c757d;
}
.auth-gate-toggle {
  display: inline-flex;
  align-self: center;
  padding: 4px;
  background: linear-gradient(180deg, #eef4ff 0%, #e2ebfb 100%);
  border: 1px solid #d4e0f8;
  border-radius: 999px;
  gap: 4px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.85);
}
.auth-gate-toggle-option {
  border: none;
  background: transparent;
  color: #5f6c80;
  padding: 9px 18px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease,
    box-shadow 0.18s ease;
}
.auth-gate-toggle-option:hover {
  color: #1f2a3d;
}
.auth-gate-toggle-option.active {
  background: linear-gradient(135deg, #1a73e8 0%, #4f8df5 100%);
  color: #fff;
  box-shadow: 0 8px 18px rgba(26, 115, 232, 0.28);
}
.auth-gate-toggle-option:focus-visible {
  outline: 2px solid #8ab4f8;
  outline-offset: 2px;
}
.auth-gate-card label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 13px;
  color: #495057;
}
.auth-gate-card input,
.auth-gate-card textarea {
  padding: 10px;
  border-radius: 6px;
  border: 1px solid #ced4da;
  font-size: 13px;
}
.auth-gate-error {
  color: #c92a2a;
}

/* â”€â”€â”€ Drive Files Modal (ported from Meta FilesStepBodies.tsx / App.css) â”€â”€â”€â”€â”€ */

/* Modal backdrop */
.modal-backdrop {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* One step below .panels (15): the jobs/queues panel opened from a usage
   overlay shows above the files modal while the user peeks. SourceFilesModal
   toggles this class; any mousedown on the modal box removes it. */
.modal-backdrop--peek {
  z-index: 10;
}

/* Modal shell */
.modal {
  background-color: white;
  border-radius: 8px;
  width: 90vw;
  min-width: 760px;
  max-width: 1100px;
  max-height: 90vh;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  padding: 5px;
  display: flex;
  flex-direction: column;
}

/* Drive files modal â€” wider than the default modal (Gap 5) */
.modal.source-files-modal {
  width: 110vw;
  min-width: 1000px;
  max-width: 2500px;
  /* height, not max-height: this modal is a fixed-height frame — sticky
     toolbar, scrolling virtualised table, footer — and the table's own
     scroll container only gets a height to work with if the modal has one.
     Under max-height the box shrank to its content, so a short folder left
     the footer floating mid-screen and the table never scrolled internally.
     max-height repeats the value to beat .modal's 90vh, which would
     otherwise clamp this back down. zoom shrinks the content; the
     oversized box scales back to ~99vw x ~99vh on screen. */
  height: calc(110vh - 40px);
  max-height: calc(110vh - 40px);
  zoom: 0.9;
}

/* Source files table Ã¢â‚¬â€ ported from Meta's shared .data-table treatment,
   with the modal-specific wrapping/centering rules scoped locally so
   no inline th/td styles are needed. */
.source-files-table-wrap {
  flex: 1;
  overflow-y: auto;
  border: 1px solid #dee2e6;
  border-radius: 4px;
}

.source-files-table td {
  vertical-align: middle;
  word-break: break-all;
  max-width: none;
}

.source-files-table td {
  white-space: normal;
}

.source-files-table__sortable {
  cursor: pointer;
  user-select: none;
}

.source-files-table__cell {
  color: #212529;
}

.source-files-table__updated-timestamp {
  font-size: 0;
}

/* Updated column renders the CalendarTimestamp chip now - no bespoke
 * <time> sizing (the 14px rule fought the chip's plain-text time). */

.source-files-table__checkbox-col,
.source-files-table__checkbox-cell,
.source-files-table__center-col {
  text-align: center;
}

.source-files-table__checkbox-col,
.source-files-table__tight-col {
  width: 1%;
}

/* The file name is the one column the user reads; on a narrow window the
   table would otherwise squeeze it to a few characters per line. */
.source-files-table__name-col {
  min-width: 220px;
}

.source-files-table__checkbox-cell {
  position: relative;
}

.source-files-table__thumb-col,
.source-files-table__thumb-cell {
  width: 52px;
  padding: 2px 4px;
}

/* Column-hide affordance: a small "-" badge floats above a header cell,
   horizontally centered, on hover; clicking hides that column (its <th>
   and every <td> switch to display:none — the browser correctly collapses
   the column even though <colgroup><col> still declares it, same
   technique DataTables' colvis plugin uses). Re-enable hidden columns via
   the column-visibility button (.column-selector, shared with
   PerformanceColumnsSelector) in the filters result bar.

   The table's <thead> is position:sticky inside an overflow-y:auto wrapper
   (.source-files-table-wrap), which clips ANY descendant painted outside
   its own box — a plain `position: absolute; top: -10px` badge is still
   inside that wrapper's containing-block chain, so no amount of reserved
   padding keeps it from being clipped at every scroll position (the sticky
   ancestor's clip boundary moves WITH it as the user scrolls).

   CSS anchor positioning (Chrome/Edge/Firefox 132+/Safari 18.2+, ~88%
   coverage mid-2026) breaks the badge out of that chain entirely instead:
   position:fixed removes it from the wrapper's containing block, and
   anchor()/position-anchor re-attach its coordinates directly to the <th>
   BY REFERENCE rather than by DOM nesting — overflow-y:auto on an ancestor
   it's no longer contained by can't clip it. anchor-scope on the <th> is
   required alongside anchor-name: without it every badge on the page
   would bind to the LAST <th> in the document (anchor-name matches are
   shared/global by default, not nearest-DOM-ancestor — see
   https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/anchor-scope).
   Falls back to the old in-flow absolute positioning (visually still
   clipped) for the remaining browsers without anchor positioning. */
.source-files-table__th {
  position: relative;
  anchor-name: --col-hide-th;
  anchor-scope: --col-hide-th;
}
.source-files-table__col-hide-btn {
  position: absolute;
  top: -10px;
  left: 50%;
  transform: translateX(-50%);
  width: 18px;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid #dee2e6;
  border-radius: 50%;
  background: #fff;
  color: #dc3545;
  font-size: 11px;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.1s ease;
  z-index: 5;
}
@supports (anchor-name: --a) {
  .source-files-table__col-hide-btn {
    position: fixed;
    position-anchor: --col-hide-th;
    top: calc(anchor(top) - 10px);
    left: anchor(center);
    /* z-index is now relative to the fixed-position (viewport) stacking
       context instead of the <th>'s own local one — needs to clear the
       sticky thead's z-index:10 (.data-table thead) from anywhere on the
       page, not just its own header cell. */
    z-index: 20;
  }
}
.source-files-table__th:hover > .source-files-table__col-hide-btn {
  opacity: 1;
  pointer-events: auto;
}

.source-files-table__name {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}

.source-files-table__spacer {
  padding: 0;
  border: 0;
}

.modal-header {
  padding: 10px 20px;
  border-bottom: 1px solid #dee2e6;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
}

.modal-header h3 {
  margin: 0;
  font-size: 18px;
  font-weight: bold;
}

.modal-inner {
  flex: 1;
  min-height: 250px;
  max-height: calc(110vh - 150px);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

.modal-footer {
  padding: 10px 20px;
  border-top: 1px solid #dee2e6;
  display: flex;
  gap: 12px;
  align-items: center;
  justify-content: flex-end;
  flex-shrink: 0;
}

/* Files load parameters bar */
.files-load-parameters {
  display: flex;
  gap: 16px;
  align-items: flex-end;
  margin-bottom: 16px;
  padding: 12px;
  background-color: #f8f9fa;
  border: 1px solid #dee2e6;
  border-radius: 4px;
}

/* Alert boxes */
.alert {
  padding: 16px;
  background-color: #f3f3f3;
  border: 1px solid #ccc;
  border-radius: 4px;
  margin-bottom: 16px;
}

.alert-info {
  border-color: #90caf9;
  background-color: #e3f2fd;
  color: #1565c0;
}

.alert-error {
  background-color: #fff3cd;
  border: 1px solid #ffeaa7;
  color: #856404;
}

/* Selection checkbox */
.selection-input {
  width: 16px;
  height: 16px;
  cursor: pointer;
  accent-color: #007bff;
}

/* File type badges */
.td-file-type-image {
  padding: 2px 8px;
  border-radius: 4px;
  background-color: #e3f2fd;
  color: #1565c0;
  font-size: 11px;
  font-weight: 600;
}

.td-file-type-video {
  padding: 2px 8px;
  border-radius: 4px;
  background-color: #fce4ec;
  color: #880e4f;
  font-size: 11px;
  font-weight: 600;
}

.td-file-type-other {
  padding: 2px 8px;
  border-radius: 4px;
  background-color: #f3e5f5;
  color: #4a148c;
  font-size: 11px;
  font-weight: 600;
}

/* Folder path sub-label */
.file-folder {
  color: #999;
  margin-top: 2px;
  font-style: italic;
  font-size: 0.9em;
}

/* "×N" badge: the row has content-identical twins (md5); title lists them */
/* Content twins: this file's bytes already exist under another name or
   folder in the same tenant. HIGHLIGHTED, not greyed — selecting two of them
   into one ad group is a real error, not trivia. Google Ads resolves
   identical media to ONE Asset and then rejects the operation
   (DUPLICATE_ASSET); job JOB1-H888VD lost all 12 of its destinations to a
   single zip picked twice from two folders, and the two rows looked
   identical because only the folder sub-label differed. The badge has to be
   visible while you are choosing, which a #6c757d footnote was not. */
.file-siblings {
  margin-left: 6px;
  font-size: 11px;
  font-weight: 600;
  color: #8a5300;
  background: #fff4d6;
  border: 1px solid #f0c36d;
  border-radius: 8px;
  padding: 0 6px;
  cursor: help;
  white-space: nowrap;
}
/* Two joined squares — "these bytes exist elsewhere too". Decorative: the
   count and the title attribute already carry the meaning for a screen
   reader, so this must not be read out. */
/* The badge is a button now (it opens the twin popover), so strip the
   button chrome the browser adds and keep the pill it already looked like. */
.file-siblings {
  cursor: pointer;
  font-family: inherit;
  line-height: 1.5;
}
.file-siblings:hover { background: #ffe9b0; }
/* Filename inside the twin popover: same weight as the table's own names. */
.twin-name { font-weight: 600; word-break: break-word; }

.file-siblings::before {
  content: "⧉";
  margin-right: 4px;
  opacity: 0.85;
}

/* File name cell */
.td-name-text {
  font-weight: 500;
  word-break: break-all;
}

/* Concept cell */
.td-concept-wrap {
  max-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Inline flex helper */
.inline-flex-center {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

/* Table row selected */
.table-row-selected {
  background-color: #e8f4ff;
}

/* QueuesPanel: cell for the per-row "drop_reason" text on the
   Dropped items table. The reason can be very long (it names every
   rejected file + AppLovin's reason); break it freely instead of
   ellipsising so admins see the full text inline. */
.dropped-item-reason {
  color: #dc3545;
  word-break: break-all;
}

/* DriveFilesModal: AppLovin-rejected file rows are struck through
   so the user can scan a long table and skip them at a glance.
   The red-X icon on the checkbox cell already carries the
   per-file reason tooltip. */
tr.rejected {
  text-decoration: line-through;
  color: #999;
}
/* A paused AppLovin asset is muted but not struck through: it is not rejected
   and not gone, a person re-activates it in Axon. */
tr.paused {
  color: #888;
}

/* A file Done refused (the Cloud Files modal's pick check): it was unticked, and
   this keeps saying why until the person ticks it again. Same reds as the
   refusal toast (#f8d7da / #842029) and the status badge (#dc3545). */
tr.pick-refused {
  background-color: #fdecee;
}
tr.pick-refused > td:first-child {
  box-shadow: inset 3px 0 0 #dc3545;
}
tr.pick-refused .selection-input {
  outline: 2px solid #dc3545;
  outline-offset: 1px;
}
.pick-refused__note {
  margin-top: 2px;
  color: #842029;
  font-size: 0.9em;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 460px;
}
/* One-shot attention (0.6 s): a short shake and a red flash that settles into
   the tint above. The class is on the row only for the moment after Done. */
tr.pick-refused--flash {
  animation: pick-refused-flash 0.6s ease-out 1;
}
tr.pick-refused--flash > td {
  animation: pick-refused-shake 0.6s ease-out 1;
}
@keyframes pick-refused-flash {
  0% { background-color: #f1aeb5; }
  100% { background-color: #fdecee; }
}
@keyframes pick-refused-shake {
  0%, 100% { transform: translateX(0); }
  15% { transform: translateX(-6px); }
  35% { transform: translateX(6px); }
  55% { transform: translateX(-4px); }
  75% { transform: translateX(3px); }
}
/* The header "N selected" chip, when the count dropped because of a refusal. */
.selected-count-chip--pulse {
  animation: selected-count-chip-pulse 0.5s ease-out 1;
}
@keyframes selected-count-chip-pulse {
  0% { transform: scale(1.12); box-shadow: 0 0 0 0 rgba(220, 53, 69, 0.55); }
  100% { transform: scale(1); box-shadow: 0 0 0 10px rgba(220, 53, 69, 0); }
}
@media (prefers-reduced-motion: reduce) {
  tr.pick-refused--flash,
  tr.pick-refused--flash > td,
  .selected-count-chip--pulse { animation: none; }
}

/* Badge superimposed on the checkbox cell of the DriveFilesModal
   row (red X for AppLovin-rejected files, future variants can
   reuse the base class). Vertical positioning relies on the
   containing <td>'s vertical-align: middle. */
.drive-row-status-icon {
  position: absolute;
  right: 2px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 15px;
  background: #fff;
  border-radius: 50%;
  padding: 1px 3px;
  cursor: help;
  pointer-events: auto;
}
.drive-row-status-icon--rejected,
.drive-row-status-icon--blocked {
  color: #dc3545;
}
.drive-row-status-icon--paused {
  color: #6c757d;
}
.drive-row-status-icon--in-review {
  color: #b7791f;
}
/* Corner badge: rides the checkbox's top-right corner instead of covering it,
   and lets clicks through to the label that fills the cell. */
.drive-row-status-icon--badge {
  top: -7px;
  right: -10px;
  transform: none;
  width: 16px;
  font-size: 13px;
  line-height: 16px;
  text-align: center;
  background: transparent;
  border-radius: 0;
  padding: 0;
  pointer-events: none;
  filter: drop-shadow(1px 0 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 1px 0 #fff) drop-shadow(0 -1px 0 #fff);
}
.source-files-table__checkbox-cell:has(> .source-files-table__check-hit) {
  padding: 0;
}
.source-files-table__check-hit {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: 6px 14px 6px 8px;
  cursor: pointer;
  user-select: none;
}
/* The row is taller than the label; this layer makes the whole cell clickable. */
.source-files-table__check-hit::after {
  content: "";
  position: absolute;
  inset: 0;
}
.source-files-table__check-hit:has(.selection-input:disabled) {
  cursor: not-allowed;
}
/* Above the ::after hit layer, so the checkbox itself stays the click target. */
.source-files-table__check-box {
  position: relative;
  z-index: 1;
  display: block;
  width: 16px;
  height: 16px;
}
.source-files-table__check-box > .selection-input {
  display: block;
  margin: 0;
}

.source-used-axon-logo {
  align-items: center;
  background: #eef0f2;
  border: 1px solid #c9ced4;
  border-radius: 4px;
  color: #6c757d;
  display: inline-flex;
  filter: grayscale(1);
  font-size: 8px;
  font-weight: 800;
  height: 20px;
  justify-content: center;
  letter-spacing: -0.4px;
  line-height: 1;
  margin-right: 6px;
  opacity: 0.58;
  vertical-align: middle;
  width: 20px;
}

/* Outline-primary button variant (used by refetch / load-more) */
.btn-outline-primary {
  border: 1px solid #007bff;
  background: transparent;
  color: #007bff;
}

.btn-outline-primary:hover:not(:disabled) {
  background: #007bff;
  color: white;
}

/* Was used by 3 components but never defined, so they rendered borderless. */
.btn-outline-secondary {
  border: 1px solid #6c757d;
  background: transparent;
  color: #6c757d;
}

.btn-outline-secondary:hover:not(:disabled) {
  background: #6c757d;
  color: white;
}

/* Placement orientation icons */
.placement-icon {
  display: inline-block;
  box-sizing: border-box;
  border: 2px solid currentColor;
  border-radius: 3px;
  vertical-align: middle;
  flex: 0 0 auto;
}

.placement-icon.portrait  { width: 8px; height: 14px; color: #5c7cfa; }
.placement-icon.landscape { width: 14px; height: 6px; color: #20c997; }
.placement-icon.square    { width: 10px; height: 10px; color: #fd7e14; }

/* col_filetype: hidden on small viewports (matches Meta) */
.col_filetype { display: none; }

/* Selected-files table border wrapper */
.selected-files-table-border {
  display: flex;
  flex-direction: column;
  min-height: 0;
  border: solid 3px #007bff;
  padding: 20px;
  border-radius: 8px;
}

/* Table wrapper */
.table-wrapper {
  overflow-y: auto;
  min-height: 125px;
}

.filter-container {
  padding: 12px;
  background: #f8f9fa;
  border: 1px solid #dee2e6;
  border-bottom: none;
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  align-items: center;
}

.filter-search-container {
  min-width: 200px;
  flex: 1 1 240px;
}

.filter-select-container {
  min-width: 160px;
}

.target-multi-select {
  position: relative;
  min-width: min(520px, 100%);
  max-width: min(760px, 100%);
}

.target-multi-select__control {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  min-height: 34px;
  padding: 3px 7px;
  border: 1px solid #ced4da;
  border-radius: 4px;
  background: #fff;
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.03);
  cursor: pointer;
}

.target-multi-select__control.is-open {
  border-color: #2f80ed;
  box-shadow: 0 0 0 2px rgba(47, 128, 237, 0.14);
}

.target-multi-select__badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  max-width: 260px;
  min-height: 24px;
  padding: 2px 5px 2px 7px;
  border: 1px solid #bcd4f6;
  border-radius: 4px;
  background: #eef5ff;
  color: #343a40;
}

.target-multi-select__badge-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.target-multi-select__badge button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border: 0;
  border-radius: 3px;
  background: transparent;
  color: #5c6f82;
  cursor: pointer;
}

.target-multi-select__badge button:hover:not(:disabled) {
  background: rgba(47, 128, 237, 0.14);
  color: #1f5fbf;
}

.target-multi-select__badge button:disabled {
  cursor: default;
  opacity: 0.38;
}

.target-multi-select__input {
  flex: 1 1 140px;
  min-width: 120px;
  border: 0;
  outline: 0;
  padding: 4px 2px;
  background: transparent;
  color: #343a40;
}

.target-multi-select__menu {
  position: absolute;
  z-index: 30;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  max-height: 260px;
  overflow-y: auto;
  padding: 4px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  background: #fff;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.12);
}

.target-multi-select__option {
  display: flex;
  width: 100%;
  align-items: center;
  padding: 7px 8px;
  border: 0;
  border-radius: 3px;
  background: transparent;
  color: #343a40;
  text-align: left;
  cursor: pointer;
}

.target-multi-select__option:hover,
.target-multi-select__option:focus {
  background: #f1f6ff;
  outline: 0;
}

.target-multi-select__value {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.target-multi-select__label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.target-multi-select__empty {
  padding: 8px;
  color: #6c757d;
  font-size: 13px;
}

.filter-input,
.filter-select {
  width: 100%;
  padding: 4px 8px;
  border: 1px solid #ced4da;
  border-radius: 3px;
}

.filter-clear-button {
  padding: 4px 10px;
  border: 1px solid #ced4da;
  border-radius: 4px;
  background: #fff;
  cursor: pointer;
}

.filter-clear-button:hover {
  background: #f1f3f5;
}

.td-text-content {
  word-break: break-word;
  white-space: normal;
  line-height: 1.4;
}

.td-text-content-empty {
  word-break: break-word;
  white-space: normal;
  line-height: 1.4;
  color: #6c757d;
  font-style: italic;
}

.empty-state-center {
  text-align: center;
  padding: 40px;
  color: #6c757d;
}

.empty-state-center-error {
  text-align: center;
  padding: 40px;
  color: #dc3545;
}

/* â”€â”€â”€ Filter toolbar (Step 2 campaigns) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
.filter-controls {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  padding: 8px 10px;
  border: 1px solid #e9ecef;
  border-bottom: 0;
  border-top-left-radius: 6px;
  border-top-right-radius: 6px;
  background: #f8f9fa;
}
.filter-controls > * {
  order: 1;
}
.filter-controls > input.setup-input {
  order: 2;
  flex: 1 1 100%;
  min-width: 0 !important;
}
.filter-controls-right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 10px;
}
.filter-info {
  font-size: 12px;
  color: #6c757d;
}
.filter-refresh-button {
  background: #fff;
  border: 1px solid #ced4da;
  border-radius: 4px;
  padding: 4px 8px;
  cursor: pointer;
  color: #495057;
}
.filter-refresh-button:hover { background: #fffbe5; }
.filter-refresh-button:disabled { opacity: 0.5; cursor: not-allowed; }

.filter-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #495057;
}
.filter-toggle-right { margin-left: auto; }
.filter-toggle-label {
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
}
.filter-toggle-switch {
  position: relative;
  display: inline-block;
  width: 36px;
  height: 18px;
}
.filter-toggle-switch input { opacity: 0; width: 0; height: 0; }
.filter-toggle-slider {
  position: absolute;
  cursor: pointer;
  inset: 0;
  background-color: #ced4da;
  border-radius: 999px;
  transition: background-color 0.2s ease;
}
.filter-toggle-slider::before {
  position: absolute;
  content: "";
  height: 14px;
  width: 14px;
  left: 2px;
  top: 2px;
  background-color: #fff;
  border-radius: 50%;
  transition: transform 0.2s ease;
  box-shadow: 0 1px 2px rgba(0,0,0,0.2);
}
.filter-toggle-switch input:checked + .filter-toggle-slider { background-color: #007bff; }
.filter-toggle-switch input:checked + .filter-toggle-slider::before { transform: translateX(18px); }

/* Sort indicators on data-table headers */
.data-table th.is-sortable {
  cursor: pointer;
  user-select: none;
}
.data-table th .sort-icon {
  margin-left: 4px;
  color: #adb5bd;
  font-size: 10px;
}
.data-table th.is-sortable:hover { background: #f1eccc; }
.data-table tbody tr.is-checked { background: #ddf3ff; }
.data-table tbody tr.adgroup-row td { background: #fafafa; }
/* The campaigns search: a set it matched, the "show more" row, and the
   count of matching sets on a campaign row. */
.campaign-search-badge {
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
  background: rgba(249, 115, 22, 0.1);
  color: rgb(249, 115, 22);
}
.data-table tbody tr.adgroup-row.is-search-hit td { background: #fff8c5; }
.campaign-search-more {
  font-size: 11px;
  color: #6c757d;
}
.campaign-search-more button {
  padding: 0;
  border: none;
  background: none;
  color: #0d6efd;
  font-size: inherit;
  cursor: pointer;
}

/* â”€â”€â”€ Name Template Editor (ported from Meta NameTemplateEditor.tsx / App.css) â”€â”€ */

/* Two-column layout: textarea left, macro badges right */
.name-template-layout {
  display: flex;
  gap: 16px;
  align-items: stretch;
  flex-wrap: wrap;
}

.name-template-input-column {
  flex: 1 1 0;
  min-width: 0;
}

.name-template-macros-column {
  flex: 1 1 0;
  min-width: 0;
  margin-top: 0;
}

.name-template-macro-badges {
  margin-top: 8px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* WYSIWYG: transparent textarea over a coloured highlight div */
.name-template-wysiwyg {
  position: relative;
  display: flex;
}

.name-template-wysiwyg .form-control {
  position: relative;
  flex: 1;
  background: transparent;
  z-index: 2;
}

.name-template-wysiwyg textarea.form-control {
  min-height: 60px;
  resize: vertical;
  white-space: pre-wrap;
  font-family: monospace;
  font-size: 13px;
}

/* Highlight layer â€” sits behind the textarea, renders macro spans */
.name-template-highlight {
  position: absolute;
  inset: 0;
  font-family: monospace;
  color: transparent;
  pointer-events: none;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  overflow: hidden;
  padding: 8px 13px;
  font-size: 13px;
  z-index: 3;
}

/* Macro token highlight colour */
.name-template-highlight span {
  color: #ff9933;
  background: rgba(255, 220, 150, 0.4);
}
/* A {token} that is not a macro (the preview's unknown_macro error says why). */
.name-template-highlight span.is-unknown {
  color: #dc3545;
  background: rgba(220, 53, 69, 0.12);
  text-decoration: underline wavy #dc3545;
}

/* Macro insertion badge buttons */
.btn-badge {
  padding: 5px;
  border: solid 1px #999;
  background: #eee;
  line-height: 1;
  color: #333;
}
.btn-badge:hover {
  background: #ddd;
  border-color: #ff9933;
}

/* Accent variants for {concept} and {category} badges â€” Meta style
   (presentation/web/src/App.css:5210 in MetaAssetManager). Font
   colour only; the surrounding .btn-badge gray fill stays put so
   the badges blend with the form chrome instead of standing out
   as solid colour blocks. .concept-accent / .category-accent at
   lines 2265 / 2269 already define the goldenrod / magenta font
   colours used here â€” no per-element override needed. */

/* Utility helpers (absent from google-copilot meta-port.css before this patch) */
.help-text {
  color: #6c757d;
  margin-top: 4px;
  font-size: 11px;
}

.help-box {
  font-size: 11px;
  color: #6c757d;
  padding: 8px;
  background-color: #f8f9fa;
  border-radius: 4px;
  border: 1px solid #dee2e6;
}

.text-error {
  color: #dc3545;
}

/* â”€â”€â”€ Jobs panel â€” cell layout â”€â”€ */
/* ROW POLICY: one row = one line. Every cell nowrap; Target (unbounded
   length) and Username ellipsize with a tooltip and absorb the slack. */
.jp-td-caret {
  width: 22px;
  cursor: pointer;
  color: #888;
  text-align: center;
}
/* Queues panel: archive (row Status cell) and Flush (Pending items header). */
.queue-archive-btn { margin-left: 8px; vertical-align: middle; padding: 2px 6px; }
.queue-flush-btn { color: #c0392b; }
/* Save + Cancel sit together in the section header, where one Change-order
   button used to. */
.queue-reorder-actions { display: inline-flex; gap: 6px; }

/* Reorder mode. Rows only become draggable in the mode, so the grab cursor
   is the signal that the table is now a list you arrange. */
.queue-row-draggable { cursor: grab; }
.queue-row-draggable:active { cursor: grabbing; }
.queue-row-selected > td { background: #eef5ff; }
/* Where the row would land. A top border rather than a filled row: the gap
   is what moves, not the row under the pointer. */
.queue-row-dragover > td { box-shadow: inset 0 2px 0 0 #007bff; }

/* Frozen while the server confirms the new order: the rows the user just
   arranged must not be touchable until they are agreed. */
.queue-reorder-saving { position: relative; }
.queue-reorder-saving table { opacity: .45; pointer-events: none; }
.queue-reorder-veil {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-size: 12px;
  color: #495057;
  background: rgba(255, 255, 255, .6);
}
/* Queue item public ref (ITM1-...). Values match the inline QUE1-/ROT1-
   refs in the same panel so the three levels read as one family. */
.queue-item-waiting {
  /* Marks a pending item the rotation is stepping over (#293). Sits next to
     .queue-item-ref in the same cell, so it borrows its type scale and only
     adds the badge shape — without a rule of its own the element rendered as
     bare unstyled text and read as a stray word rather than a signal. */
  display: inline-block;
  padding: 1px 6px;
  border-radius: 9px;
  font-size: 11px;
  line-height: 16px;
  white-space: nowrap;
  vertical-align: middle;
  color: #8a6d1f;
  background: #fff4d6;
  border: 1px solid #f0dca6;
}
.queue-item-ref {
  display: inline-block;
  margin-right: 6px;
  font-size: 11px;
  font-family: monospace;
  color: #6c757d;
  white-space: nowrap;
  vertical-align: middle;
}
.jp-td-username {
  font-size: 12px;
  color: #555;
  /* min == max: a FIXED width, not "up to". The table is table-layout:auto, so
     the Origin column (Marta C4) took width out of here — the cell rendered at
     90px, leaving 36px for the name after avatar+gap, and "pvl-misha" (54px)
     wrapped onto two lines.

     120, not the original 130: the jobs table sits in a fixed 880px panel with
     no slack, so those 10px are what keeps .jp-td-jobtype off a second line
     ("Create CS" needs ~87px and had 79px at 130). Measured on the live page
     across 130/120/112/108 — 120 is the smallest change that puts BOTH the
     username and Job Type on one line at zero overflow. Longer usernames
     ellipsize, as they already did. */
  min-width: 100px;
  max-width: 100px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.jp-username-with-avatar {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  /* The ellipsis lives on the td, but a flex item won't shrink below its
     content without this pair — that is why the column kept resizing. */
  min-width: 0;
  max-width: 100%;
}

.jp-username-with-avatar > span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Origin (Marta C4): shrink-to-fit. `width: 1%` on an auto-layout table asks
   for the narrowest column that still fits its content, so the chip takes
   exactly what it needs and no more — the remaining width stays with Target
   and Job Type, which is where a long value actually needs it. */
.jp-td-origin {
  width: 1%;
  white-space: nowrap;
}
/* The dash for a job tied to no app. It takes `.target-badge` for the 30px
   box so the Target column lines up, and holds itself to greys here.
   Deliberately NOT inherited: `.target-badge`'s own fill is a neutral that a
   real chip immediately overrides inline with a hue from the product name, so
   leaning on it would let a future edit there give this row a colour — and a
   colour reads as an identity this row does not have. Muted, not faded: no
   app is a real state, not missing data (see targetCellText). */
.jp-target-none {
  background: #f8f9fa;
  border-color: #ced4da;
  color: #6c757d;
  font-weight: 600;
}

.jp-td-target {
  font-weight: 500;
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.jp-td-target .jp-td-target-id {
  font-size: 10px;
  color: #888;
  margin-left: 4px;
}
.jp-td-jobtype {
  white-space: nowrap;
  font-size: 12px;
  color: #444;
  /* .jobs-panel td sets word-break:break-all, which exists to stop long
     space-less values (ids, filenames) pushing a horizontal scrollbar. Job
     types are short labels WITH spaces, so break-all just made them break
     mid-word — "Upload O / nly", "Update C / S". Break at the space instead;
     overflow-wrap:anywhere keeps the original protection for the hypothetical
     unbreakable token. Scoped to this cell so the blanket rule stands. */
  word-break: normal;
  overflow-wrap: anywhere;
}
.jp-td-jobtype i {
  color: #6c757d;
  margin-right: 5px;
}
/* Metadata. 11px + #666 puts "when" below the username and job type, which
   are what you actually scan a log for, without going so small it stops being
   comfortably readable. Deliberately not 10px: that size belongs to an
   annotation sitting inside another cell (.jp-td-target-id), and this is a
   column of its own. Both were tried on the running page at 10 and 11. */
.jp-td-created {
  font-size: 11px;
  color: #666;
  white-space: nowrap;
}
/* Shrink-to-fit, same as .jp-td-origin. Without a width the auto-layout table
   hands this column slack it has no use for — the cell is an icon, and only
   the optional "Archived" badge ever needs more. The freed width goes to
   Target and Job Type, where long values actually need it. */
.jp-td-status {
  width: 1%;
  white-space: nowrap;
  text-align: center;
  vertical-align: middle;
}
/* Center the status content as one group both axes. A block flex that fills
   the cell (height:100%) centres the icon (a baseline-positioned glyph) and
   the optional "Archived" badge via align-items/justify-content — robust
   regardless of the row height or the cell's text-align/vertical-align. */
.jp-status-inner {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}
.jp-td-actions {
  text-align: right;
  white-space: nowrap;
}
.jp-action-btn {
  font-size: 11px;
  padding: 3px 8px;
  margin-left: 4px;
  border: 1px solid #c9b96a;
  background: #fff;
  border-radius: 4px;
  cursor: pointer;
  color: #444;
}
.jp-action-btn:hover { background: #fffbe5; }
.jp-action-btn:disabled {
  cursor: not-allowed;
  opacity: 0.4;
}
.jp-action-btn--danger {
  border-color: #dc3545;
  color: #b02a37;
}
.jp-action-btn--danger:hover {
  background: #fff5f5;
}
.jp-action-btn.is-primary {
  background: #2c6cd5;
  color: #fff;
  border-color: #2c6cd5;
}
.jp-action-btn.is-primary:hover { background: #1d57b8; }

.job-payloads-modal {
  max-width: min(1280px, 96vw);
  width: 96vw;
}

.job-payloads-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 12px;
  padding: 14px;
  overflow: hidden;
}

.job-payloads-section {
  min-width: 0;
}

.job-payloads-section h4 {
  margin: 0 0 6px;
  font-size: 12px;
  color: #343a40;
}

.job-payloads-section .jp-result-pre {
  max-height: 68vh;
}

.job-payloads-loading,
.job-payloads-error {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 18px;
  color: #495057;
  font-size: 13px;
}

.job-payloads-error {
  color: #b02a37;
}

@media (max-width: 900px) {
  .job-payloads-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

.jp-detail-row-tr td {
  background: rgba(0, 0, 0, 0.05);
  border-bottom: 1px solid #e5d9a0;
  padding: 0 10px 10px 32px;
}

.jp-status-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px 8px;
  border-radius: 3px;
  font-size: 11px;
  font-weight: 500;
}

.jp-status-badge-partial {
  background: #fff3cd;
  color: #856404;
}

.jp-status-badge-default {
  background: #f8f9fa;
  color: #6c757d;
}

.jp-status-with-warning {
  display: inline-flex;
  line-height: 1;
  position: relative;
}

.jp-status-warning-overlay {
  bottom: -4px;
  color: #dc3545;
  font-size: 10px;
  position: absolute;
  right: -6px;
}

/* Step plan row (used in expanded detail) â€” pending/running/done/failed dots */
.jp-step-row.is-pending .jp-step-dot { background: #d0d0d0; }
.jp-step-row.is-running .jp-step-dot { background: #ff9800; }
.jp-step-row.is-running .jp-step-name::after {
  content: " ";
  display: inline-block;
  margin-left: 6px;
  border: 2px solid #ff9800;
  border-top-color: transparent;
  border-radius: 50%;
  width: 9px;
  height: 9px;
  animation: jp-spin 0.7s linear infinite;
  vertical-align: -1px;
}
.jp-step-row.is-succeeded .jp-step-dot { background: #28a745; }
.jp-step-row.is-failed .jp-step-dot { background: #dc3545; }
@keyframes jp-spin { to { transform: rotate(360deg); } }

/* â”€â”€â”€ Maintenance / deployment overlay (mirrors Meta) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
.maintenance-overlay {
  position: fixed;
  inset: 0;
  background: rgba(33, 37, 41, 0.85);
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.maintenance-content {
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.3);
  padding: 36px 40px;
  max-width: 480px;
  width: 100%;
  text-align: center;
}

.maintenance-icon {
  font-size: 3rem;
  color: #007bff;
  margin-bottom: 14px;
}

.maintenance-content h2 {
  margin: 0 0 12px;
  font-size: 22px;
  font-weight: 600;
  color: #212529;
}

.maintenance-content p {
  margin: 0 0 20px;
  color: #495057;
  line-height: 1.55;
  font-size: 14px;
}

/* .maintenance-spinner + .spinner are already defined in the header section */

/* â”€â”€â”€ merged from queues-panel.css â”€â”€â”€ */
/*
 * Queues panel chrome â€” port of MetaAssetManager's panel CSS rules.
 *
 * The DOM hierarchy in our QueuesPanel mirrors Meta's:
 *   .side-panel.queues-panel
 *     â”œâ”€ .side-panel-drag-handle
 *     â”œâ”€ .side-panel-header > .side-panel-title + .side-panel-close-button
 *     â”œâ”€ .side-panel-filters > .side-panel-filters-colÃ—N
 *     â”œâ”€ .side-panel-tabs
 *     â””â”€ .side-panel-body > .side-panel-body-inner > .data-table-wrap
 *           â””â”€ .table-wrapper > table.data-table > tbody > .queue-item
 *                                                           â””â”€ .queue-detail
 *
 * Class names + property values are taken verbatim from the
 * MetaAssetManager App.css so any visual deviation comes only from
 * the surrounding shell (header, fonts, button base styles), which we
 * already inherit from the global stylesheet.
 */

/* â”€â”€â”€ Multi-panel parent (.panels) â€” direct port of Meta's pattern.
 * Anchored to the right edge under the AppHeader, flex `row-reverse`
 * so the most-recently-rendered panel (JobsPanel) ends up on the
 * right and QueuesPanel slots in to its left. `pointer-events: none`
 * lets clicks pass through the empty area between/around panels so
 * the user can interact with the page underneath; each panel
 * re-enables pointer-events for itself. */
.panels {
  position: fixed;
  /* The AppHeader's MEASURED height (AppHeader.tsx publishes it): its CSS
     gives a 60px floor, and the step chips wrap past it on a narrow
     window. The 60px fallback is what this said before, so a render
     before the first measurement looks exactly as it used to. */
  top: var(--app-header-h, 60px);
  right: 0;
  bottom: 0;
  z-index: 15;
  display: flex;
  flex-direction: row-reverse;
  pointer-events: none;
}

/* â”€â”€â”€ Side-panel chrome â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
.side-panel {
  position: relative;
  width: 750px;
  min-width: 600px;
  /* Sits below the AppHeader inside the .panels flex container. */
  height: calc(100vh - var(--app-header-h, 60px));
  box-shadow: -4px 0 16px rgba(0, 0, 0, 0.15);
  background: white;
  overflow-y: auto;
  pointer-events: auto;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
}

/* When more than one panel is open, narrow each so they fit
 * side-by-side without overflowing â€” same rule Meta uses. */
.side-panel:not(:only-child) {
  max-width: 40vw;
}

.side-panel-drag-handle {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 8px;
  cursor: col-resize;
  z-index: 1002;
  transition: background-color ease 0.2s;
}

.side-panel-drag-handle:hover {
  background: inherit;
  filter: brightness(0.8);
}

.side-panel-header {
  padding: 10px 20px;
  border-bottom: 1px solid #e9ecef;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
}

.side-panel-title {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
}

.side-panel-close-button {
  background-color: transparent;
  border: none;
  cursor: pointer;
  padding: 8px;
  border-radius: 4px;
  color: #6c757d;
  font-size: 18px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  transition: all 0.2s ease;
}

.side-panel-close-button:hover {
  background-color: rgba(0, 0, 0, 0.1);
  color: #495057;
}

.side-panel-filters {
  padding: 10px 16px;
  border-bottom: 1px solid rgb(226, 230, 234);
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.side-panel-filters-col {
  flex: 1;
  min-width: 140px;
}

.side-panel-filters-col .form-control {
  width: 100%;
  box-sizing: border-box;
}

.side-panel-filters label {
  display: block;
  font-size: 11px;
  color: #6c757d;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  margin-bottom: 2px;
}

.jobs-panel-filters {
  align-items: flex-start;
}

.jobs-panel-filters .jobs-filter-col {
  /* Flexible columns that FILL the whole filter bar (no leftover gap on the
     right when wide) and shrink gracefully on a narrow panel — replacing the
     fixed widths that left empty space when wide and wrapped awkwardly when
     narrow. flex-basis 0 + per-column flex-grow shares the row by weight. */
  flex: 1 1 0;
  min-width: 120px;
}

.jobs-filter-col--user {
  flex-grow: 1;
}

.jobs-filter-col--type {
  flex-grow: 1.5;
}

.jobs-filter-col--status {
  flex-grow: 1.5;
}

/* Target filter column: pinned (min = max) so it stays compact and leaves
   room for the other filters. Long app names truncate in the trigger and
   are fully readable in the open dropdown (which expands to content).

   150px, not the 140 it was. .target-select-box floors at 150 (#583), so
   inside a 140px column the trigger overflowed it by 10px, which is
   exactly this bar's gap: the gap did not shrink, it was covered. The
   column gives way rather than the floor, because the floor is the newer
   decision and the one about legibility. The 10px comes off the flex:1
   columns beside it, which only shows as wrapping 10px sooner in a very
   narrow panel. */
.jobs-filter-col--target,
.side-panel-filters-col--target {
  flex: 0 0 150px;
  min-width: 150px;
  max-width: 150px;
}
/* Beat the container-scoped `.jobs-panel-filters .jobs-filter-col`
   min-width:120px so the floor actually holds in the jobs panel. */
.jobs-panel-filters .jobs-filter-col--target { min-width: 150px; }

/* User filter column: pinned to 150px (min = max). It was capped at 100px
   when the avatars came out, which left the trigger truncating almost
   every real name — the expanding dropdown made that survivable rather
   than good. 150px shows most names outright. min-width is set here too
   and the selector is scoped under .side-panel-filters so it outranks the
   panel's base `.jobs-panel-filters .jobs-filter-col { min-width: 120px }`. */
.side-panel-filters .side-panel-filters-col--user {
  flex: 0 0 150px;
  min-width: 150px;
  max-width: 150px;
}

/* In the side-panel filter bars (Jobs/Queues/Workflows), the User AND Target
   pickers grow their open dropdown past the (narrow/capped) trigger so long
   "name (email)" rows and long app names stay readable — floored at the
   trigger width, capped so it can't run away. Pickers elsewhere (setup /
   monitor forms) keep their trigger-width menu. */
.side-panel-filters .target-select-box__menu {
  right: auto;
  min-width: 100%;
  width: max-content;
  max-width: 340px;
}

/* A <button> does not inherit font, so this trigger renders at the UA default
   13.33px while the inputs beside it are 12px — visible only once a value is
   picked, since the label inherits from here. */
.side-panel-filters .target-select-box__button {
  font: inherit;
}

/* "All users" is a SELECTED option, not a hint: the dropdown lists it as a
   row and marks it is-selected when nothing else is, exactly as a native
   <select> marks its "all" option. So it renders like any other chosen
   value — plain label text.

   The grey pill it used to wear was an accident of sharing __meta's rule,
   and __meta is the SECONDARY hint printed beside a value, i.e. the one
   treatment that means "this is not the value". It read as an already-applied
   filter. Scoped to the filter bars; setup/monitor forms keep the chip. */
/* TargetSelect sets `is-disabled` whenever it is `disabled` OR `loading`, and
   nothing in this stylesheet ever styled it — so a picker mid-load rendered
   "Loading…" in the ordinary value treatment and read exactly like a filled
   one, with a button that silently did nothing on click.

   Deliberately NOT fixed by restoring the placeholder pill: the filter bars
   strip that on purpose, because "All users" is a SELECTED value there rather
   than a hint (see the rule below, and filter-bar-one-box.test.mjs). The
   loading state needs its own signal, which is what this class was for. */
.target-select.is-disabled {
  opacity: 0.6;
}
.target-select.is-disabled .target-select-box__button {
  cursor: not-allowed;
  background: #f2f4f5;
}

.side-panel-filters .target-select-box__placeholder {
  font-size: 12px;
  background: none;
  padding: 0;
  border-radius: 0;
  color: inherit;
}

/* ONE box for every control in every side-panel filter bar (Jobs, Queues,
   Workflows). This replaced four independent mechanisms that each set the
   same thing and none of which knew about the others: TokenMultiSelect's
   inline `height: 28`, this button's `min-height: 0` + 5px padding,
   form-sm's padding on the input, and a queues-only copy of this rule.
   Measured before: 30 / 30 / 23 / 28 / 28 across the jobs bar, and the
   queues User picker was 30 too.

   An earlier note here warned that a shared box "disturbed the chevrons".
   Re-measured against the real FontAwesome icon: the chevron sits 0.00px
   from the button's vertical centre before and after, because the button is
   already `display: flex; align-items: center` — what changes is the outer
   box, not where the icon lands inside it. */
.side-panel-filters .form-control,
.side-panel-filters .target-select-box__button {
  box-sizing: border-box;
  min-height: 28px;
}

/* min-height can only RAISE a box, never lower one, so the picker button
   needs its padding brought down to form-sm's 4px or it stays at 30px. */
.side-panel-filters .target-select-box__button {
  padding: 4px 6px;
}

/* The select's arrow gap is deliberately NOT handled here: #236 already
   swaps the OS-default arrow for a consistent 12px chevron on every
   `select.form-control` (with padding-right: 30px). Adding a second
   treatment would give the queues bar two competing chevrons. */

.jobs-filter-col--search {
  flex-grow: 1.5;
}

.jobs-filter-type-select {
  width: 100%;
  min-width: 0;
}

/* Scheduled-job status cell: reuse the shared cal-chip but shrunk + muted so
   the scheduled date sits quietly next to the calendar icon. */
.jp-sched-status .cal-chip {
  zoom: 0.8;
  filter: grayscale(1);
  opacity: 0.7;
}

/* The inner CalendarTimestamp renders its own `title` (a UTC timestamp), so
   hovering the date chip showed a DIFFERENT tooltip than hovering the icon.
   Make the chip transparent to the pointer so the whole cell is one hover
   target — the parent .jp-sched-status "Scheduled for …" title covers both
   the icon and the date. */
.jp-sched-status .cal-ts {
  pointer-events: none;
}

.side-panel-tabs {
  display: flex;
  border-bottom: 1px solid #999;
  gap: 2px;
  padding: 0 16px;
}

.side-panel-tab {
  padding: 8px 16px;
  border: none;
  background: transparent;
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  color: #495057;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}

.side-panel-tab.is-active {
  color: #1565c0;
  border-bottom-color: #1565c0;
  font-weight: 600;
}

.side-panel-body {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

.side-panel-body-inner {
  padding: 16px;
}

.side-panel-footer {
  flex-shrink: 0;
  border-top: 1px solid #e9ecef;
  padding: 10px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: rgba(255, 255, 255, 0.6);
  font-size: 12px;
  color: #495057;
}

.side-panel-footer .footer-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.side-panel-footer .footer-actions {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.side-panel table {
  font-size: 12px;
}

/* â”€â”€â”€ Panel-kind backgrounds (verbatim from Meta) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
.side-panel.jobs-panel    { background: #FAF3E0; }
.side-panel.queues-panel  { background: #d4e3e0; }
.side-panel.workflows-panel { background: #d9e6ee; }

/* â”€â”€â”€ Per-queue row + expandable detail â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
.side-panel tr.expanded,
.side-panel tr.expanded:hover,
.side-panel tr.details-row {
  background: rgba(255, 255, 255, 0.7);
}

.side-panel tr.expanded td {
  border-bottom: none;
}

.side-panel .data-table td {
  /* Center row cells vertically so the Status pill/badge (and the single-line
     User/Type/Target cells) line up on the row's mid-line. The nested
     details-row table below keeps its own alignment. */
  vertical-align: middle;
  word-break: break-all;
}

.side-panel .data-table .details-row table thead {
  background: rgba(0, 0, 0, 0.05);
  color: #155724;
}

.side-panel .data-table .details-row table td {
  border-bottom: dotted 1px #fff;
}

.queues-panel td.cell-adset {
  font-weight: bold;
}

.queues-panel .adset-parent-campaign {
  color: #999;
  margin-top: 2px;
  font-style: italic;
  font-size: .9em;
  font-weight: normal;
  word-break: break-all;
}

.queues-panel td,
.jobs-panel td {
  word-break: break-all;
}

/* The rule above keeps long ids/filenames inside narrow list cells, but
   it INHERITS into the expanded detail pane, where the content is prose
   (humanized error text, skip reasons). break-all splits on any character,
   so "…once it appears approved…" rendered as "…appears a / pproved…".
   overflow-wrap: anywhere keeps the no-horizontal-scroll guarantee for
   unbreakable tokens while wrapping prose on word boundaries. Cells that
   genuinely need break-all set it on themselves and are unaffected. */
.queues-panel tr.details-row > td,
.jobs-panel tr.details-row > td {
  word-break: normal;
  overflow-wrap: anywhere;
}

/* A creative-set name is one 100-char token whose only natural break is the
   date's hyphen, so `anywhere` orphaned "2026-06-" on its own line and broke
   the rest mid-token anyway. Fill each line instead. */
.jp-set-name {
  word-break: break-all;
}

/* â”€â”€â”€ Queue detail card (per rotation, per pending block) â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
.queue-detail {
  border-radius: 6px;
  padding: 12px;
  background-color: rgba(255, 255, 255, 0.7);
}

.rotation-asset-card-grid {
  display: flex;
  gap: 16px;
  align-items: flex-start;
}

.rotation-asset-card-grid > * {
  min-width: 0;
}

.rotation-asset-card-grid > :first-child {
  flex: 0 0 30%;
}

.rotation-asset-card-grid > :last-child {
  flex: 0 0 70%;
  min-width: 0;
}

.rotation-asset-card-right {
  border-left: 1px solid #dee2e6;
  padding-left: 12px;
}

.rotation-asset-row {
  border-top: 1px dotted #dee2e6;
  padding-top: 6px;
}

.rotation-asset-row:first-child {
  border-top: none;
  padding-top: 0;
}

@media (max-width: 900px) {
  .rotation-asset-card-grid {
    flex-direction: column;
    gap: 10px;
  }

  .rotation-asset-card-right {
    border-left: none;
    border-top: 1px solid #dee2e6;
    padding-left: 0;
    padding-top: 10px;
  }
}

.queue-detail.ongoing    { background-color: #ffffcc; }
.queue-past-rotations .queue-detail { background-color: rgba(0, 0, 0, 0.03); }
.queue-detail.done       { border-color: #28a745; background-color: #28a7450d; }
.queue-detail.failed     { border-color: #cc0000; background-color: #ffefef; }
.queue-detail.processing { border-color: gold; background-color: #ffffef; }

.queue-item .queue-detail {
  border-radius: 0 0 4px 4px;
}

.queue-card {
  border-radius: 8px;
  padding: 15px;
  margin: 10px;
  background-color: rgba(255, 255, 255, 0.3);
}

/* â”€â”€â”€ Schedule-day chip (verbatim) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
.btn-schedule-selected {
  background-color: #1565c0 !important;
  color: white !important;
  border-color: #1565c0 !important;
}

/* Pill geometry for the rotation-day chips. Was 6 inline style props
   duplicated in QueueDefaultsModal; both pickers use this now.
   `--compact` keeps the shape but tightens it for the dense queue editor. */
.btn-schedule-day {
  padding: 6px 10px !important;
  border-radius: 16px;
  font-size: 12px;
  font-weight: 600;
}

.btn-schedule-day--compact {
  padding: 3px 9px !important;
  font-size: 11px;
}

/* â”€â”€â”€ Performance-snapshot list â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
.queue-perf-list {
  list-style: none;
  padding: 0;
  margin: 6px 0 0 0;
  display: grid;
  gap: 4px;
}
.queue-perf-list li {
  font-size: 12px;
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.queue-perf-list li .perf-value {
  font-weight: 600;
}
.queue-perf-list li.is-paused .perf-value { color: #cc0000; }
.queue-perf-list li.is-best   .perf-value { color: #28a745; }

/* â”€â”€â”€ No-eligible banner (yellow) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
.queue-no-eligible-banner {
  background: #fef3c7;
  border: 1px solid #f59e0b;
  padding: 10px;
  border-radius: 4px;
  color: #78350f;
  font-size: 12px;
  margin: 8px 0;
}

/* â”€â”€â”€ Text Assets Tabs (ported from MetaAssetManager) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
.text-assets-tabs {
  display: flex;
  border-bottom: 1px solid #dee2e6;
  background: #f8f9fa;
}

.text-assets-tab {
  padding: 10px 20px;
  border: none;
  border-top: 2px solid transparent;
  background: transparent;
  color: #6c757d;
  cursor: pointer;
  font-weight: normal;
  font-size: 14px;
  position: relative;
  border-bottom: 1px solid transparent;
  margin-bottom: -1px;
  transition: all 0.2s ease;
}

.text-assets-tab:hover:not(.active) {
  background: #e9ecef;
  color: #495057;
}

.text-assets-tab.active {
  background: #ffffff;
  color: #007bff;
  border-top-color: #007bff;
  border-bottom-color: #ffffff;
  font-weight: 600;
}

.manual-text-section {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.manual-text-grid {
  display: flex;
  gap: 24px;
}

.manual-text-column {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.manual-text-title {
  font-size: 13px;
  font-weight: 600;
  color: #495057;
}

.manual-text-input {
  padding: 8px 10px;
  border: 1px solid #ced4da;
  border-radius: 6px;
  font-size: 13px;
  width: 100%;
}

.manual-text-input:focus {
  outline: none;
  border-color: #007bff;
  box-shadow: 0 0 0 2px rgba(0,123,255,0.15);
}

.manual-text-row {
  display: flex;
  gap: 6px;
  align-items: center;
}

.manual-text-actions {
  display: flex;
  justify-content: flex-start;
}

/* â”€â”€â”€ Spend / performance progress bar â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
.spend-progress-bar {
  display: inline-block;
  width: 40px;
  height: 6px;
  background: #e0e0e0;
  border-radius: 3px;
  overflow: hidden;
}

.spend-progress-fill {
  display: block;
  height: 100%;
  background: #198754;
}

/* Loading state for performance cells: three blinking dots. A dash in
 * a perf column reads as "no data / bug" while the metrics query is
 * still in flight - the dots say "coming". */
.perf-loading-dots span {
  display: inline-block;
  width: 4px;
  height: 4px;
  margin: 0 1px;
  border-radius: 50%;
  background: #adb5bd;
  animation: perf-dot-blink 1.2s infinite;
}
.perf-loading-dots span:nth-child(2) { animation-delay: 0.2s; }
.perf-loading-dots span:nth-child(3) { animation-delay: 0.4s; }
@keyframes perf-dot-blink {
  0%, 80%, 100% { opacity: 0.25; }
  40% { opacity: 1; }
}

/* â”€â”€â”€ Column selector dropdown â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
.column-selector {
  position: relative;
}

.column-selector-panel {
  position: absolute;
  right: 0;
  top: 110%;
  background: #fff;
  border: 1px solid #dee2e6;
  border-radius: 6px;
  padding: 8px 10px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
  z-index: 15;
  min-width: 180px;
}

.column-selector-option {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
  cursor: pointer;
}

/* â”€â”€â”€ User management table (ported verbatim from MetaAssetManager) â”€â”€ */
.table-container {
  overflow: auto;
  height: 100%;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
}

.user-management-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  zoom: .8;
}

.user-management-table th {
  background: #f9fafb;
  padding: 12px 8px;
  text-align: left;
  font-weight: 600;
  color: #374151;
  border-bottom: 1px solid #e5e7eb;
  position: sticky;
  top: 0;
  z-index: 10;
}

.user-management-table td {
  padding: 12px 8px;
  border-bottom: 1px solid #f3f4f6;
  vertical-align: top;
}

.user-management-table tbody tr:hover { background: #f9fafb; }

/* Scroll inside the container so the sticky thead actually engages
   (same as MetaAssetManager's user-management-table-container). */
.user-management-table-container {
  max-height: calc(100vh - 350px);
  overflow-x: auto;
  overflow-y: auto;
}

/* Sticky first column: username stays visible while scrolling
   horizontally to the permission toggles. */
.user-management-table-container td:first-child {
  position: sticky;
  left: 0;
  z-index: 5;
  background: #fff;
  border-right: 1px solid #e5e7eb;
}
.user-management-table-container th:first-child {
  left: 0;
  z-index: 11; /* above the sticky thead row */
  border-right: 1px solid #e5e7eb;
}
.user-management-table-container tbody tr:hover td:first-child { background: #f9fafb; }

.user-cell { min-width: 120px; }
.user-cell strong { display: block; color: #1f2937; margin-bottom: 2px; }
.user-cell .user-id {
  font-size: 11px; color: #6b7280; font-family: monospace;
}

.folders-cell { min-width: 200px; max-width: 250px; }
.folders-list { max-height: 100px; overflow-y: auto; }
.folder-item {
  margin-bottom: 4px;
  padding: 4px 6px;
  background: #f3f4f6;
  border-radius: 4px;
}
.folder-name { display: block; font-weight: 500; color: #374151; }
.folder-id {
  display: block; font-size: 10px; color: #6b7280; font-family: monospace;
}
.no-folders { color: #9ca3af; font-style: italic; }

.workflows-cell { text-align: center; }
.active-count { font-weight: 600; color: #059669; }
.inactive-count { color: #6b7280; }
.total-count { color: #6b7280; margin-left: 4px; }

.jobs-cell { min-width: 180px; }
.jobs-history { position: relative; }
.total-jobs { font-weight: 600; font-size: 16px; color: #1f2937; }
.monthly-breakdown { margin-top: 8px; }
.mini-table { width: 100%; font-size: 11px; border-collapse: collapse; }
.mini-table th,
.mini-table td {
  padding: 2px 4px;
  text-align: left;
  border-bottom: 1px solid #f3f4f6;
}
.mini-table th { font-weight: 500; color: #6b7280; background: #f9fafb; }

.last-access-cell { min-width: 110px; }
.access-date { font-weight: 500; color: #374151; }
.access-time { font-size: 11px; color: #6b7280; }
.never-accessed { color: #9ca3af; font-style: italic; }

.permission-cell { text-align: center; padding: 12px; }

.unknown-permission {
  color: #9ca3af;
  font-style: italic;
  font-size: 12px;
}

.section-container {
  background: #ffffff;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 16px;
}

.target-select,
.target-select-box {
  position: relative;
  /* Block-level flex that FILLS its parent (width:100%) instead of the
     old inline-flex, which shrink-wrapped to its content — narrow on the
     placeholder, then ballooning (and overflowing its column) once a
     target was picked. Now the trigger always fills the column and the
     label truncates, so the width is stable whether or not a value is
     selected. flex:1 still lets it grow to fill a flex-row parent. */
  display: flex;
  width: 100%;
  flex: 1;
  min-width: 150px;
}

.target-select-box__button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  min-height: 38px;
  text-align: left;
  background: #fff;
}

.target-select-box__menu {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  max-height: 320px;
  overflow-y: auto;
  padding: 6px;
  border: 1px solid #d7dce2;
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 12px 28px rgba(15, 23, 42, 0.12);
}

.target-select-box__option {
  display: flex;
  align-items: center;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  outline: 0;
  box-shadow: none;
  appearance: none;
  border-radius: 8px;
  background: transparent;
  color: #212529;
  text-align: left;
  cursor: pointer;
}

.target-select-box__option:hover:not(:disabled),
.target-select-box__option.is-selected {
  background: #eef6ff;
}

.target-select-box__option:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.target-select-box__value {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  width: 100%;
}

.target-select-box__label {
  min-width: 0;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.target-select-box__meta,
.target-select-box__placeholder {
  background: #ddd;
  color: #5c6773;
  font-size: 0.8em;
  padding: 1px 6px;
  border-radius: 999px;
}

.target-select-box__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.8em;
  padding: 1px 6px;
  border-radius: 999px;
  background: #ddd;
  color: #5c6773;
  font-size: 0.8em;
  font-weight: 600;
  line-height: 1.4;
}

/* â”€â”€â”€ Step 5 Triggers â€” inline config boxes (green=queue, blue=scheduled) â”€â”€ */
.trigger-config-box {
  margin-top: 16px;
  padding: 18px;
  border-radius: 12px;
  border: 1px solid #d0d7de;
}
.trigger-config-box--blue {
  background: #f5faff;
  border-color: #2c7be5;
}
.trigger-config-box--green {
  background: #f4fbf6;
  border-color: #2ea44f;
  border-radius: 12px 0 12px 12px;
}
.trigger-config-box__title {
  font-weight: 700;
  margin-bottom: 10px;
}
.trigger-config-box__row {
  display: flex;
  gap: 12px;
  align-items: end;
}
.trigger-config-field { flex: 1; }
.trigger-config-field--time { max-width: 170px; }
.trigger-config-box__help {
  margin-top: 8px;
  font-size: 12px;
}
.queue-defaults-inline {}
.queue-defaults-inline__metrics-row {
  margin-top: 14px;
  display: flex;
  gap: 16px;
  align-items: flex-start;
  flex-wrap: wrap;
}
.queue-defaults-inline__metrics-field {
  flex: 1 1 160px;
  min-width: 160px;
}

/* â”€â”€â”€ <campaign> badge â€” prepended to every campaign name display â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
campaign {
  display: inline-block;
  margin-right: 4px;
  vertical-align: middle;
  color: #555;
}
campaign::before {
  content: '\f0a1'; /* fa-bullhorn */
  font-family: 'Font Awesome 6 Free';
  font-weight: 900;
  font-size: 0.85em;
}

/* â”€â”€â”€ <file> â€” wraps every rendered filename in monospace â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
   Use exclusively for actual filenames (e.g. video.mp4, banner.png), never
   for paths or labels. Custom element declared in
   `presentation/web/src/types/jsx-custom.d.ts`. */
file {
  font-family: monospace;
}

/* â”€â”€â”€ <set> badge â€” prepended to every AppLovin creative-set name display â”€â”€ */
set {
  font-size: 0.7em;
  text-transform: uppercase;
  color: #fff;
  background: #6366f1;
  padding: 2px 4px;
  border-radius: 4px;
  font-family: monospace;
  margin-right: 4px;
  vertical-align: middle;
  letter-spacing: 0.5px;
}
set::after {
  content: 'set';
}

/* â”€â”€â”€ <asset> badge â€” prepended to every Media Library asset name â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
asset {
  display: inline-block;
  margin-right: 4px;
  vertical-align: middle;
  color: #555;
}
asset::before {
  content: '\f15b'; /* fa-file */
  font-family: 'Font Awesome 6 Free';
  font-weight: 900;
  font-size: 0.85em;
  margin-right: 3px;
}

/* â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
 * Workflows feature-upgrade popup. Direct port of MetaAssetManager
 * App.css `.feature-upgrade-*` rules. Used by FeatureUpgradePopup
 * (the placeholder Workflows upsell shown by the header button).
 * â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
.feature-upgrade-overlay {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2000;
  animation: fadeIn 0.3s ease;
}

.feature-upgrade-modal {
  display: flex;
  flex-direction: column;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border-radius: 16px;
  box-shadow: 0 25px 50px rgba(0, 0, 0, 0.3);
  max-width: 600px;
  width: 90vw;
  max-height: 90vh;
  overflow: hidden;
  animation: slideUp 0.4s ease;
}

.feature-upgrade-header {
  position: relative;
  padding: 32px 40px 24px;
  text-align: center;
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
}

.feature-icon {
  position: relative;
  display: inline-block;
  font-size: 48px;
  margin-bottom: 16px;
  opacity: 0.9;
}

.upgrade-crown {
  position: absolute;
  top: -8px;
  right: -8px;
  font-size: 16px;
  color: gold;
  text-shadow: 0 0 8px rgba(255, 215, 0, 0.8);
  animation: crownGlow 2s infinite alternate;
}

.feature-upgrade-header h2 {
  margin: 0 0 8px;
  font-size: 28px;
  font-weight: 700;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}

.feature-upgrade-header .close-button {
  position: absolute;
  top: 20px;
  right: 20px;
  background: rgba(255, 255, 255, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.3);
  color: white;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s ease;
}

.feature-upgrade-header .close-button:hover {
  background: rgba(255, 255, 255, 0.3);
}

.feature-upgrade-content {
  flex: 1;
  overflow: auto;
  padding: 24px 40px 40px;
}

.feature-paragraph {
  font-size: 16px;
  line-height: 1.6;
  margin-bottom: 20px;
  opacity: 0.95;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}

.feature-paragraph:last-of-type {
  margin-bottom: 32px;
}

.feature-cta {
  text-align: center;
  padding-top: 24px;
  border-top: 1px solid rgba(255, 255, 255, 0.2);
}

.cta-text {
  font-size: 18px;
  font-weight: 600;
  margin-bottom: 20px;
  color: #fef3cd;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}

.upgrade-button {
  background: linear-gradient(135deg, #ffd700 0%, #ffb347 100%);
  color: #1a1a1a;
  border: none;
  padding: 12px 32px;
  font-size: 16px;
  font-weight: 600;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 4px 15px rgba(255, 215, 0, 0.3);
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.upgrade-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 25px rgba(255, 215, 0, 0.4);
  background: linear-gradient(135deg, #ffed4e 0%, #ffc947 100%);
}

.upgrade-button i {
  opacity: 0.8;
}

@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes slideUp {
  from { opacity: 0; transform: translateY(40px) scale(0.95); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes crownGlow {
  from { opacity: 0.8; transform: scale(1); }
  to   { opacity: 1;   transform: scale(1.1); }
}

/* Platform badges: green Android robot, blue-gray Apple. Applied
   globally so every Android/iOS marker across the SPA picks up the
   same colour without each component having to re-style. */
.fa-android { color: #37b24d; }
.fa-apple   { color: #8e8e93; }

/* --- Step 5 Triggers cards (ported verbatim from Google Creative
   Copilot). Purple = "now", blue = "scheduled", green = "queue".
   Selected blue/green cards lift translateY(18px) and drop their
   bottom border so they merge into the config panel that drops below
   them. Locked cards (no queue_access) dim + show a gold crown. --- */
.trigger-card-row {
  display: flex;
  gap: 12px;
}

.trigger-card {
  flex: 1;
  text-align: left;
  border: 1px solid #d0d7de;
  border-radius: 12px;
  padding: 16px;
  cursor: pointer;
  background: #fff;
  box-shadow: none;
  transition: box-shadow 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}

.trigger-card:hover {
  transform: translateY(-1px);
}

.trigger-card__title {
  font-weight: 700;
  font-size: 15px;
  margin-bottom: 4px;
}

.trigger-card__blurb {
  font-size: 13px;
  color: #555;
  line-height: 1.45;
}

.trigger-card--purple {
  background: #faf6ff;
  border-color: #e3d6f5;
}

.trigger-card--purple.is-selected {
  border-color: #7948c5;
  box-shadow: 0 0 0 2px rgba(121, 72, 197, 0.18);
}

.trigger-card--blue {
  background: #f5faff;
  border-color: #d0e3ff;
}

.trigger-card--blue.is-selected {
  border-color: #2c7be5;
  box-shadow: none;
  transform: translateY(18px);
  border-bottom: none;
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 0;
}

.trigger-card--green {
  background: #f4fbf6;
  border-color: #cdebd6;
}

.trigger-card--green.is-selected {
  border-color: #2ea44f;
  box-shadow: none;
  transform: translateY(18px);
  border-bottom: none;
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 0;
}

.trigger-card--locked {
  opacity: 0.65;
  cursor: not-allowed;
}

/* Neutralize the base .trigger-card:hover lift (translateY(-1px)) so a
   locked card doesn't feel interactive. */
.trigger-card--locked:hover {
  transform: none;
}

.trigger-card__crown {
  margin-left: 6px;
  color: gold;
  font-size: 0.85em;
}

.agc-preview-card-stack {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.agc-preview-card {
  border: 1px solid #d9dee6;
  border-radius: 8px;
  background: #fff;
  overflow: hidden;
}

.agc-preview-card.is-blocked {
  border-color: #ffd8a8;
}

.agc-preview-card-summary {
  width: 100%;
  list-style: none;
  cursor: pointer;
  padding: 10px 16px;
  border: 0;
  background: #fff;
  text-align: left;
}

.agc-preview-card-title-row {
  display: flex;
  /* stretch: the title box becomes the row's height and centres its own
     content, so a one-line name sits level with the chips instead of a
     couple of pixels above them (a chip's padding makes its box taller
     than a line of text). The chips then pin themselves to the top —
     see .agc-preview-card-chips — so a title that wraps to two lines
     keeps them beside its FIRST line rather than floating them down to
     its middle, which is what plain `center` on this row used to do. */
  align-items: stretch;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.agc-preview-card-title {
  display: inline-flex;
  /* Centres the chevron, the badge and the name against each other, and
     against the chips once the row stretches this box to its height. */
  align-items: center;
  gap: 8px;
  /* Basis 0, not auto: on `auto` the title's hypothetical width is the whole
     name, so flex-wrap moved the chips to their own line before any shrinking
     happened. At 0 both fit one line and the name wraps under itself. */
  flex: 1 1 0;
  min-width: 0;
  font-size: 14px;
  font-weight: 600;
  color: #212529;
}

/* A set name is one 100-char token; clipped it read "2026-08-25_Crada…" on the
   last screen before dispatch, and the tail is what tells two sets apart. */
.agc-preview-card-title span {
  white-space: normal;
  word-break: break-all;
}

.agc-preview-card-title set {
  /* No manual nudge: the 2px here was pushing the badge down to meet an
     align-items: flex-start row. The row centres now, so it would push
     the badge 2px BELOW the name it sits against. */
  flex: 0 0 auto;
}

.agc-preview-card-chips {
  display: inline-flex;
  flex-wrap: wrap;
  flex: 0 0 auto;
  /* Top, not stretched: the row's height is the title's once the name
     wraps, and the chips belong beside its first line. */
  align-self: flex-start;
  gap: 8px;
  font-size: 12px;
  color: #495057;
}

.agc-preview-card-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  border-radius: 999px;
  background: #f8f9fa;
  border: 1px solid #e9ecef;
}

.agc-preview-card-chip--error {
  color: #c92a2a;
  background: #fff5f5;
  border-color: #ffc9c9;
}

.agc-preview-card-chip--reused {
  color: #d9480f;
  background: #fff4e6;
  border-color: #ffd8a8;
}

.agc-preview-card-body {
  display: grid;
  gap: 14px;
  padding: 12px 16px 16px;
  border-top: 1px solid #edf0f2;
}

.agc-preview-card-section {
  display: grid;
  gap: 6px;
}

.agc-preview-card-section-title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 700;
  color: #495057;
  text-transform: uppercase;
  letter-spacing: 0;
}

.agc-preview-card-section-title--error {
  color: #c92a2a;
}

.agc-preview-card-list--plain {
  display: grid;
  gap: 4px;
  padding-left: 0;
  list-style: none;
}

.agc-preview-card-list--plain li {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 5px 8px;
  border: 1px solid #e9ecef;
  border-radius: 6px;
  background: #f8f9fa;
}

.agc-preview-card-list--plain file {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.agc-preview-card-source-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
  font-size: 11px;
  padding: 1px 6px;
  border-radius: 999px;
  background: #e7f5ff;
  color: #1864ab;
}

.agc-preview-card-reused-row {
  background: #fff8f0 !important;
  border-color: #ffe8cc !important;
  font-style: italic;
}

.agc-preview-card-source-chip--reused {
  background: #fff4e6;
  color: #d9480f;
}

/* Jobs detail: this campaign did not get its own set, it shares the one
   created above. Same orange the create preview uses for a shared set. */
/* Which app the rows beneath belong to. Only rendered when the job spans
   apps: on an ordinary one a lone header over everything is furniture.
   Structure rather than a per-row chip, because a chip can be skimmed past
   and a heading cannot. Neutral: it states a fact, it is not a warning. */
.jp-detail-dest-app {
  margin: 8px 0 2px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #495057;
}

.jp-detail-dest-app:first-child { margin-top: 0; }

/* The rows sit under their heading, which is what makes it a grouping
   rather than a caption. */
.jp-detail-dest-list--grouped .jp-detail-dest { margin-left: 12px; }

.jp-detail-dest-attached {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 999px;
  font-size: 11px;
  background: #fff4e6;
  color: #d9480f;
}

/* Step 0 view-type picker (Monitor / Workflow) â€” vertical card stack. */
.mvt-cards {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 8px 0;
}

.wt-cards {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 8px 0;
}

.wt-card {
  position: relative;
  border: 2px solid transparent;
  border-radius: 10px;
  padding: 14px 16px;
  text-align: left;
  cursor: pointer;
  background: #fff;
  transition: transform 80ms ease, border-color 120ms ease, box-shadow 120ms ease;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
  font-family: inherit;
  width: 100%;
}

.wt-card:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}

.wt-card--disabled,
.wt-card--disabled:hover {
  cursor: not-allowed;
  opacity: 0.55;
  transform: none;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
}

/* When any card is selected, dim the other (non-selected) cards. */
.wt-cards:has(.wt-card--selected) .wt-card:not(.wt-card--selected),
.mvt-cards:has(.wt-card--selected) .wt-card:not(.wt-card--selected) {
  opacity: 0.7;
}

.wt-cards:has(.wt-card--selected) .wt-card--disabled {
  opacity: 0.55;
}

.wt-card__icon {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  margin-bottom: 8px;
  font-size: 18px;
}

.wt-card--blue   .wt-card__icon { color: #2c7be5; }
.wt-card--green  .wt-card__icon { color: #2ea44f; }
.wt-card--purple .wt-card__icon { color: #7948c5; }
.wt-card--orange .wt-card__icon { color: #f97316; }

.wt-card__title {
  font-weight: 700;
  font-size: 14px;
  margin-bottom: 4px;
}

/* Premium-locked Monitor view-type card (Impact Analysis without access). */
.wt-card__crown {
  margin-left: 6px;
  color: #f59f00;
  font-size: 0.85em;
}
.wt-card--premium .wt-card__icon {
  opacity: 0.85;
}

.wt-card__desc {
  font-size: 12px;
  color: #555;
  line-height: 1.4;
}

.wt-card--blue   { border-color: #d0e3ff; background: #f5faff; }
.wt-card--green  { border-color: #cdebd6; background: #f4fbf6; }
.wt-card--purple { border-color: #e3d6f5; background: #faf6ff; }
.wt-card--orange { border-color: #fde0c8; background: #fff7ed; }

.wt-card--blue.wt-card--selected   { border-color: #2c7be5; box-shadow: 0 0 0 2px rgba(44, 123, 229, 0.2); }
.wt-card--green.wt-card--selected  { border-color: #2ea44f; box-shadow: 0 0 0 2px rgba(46, 164, 79, 0.2); }
.wt-card--purple.wt-card--selected { border-color: #7948c5; box-shadow: 0 0 0 2px rgba(121, 72, 197, 0.2); }
.wt-card--orange.wt-card--selected { border-color: #f97316; box-shadow: 0 0 0 2px rgba(249, 115, 22, 0.2); }

/* Selected card â€” CSS-only triangle pointing right (suggests "this is
   the column you'll jump to next"). Two pseudo-elements: outline +
   fill triangles layered so the card looks like it has a pointy edge. */
.wt-card--selected::before,
.wt-card--selected::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 0;
  height: 0;
  pointer-events: none;
}

.wt-card--selected::before {
  right: -16px;
  transform: translateY(-50%);
  border-top: 16px solid transparent;
  border-bottom: 16px solid transparent;
}

.wt-card--selected::after {
  right: -13.5px;
  transform: translateY(-50%);
  border-top: 14px solid transparent;
  border-bottom: 14px solid transparent;
}

.wt-card--blue.wt-card--selected::before    { border-left: 16px solid #2c7be5; }
.wt-card--blue.wt-card--selected::after     { border-left: 14px solid #f5faff; }
.wt-card--green.wt-card--selected::before   { border-left: 16px solid #2ea44f; }
.wt-card--green.wt-card--selected::after    { border-left: 14px solid #f4fbf6; }
.wt-card--purple.wt-card--selected::before  { border-left: 16px solid #7948c5; }
.wt-card--purple.wt-card--selected::after   { border-left: 14px solid #faf6ff; }
.wt-card--orange.wt-card--selected::before  { border-left: 16px solid #f97316; }
.wt-card--orange.wt-card--selected::after   { border-left: 14px solid #fff7ed; }

/* ----- Monitor: Activity & Performance overview ----- */
/* Mini step column â€” for the leftmost narrow Step 0 (view-type picker).
   Ports MetaAssetManager's WorkflowTypeStep.css `.step-column-mini`. */
.step-column-mini {
  min-width: 300px;
  max-width: 300px;
  background: none;
  border: none;
  box-shadow: none;
  opacity: 1 !important;
  /* Snap to start so the canvas's scroll-snap pulls this narrow column
     flush against the left edge instead of centering the next column. */
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  padding: 16px;
  box-sizing: border-box;
}

.monitor-overview-step {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 8px;
  flex: 1 1 0%;
  min-height: 0;
  overflow: hidden;
}

.monitor-overview-toolbar {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: stretch;
}

.monitor-overview-toolbar-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: end;
}

.monitor-overview-toolbar-row-primary label {
  min-width: 180px;
}

.monitor-overview-toolbar-row-secondary label {
  min-width: 140px;
}

.monitor-overview-toolbar label {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 140px;
  text-transform: uppercase;
  font-size: 11px;
  color: #475569;
}

.monitor-overview-toolbar select {
  height: 34px;
  border: 1px solid #d8dee6;
  border-radius: 8px;
  padding: 0 10px;
  background: #fff;
}

.monitor-overview-toolbar-row > button {
  height: 34px;
  border: 1px solid #d8dee6;
  border-radius: 8px;
  padding: 0 12px;
  background: #f8f9fb;
}

.monitor-overview-layout {
  display: grid;
  grid-template-columns: 72% auto;
  gap: 12px;
  align-items: stretch;
  flex: 1 1 auto;
  max-height: 700px;
  min-height: 0;
  overflow: hidden;
}

.monitor-overview-chart-panel {
  min-width: 0;
  border: 1px solid #e6ebf2;
  border-radius: 12px;
  padding: 10px;
  background: linear-gradient(180deg, #f8fbff 0%, #ffffff 55%);
  height: 100%;
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  max-height: none;
}

.monitor-overview-meta {
  margin-bottom: 8px;
  color: #475569;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
}

.monitor-overview-refresh-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid #bfdbfe;
  border-radius: 999px;
  padding: 2px 8px;
  background: #eff6ff;
  color: #1d4ed8;
  font-size: 11px;
  font-weight: 600;
}

.monitor-overview-refresh-spinner {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transform: scale(0.72);
  transform-origin: center;
  width: 10px;
  height: 10px;
}

.monitor-overview-warning {
  margin-bottom: 10px;
}

.monitor-overview-chart-canvas {
  position: relative;
  flex: 1 1 auto;
  height: auto;
  min-height: 0;
  overflow: visible;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-bottom: 8px;
}

.monitor-overview-loading-center {
  width: 100%;
  height: 100%;
  min-height: 190px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.monitor-overview-chart-canvas canvas {
  display: block;
  width: 100% !important;
}

.monitor-overview-clouds {
  min-width: 0;
  display: flex;
  flex-direction: column;
  flex: 1 1 0;
  height: 100%;
  gap: 10px;
  min-height: 0;
  overflow: auto;
}

.monitor-overview-cloud {
  display: flex;
  flex: 1 1 0;
  flex-direction: column;
  border: 1px solid #e6ebf2;
  border-radius: 12px;
  padding: 10px;
  min-height: 0;
  background: linear-gradient(180deg, rgba(248, 251, 255, 0.96) 0%, rgba(244, 248, 252, 0.92) 100%);
}

.monitor-overview-cloud h4 {
  border-bottom: solid 1px #dfdfdf;
  padding-bottom: 8px;
  margin: 0 0 8px 0;
  font-size: 13px;
}

.monitor-overview-cloud-body {
  display: flex;
  flex: 1 1 auto;
  align-items: stretch;
  justify-content: center;
  min-height: 140px;
  overflow: hidden;
}

.monitor-overview-tag-cloud {
  width: 100%;
  height: 100%;
  min-height: 140px;
  padding: 0;
  overflow: hidden;
}

.monitor-overview-empty {
  color: #64748b;
  font-size: 13px;
}

.monitor-overview-actions {
  display: flex;
  justify-content: flex-end;
}

/* ----- Monitor: Asset performance ----- */
.asset-performance {
  font-family: arial, sans-serif;
}

.asset-performance td {
  font-size: 0.8em;
}

/* Rows with no file mapping get a gray question mark instead of a checkbox,
   in the checkbox's own 13px box and margins so the two line up. */
.asset-performance .asset-unmapped-icon {
  color: #adb5bd;
  font-size: 13px;
  margin: 3px 3px 3px 4px;
}

.data-table.asset-performance td {
  word-break: break-all;
}

.data-table.asset-performance td.td-name-text {
  font-weight: normal;
  min-width: 200px;
}

/* ----- Monitor: shared utilities ----- */
.ad-account-label {
  color: #6c757d;
  display: block;
  margin-bottom: 4px;
}

.loading-message {
  color: #6c757d;
  margin-left: 12px;
}

.error-message {
  color: #dc3545;
  margin-left: 12px;
}

.empty-state {
  padding: 24px 16px;
  text-align: center;
  color: #6c757d;
  font-style: italic;
  background: white;
}

.loading-spinner {
  display: inline-block;
  width: 20px;
  height: 20px;
  border: 2px solid #f3f3f3;
  border-top: 2px solid #007bff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.spinner-small {
  width: 12px;
  height: 12px;
}

.agc-preview-card-stack {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.agc-preview-card {
  border: 1px solid #d9dee6;
  border-radius: 12px;
  background: #fff;
  overflow: hidden;
}

.agc-preview-card-summary {
  list-style: none;
  cursor: pointer;
  padding: 10px 16px;
}

.agc-preview-card-summary::-webkit-details-marker {
  display: none;
}

/* The preview card's title row, title and chips are defined once, higher
   up. A second copy lived here and won on source order, so every edit to
   the first block was silently discarded — including two attempts at the
   vertical alignment of this very row. Each rule here was a strict subset
   of the one above, so removing them changes nothing except which copy
   applies. */

.agc-preview-card-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  border-radius: 999px;
  background: #f8f9fa;
  border: 1px solid #e9ecef;
}

.agc-preview-card-body {
  display: grid;
  gap: 14px;
  padding: 0 16px 16px;
  border-top: 1px solid #edf0f2;
}

.agc-preview-card-section {
  display: grid;
  gap: 6px;
}

.agc-preview-card-section-title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 700;
  color: #495057;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.agc-preview-card-list {
  margin: 10px 0 0 0;
  padding-left: 0;
  color: #212529;
  font-size: 13px;
}

.agc-preview-card-list li + li {
  margin-top: 4px;
}

/* Validation rows are .setup-error, whose global 8px margin-top pushed the
   first one off the section title. The list's `li + li` owns the gap. */
.agc-preview-card-list .setup-error {
  margin-top: 0;
}
.agc-preview-card-list .setup-error + .setup-error {
  margin-top: 4px;
}

.trigger-card-row {
  display: flex;
  gap: 12px;
}

.trigger-card {
  flex: 1;
  text-align: left;
  border: 1px solid #d0d7de;
  border-radius: 12px;
  padding: 16px;
  cursor: pointer;
  background: #fff;
  box-shadow: none;
  transition: box-shadow 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}

.trigger-card:hover {
  transform: translateY(-1px);
}

.trigger-card__title {
  font-weight: 700;
  font-size: 15px;
  margin-bottom: 4px;
}

.trigger-card__blurb {
  font-size: 13px;
  color: #555;
  line-height: 1.45;
}

.trigger-card--purple {
  background: #faf6ff;
  border-color: #e3d6f5;
}

.trigger-card--purple.is-selected {
  border-color: #7948c5;
  box-shadow: 0 0 0 2px rgba(121, 72, 197, 0.18);
}

.trigger-card--blue {
  background: #f5faff;
  border-color: #d0e3ff;
}

.trigger-card--blue.is-selected {
  border-color: #2c7be5;
  box-shadow: none;
  transform: translateY(18px);
  border-bottom: none;
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 0;
}

.trigger-card--green {
  background: #f4fbf6;
  border-color: #cdebd6;
}

.trigger-card--green.is-selected {
  border-color: #2ea44f;
  box-shadow: none;
  transform: translateY(18px);
  border-bottom: none;
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 0;
}

.trigger-card--locked {
  opacity: 0.65;
  cursor: not-allowed;
}

/* Neutralize the base .trigger-card:hover lift (translateY(-1px)) so a
   locked card doesn't feel interactive. */
.trigger-card--locked:hover {
  transform: none;
}

.trigger-card__crown {
  margin-left: 6px;
  color: gold;
  font-size: 0.85em;
}

.trigger-status-card {
  margin-bottom: 18px;
  padding: 18px 20px;
  border-radius: 16px;
  border: 1px solid #cfd6dc;
  background: linear-gradient(180deg, #f7f8fa 0%, #edf0f3 100%);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
}

.trigger-status-card--active {
  border-color: #b8e0c3;
  background: linear-gradient(180deg, #f5fbf7 0%, #e7f6eb 100%);
}

.trigger-status-card--paused {
  border-color: #cfd6dc;
  background: linear-gradient(180deg, #f7f8fa 0%, #edf0f3 100%);
}

.trigger-status-card__title {
  font-size: 14px;
  font-weight: 800;
  color: #44515c;
}

.trigger-status-card--active .trigger-status-card__title {
  color: #1f6b35;
}

.trigger-status-card__blurb {
  margin-top: 4px;
  font-size: 12px;
  color: #62707a;
  max-width: 680px;
}

.trigger-status-card--active .trigger-status-card__blurb {
  color: #3f6e4c;
}

.trigger-status-toggle {
  display: inline-flex;
  flex-shrink: 0;
  padding: 4px;
  border-radius: 999px;
  border: 1px solid #cfd6dc;
  background: rgba(255, 255, 255, 0.72);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.85);
  gap: 4px;
}

.trigger-status-card--active .trigger-status-toggle {
  border-color: #c3dfca;
}

.trigger-status-toggle__option {
  border: 0;
  background: transparent;
  color: #62707a;
  padding: 9px 16px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 800;
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease, box-shadow 0.18s ease;
}

.trigger-status-toggle__option:hover {
  color: #2f3a43;
}

.trigger-status-card--active .trigger-status-toggle__option {
  color: #4b6a55;
}

.trigger-status-card--active .trigger-status-toggle__option:hover {
  color: #1f6b35;
}

/* Locked Active option â€” admin + test campaign (testing safety policy). */
.trigger-status-toggle__option:disabled {
  cursor: not-allowed;
  opacity: 0.45;
}

.trigger-status-toggle__option:disabled:hover {
  color: #62707a;
}

.trigger-status-card--paused .trigger-status-toggle__option.active {
  background: linear-gradient(135deg, #7a8894 0%, #909ea8 100%);
  color: #fff;
  box-shadow: 0 8px 18px rgba(91, 104, 116, 0.22);
}

.trigger-status-card--active .trigger-status-toggle__option.active {
  background: linear-gradient(135deg, #2ea44f 0%, #43bc66 100%);
  color: #fff;
  box-shadow: 0 8px 18px rgba(46, 164, 79, 0.24);
}

.trigger-status-toggle__option:focus-visible {
  outline: 2px solid #95a3ad;
  outline-offset: 2px;
}

.trigger-status-card--active .trigger-status-toggle__option:focus-visible {
  outline-color: #6dc287;
}

@media (max-width: 900px) {
  .trigger-status-card {
    flex-direction: column;
    align-items: stretch;
  }

  .trigger-status-toggle {
    width: 100%;
  }

  .trigger-status-toggle__option {
    flex: 1;
  }
}

.trigger-config-box {
  margin-top: 16px;
  padding: 18px;
  border-radius: 12px;
  border: 1px solid #d0d7de;
}

.trigger-config-box--blue {
  background: #f5faff;
  border-color: #d0e3ff;
}

.trigger-config-box--green {
  background: #f4fbf6;
  border-color: #cdebd6;
}

.trigger-config-box__title {
  font-weight: 700;
  margin-bottom: 10px;
}

.trigger-config-box__row {
  display: flex;
  gap: 12px;
  align-items: end;
}

.trigger-config-field {
  flex: 1;
}

.trigger-config-field--time {
  max-width: 170px;
}

.trigger-config-box__help {
  margin-top: 8px;
  font-size: 12px;
}

.queue-defaults-inline {
}

.queue-defaults-inline__metrics-row {
  margin-top: 14px;
  display: flex;
  gap: 16px;
  align-items: flex-start;
  flex-wrap: wrap;
}

.queue-defaults-inline__metrics-field {
  flex: 1 1 160px;
  min-width: 160px;
}

.queue-detail td, .queue-detail button { font-size: 11px; }
.queue-detail button { padding: 0; text-align: left; }

/* Cloud files modal: floating selected-files count, perched above the
 * select-all checkbox so the running total stays visible while
 * scrolling the (sticky-headered) table. */
.source-files-selected-count {
  position: absolute;
  top: 9px;
  right: -18px;
  min-width: 18px;
  padding: 1px 5px;
  border-radius: 0 9px 9px 0;
  background: #198754;
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  line-height: 14px;
  text-align: center;
  pointer-events: none;
  z-index: 3;
}

/* CalendarTimestamp chip CSS ships with @bubbleye-ai/copilot-ui styles.css */

/* Premium crowns on the workflows entry points (button + mode switch)
   shown when the user lacks workflow_access. Click opens the upsell. */
.panel-button__crown,
.workflow-mode-crown {
  margin-left: 5px;
  color: #f59f00;
  font-size: 0.8em;
}

/* -- Setup Filename Processing -> Custom rules ------------------------
   Ported verbatim from metaCreativeCopilot's App.css. A colour layer is
   painted above a transparent-background textarea (the same wysiwyg trick
   NameTemplateEditor uses), so only the property macros get an accent
   while the caret and selection stay native. The two layers must keep
   identical font, size, line-height and padding or the overlay drifts
   away from the text underneath it. */
.manual-rule-wysiwyg {
  position: relative;
  display: flex;
  flex: 1;
}

.manual-rule-wysiwyg textarea {
  position: relative;
  z-index: 2;
  flex: 1;
  background: transparent;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.5;
  padding: 6px 8px;
  border-radius: 4px;
  resize: vertical;
  min-height: 30px;
}

.manual-rule-highlight {
  position: absolute;
  inset: 0;
  z-index: 3;
  color: transparent;
  pointer-events: none;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  overflow: hidden;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.5;
  padding: 7px 9px; /* textarea padding + 1px border */
}

/* Text colors only, and only for the property macros — a background box (or
   coloring every macro) visually bleeds and hides which span is which
   (2026-07-28). Non-property macros keep the textarea's own text color. */
.manual-rule-highlight .rule-macro-concept {
  color: goldenrod;
}

.manual-rule-highlight .rule-macro-category {
  color: #c026d3;
}

.manual-file-type-tabs {
  display: flex;
  gap: 6px;
  margin-bottom: 12px;
}

.manual-file-type-tab {
  display: flex;
  align-items: center;
  padding: 6px 14px;
  border: 1px solid #dee2e6;
  border-radius: 999px;
  background: #fff;
  color: #6c757d;
  cursor: pointer;
  font-size: 13px;
}

.manual-file-type-tab.current {
  border-color: #495057;
  color: #212529;
  font-weight: 600;
}

.manual-file-type-count {
  margin-left: 8px;
  font-size: 11px;
  font-weight: 600;
  border-radius: 10px;
  padding: 1px 8px;
  border: 1px solid #dee2e6;
  color: #6c757d;
}

/* -- Teach by examples: CONCEPT / CATEGORY sub-steps ------------------
   Ported verbatim from metaCreativeCopilot's App.css. Exactly one property
   is tagged at a time, so a row paints ONE live span; the other property's
   saved span stays visible but struck through (.selected-other) so you can
   see what the filename already gives up before choosing this one's
   tokens. The tab tints match the property accents: gold for concept,
   fuchsia for category. */
.extraction-stepper {
  display: flex;
  gap: 4px;
}

.extraction-step {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  border: none;
  border-radius: 6px 6px 0 0;
  background: #fdf6dd;
  color: #495057;
  cursor: pointer;
  font-size: 14px;
  opacity: 0.5;
}

.extraction-step.category {
  background: #fbeafd;
}

.extraction-step.current {
  opacity: 1;
  font-weight: 700;
  color: #333;
}

.extraction-step .extraction-step-num {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #e9ecef;
  color: #6c757d;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
}

.extraction-step.done .extraction-step-num {
  background: #28a745;
  color: #fff;
}

.extraction-step-panel {
  background: #fdf6dd;
  padding: 12px;
  border-radius: 0 8px 8px 8px;
}

.extraction-step-panel.category {
  background: #fbeafd;
}

.concept-token.selected-other {
  background: #f1f3f5;
  border-color: #dee2e6;
  color: #adb5bd;
  text-decoration: line-through;
}

/* Extraction steps: CONCEPT first, then CATEGORY. Ported verbatim from
   metaCreativeCopilot App.css — same folder-tab idiom as the mode tabs one
   level up, with the selected tab attached to a panel in its property's
   colour. */
.extraction-status-chip {
  margin-left: 8px;
  font-size: 11px;
  font-weight: 600;
  border-radius: 10px;
  padding: 1px 8px;
  border: 1px solid;
  white-space: nowrap;
}

.extraction-status-chip.ready {
  color: #198754;
  border-color: #198754;
}

.extraction-status-chip.partial {
  color: #b26a00;
  border-color: #e0a800;
}

.extraction-status-chip.empty {
  color: #adb5bd;
  border-color: #dee2e6;
}

/* Cross-copilot insight chips ("Other networks" column in the cloud-files
   performance overlay). */
.insight-chip {
  display: inline-block;
  margin: 1px 2px;
  padding: 1px 6px;
  border-radius: 8px;
  background: #eef1f4;
  font-size: 11px;
  white-space: nowrap;
  cursor: default;
}

/* "Global 7D Spend": the bar is clickable to reveal the per-network split. */
.global-spend-bar { cursor: pointer; }
.global-spend-bar[aria-expanded="true"] { font-weight: bold; }
.global-spend-breakdown { margin-top: 3px; text-align: right; white-space: normal; }

/* Insight chips: logo + count + spend, click for the per-network popover. */
button.insight-chip {
  border: 0;
  font: inherit;
  font-size: 11px;
  line-height: 1.5;
  cursor: pointer;
}
.insight-chip[aria-expanded="true"] { background: #d9e2ec; }
.insight-chip-wrap { position: relative; display: inline-block; }
.nlogo { height: 12px; width: auto; vertical-align: -2px; }
/* "On Networks": the logos of every network a file is already used on. */
.on-networks { display: inline-flex; align-items: center; gap: 4px; }
.on-networks .nlogo { height: 14px; }
.insight-popover {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 30;
  min-width: 220px;
  max-width: 360px;
  padding: 8px 10px;
  background: #fff;
  color: #333;
  border: 1px solid #d0d7de;
  border-radius: 6px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
  text-align: left;
  font-size: 11px;
  white-space: normal;
}
.insight-popover__head {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  margin-bottom: 4px;
}
.insight-popover__head .nlogo { height: 16px; }
.insight-popover__spend { margin-left: auto; font-weight: 500; color: #555; }
.insight-popover__title {
  margin: 6px 0 2px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.3px;
  text-transform: uppercase;
  color: #6c757d;
}
.insight-popover__table { width: 100%; border-collapse: collapse; }
.insight-popover__table td { padding: 2px 4px; border-top: 1px solid #eef1f4; word-break: break-word; }
.insight-popover__table tr:first-child td { border-top: 0; }
.insight-popover__note { margin-top: 6px; font-size: 10px; color: #6c757d; }
.insight-popover__stale { color: #b54708; }

/* The Global {N}D Spend bar is cross-Copilot money, not this network's — blue
   keeps it apart from the green native-perf bars sitting next to it in the
   same row. Scoped to .global-spend-bar so .spend-progress-fill stays green
   everywhere else it is used. */
.global-spend-bar .spend-progress-fill { background: #0d6efd; }

/* Perf cells print the figure above the bar (google's "Campaigns & Ad groups"
   styling) — tabular figures so the column stays scannable. */
.perf-cell-value {
  font-variant-numeric: tabular-nums;
  font-size: 10px;
}

/* ─── Admin user-management: toggle accents, column groups, sorting ─────────
   The base `.permission-toggle` / `.toggle-slider` rules live in
   @bubbleye-ai/copilot-ui (see the note further up). These are additive
   overrides only — each one doubles the modifier class so it beats the
   library's single-class selector on specificity, not on load order. */

/* Read-only is a ROLE, not a permission — purple sets it apart from the
   green permission grants beside it. */
.permission-toggle.permission-toggle--readonly input:checked + .toggle-slider {
  background-color: #9900ff;
}

/* Test-only writes is a RESTRICTION, not a grant. Pink (and the pink header)
   is the at-a-glance marker that this column reads the opposite way. */
.permission-toggle.permission-toggle--testonly input:checked + .toggle-slider {
  background-color: #ff66cc;
}

/* Feature access (Workflows / Queues) — blue, to separate "which product
   surfaces exist for this user" from "what may this user change". */
.permission-toggle.permission-toggle--feature input:checked + .toggle-slider {
  background-color: #2563eb;
}

.user-management-table th.th-readonly { color: #9900ff; }
.user-management-table th.th-testonly { color: #ff66cc; }
/* A user restricted to test-only writes is flagged across the whole row
   (the sticky user cell paints its own background, so it is named too). */
.user-management-table tbody tr.row-testonly,
.user-management-table-container tbody tr.row-testonly td:first-child { background: #fff0f8; }
.user-management-table tbody tr.row-testonly:hover,
.user-management-table-container tbody tr.row-testonly:hover td:first-child { background: #ffe4f3; }

/* The feature-access block is bracketed so the eye can separate it from the
   permission toggles that follow. */
.user-management-table th.col-group-start,
.user-management-table td.col-group-start { border-left: 2px solid #93c5fd; }
.user-management-table th.col-group-end,
.user-management-table td.col-group-end { border-right: 2px solid #93c5fd; }

/* Sortable headers — every column. */
.user-management-table th.sortable-th {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
.user-management-table th.sortable-th:hover { background-color: rgba(0, 0, 0, 0.05); }
.user-management-table th.sortable-th.is-sorted { background-color: rgba(37, 99, 235, 0.08); }
.th-sort-caret {
  margin-left: 4px;
  font-size: 0.8em;
  opacity: 0.35;
}
.th-sort-caret.is-active { opacity: 1; }

/* Permission info circle + hover bubble. A native `title` truncates these
   two-sentence explanations and lags a second before appearing. */
.perm-info {
  position: relative;
  display: inline-block;
  margin-left: 4px;
  color: #6c757d;
  cursor: help;
  font-weight: 400;
}
.perm-info__bubble {
  display: none;
  position: absolute;
  top: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 60;
  width: 280px;
  padding: 8px 10px;
  border-radius: 6px;
  background: #1f2937;
  color: #f9fafb;
  font-size: 12px;
  font-weight: 400;
  line-height: 1.45;
  white-space: normal;
  text-align: left;
  text-transform: none;
  letter-spacing: normal;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
}
.perm-info:hover .perm-info__bubble,
.perm-info:focus-within .perm-info__bubble { display: block; }

/* ─── Read-only mode: clickable pill + explainer modal ────────────────────── */
.read-only-bar {
  border: 1px solid #e8c76a;
  font: inherit;
  cursor: pointer;
  pointer-events: auto;      /* overrides the informational default above */
}
.read-only-bar:hover { box-shadow: 0 3px 14px rgba(122, 83, 0, 0.3); }

.read-only-modal__overlay {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  z-index: 2100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(0, 0, 0, 0.55);
}
.read-only-modal {
  width: 100%;
  max-width: 520px;
  border-radius: 12px;
  background: #ffffff;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.3);
  overflow: hidden;
}
.read-only-modal__head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 18px 22px 10px;
  color: #7a5300;
}
.read-only-modal__head h2 {
  margin: 0;
  font-size: 18px;
  font-weight: 700;
  color: #1f2937;
}
.read-only-modal__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: linear-gradient(180deg, #fff8e6 0%, #fdefc8 100%);
  border: 1px solid #e8c76a;
}
.read-only-modal__body {
  padding: 4px 22px 6px;
  color: #374151;
  font-size: 14px;
  line-height: 1.6;
}
.read-only-modal__body p { margin: 0 0 12px; }
.read-only-modal__body ul { margin: 0 0 12px; padding-left: 20px; }
.read-only-modal__body li { margin-bottom: 4px; }
.read-only-modal__foot {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 10px 22px 18px;
}

/* Admin is a ROLE like read-only, not a permission grant — gold marks the
   one toggle that hands over the whole panel. */
.permission-toggle.permission-toggle--admin input:checked + .toggle-slider {
  background-color: #d4a017;
}

/* Right-hand rules that close each role/restriction column, so the eye can
   tell "who this user IS" from "what this user MAY DO" without reading the
   headers. Colour-matched to the toggle inside each column. */
.user-management-table th.col-edge-role,
.user-management-table td.col-edge-role { border-right: 2px solid #adb5bd; }
.user-management-table th.col-edge-testonly,
.user-management-table td.col-edge-testonly { border-right: 2px solid #ff66cc; }

/* Job detail section headings: the whole heading is the toggle, and the body
   below it carries `hidden` on a wrapper with no display rule of its own. */
.jp-section-toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  text-align: left;
  cursor: pointer;
}
.jp-section-toggle__caret {
  width: 10px;
  flex: 0 0 auto;
  color: #6c757d;
  font-size: 12px;
  text-align: center;
}
.jp-section-toggle:hover .jp-section-toggle__caret { color: #212529; }
.jp-section-toggle:focus-visible {
  outline: 2px solid #86b7fe;
  outline-offset: 2px;
  border-radius: 2px;
}
.jp-section-body { margin-top: 8px; }

/* Subscription pending-payment lock screen — meta App.css verbatim, minus the
   64px header offset (this screen renders no AppHeader: its controls would
   all 403). See components/SubscriptionPendingScreen.tsx. */
.subscription-pending-app {
  min-height: 100vh;
  position: relative;
  overflow: hidden;
  background: #f1f3f5;
}

.subscription-pending-product {
  position: absolute;
  inset: 0;
  pointer-events: none;
  filter: grayscale(1);
  opacity: 0.34;
  background:
    linear-gradient(90deg, rgba(173, 181, 189, 0.25) 1px, transparent 1px),
    linear-gradient(180deg, rgba(173, 181, 189, 0.25) 1px, transparent 1px),
    linear-gradient(180deg, #f8f9fa 0%, #e9ecef 100%);
  background-size: 48px 48px, 48px 48px, 100% 100%;
}

.subscription-pending-product::before {
  content: "";
  position: absolute;
  left: clamp(18px, 7vw, 96px);
  right: clamp(18px, 7vw, 96px);
  top: clamp(42px, 12vh, 120px);
  height: min(56vh, 520px);
  border: 1px solid #ced4da;
  background:
    linear-gradient(#dee2e6 0 0) 24px 28px / 28% 16px no-repeat,
    linear-gradient(#dee2e6 0 0) 24px 68px / 46% 12px no-repeat,
    linear-gradient(#dee2e6 0 0) 24px 96px / 38% 12px no-repeat,
    linear-gradient(#adb5bd 0 0) calc(100% - 180px) 24px / 156px 34px no-repeat,
    repeating-linear-gradient(0deg, #ffffff, #ffffff 42px, #e9ecef 43px, #e9ecef 44px);
  border-radius: 8px;
}

.subscription-pending-notice {
  position: relative;
  z-index: 2;
  box-sizing: border-box; /* padding inside the width, or it overflows a phone */
  width: min(520px, calc(100vw - 32px));
  margin: clamp(140px, 24vh, 220px) auto 0;
  padding: 24px 28px;
  border: 1px solid #dee2e6;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.96);
  box-shadow: 0 18px 42px rgba(33, 37, 41, 0.16);
  color: #212529;
  text-align: left;
}

.subscription-pending-logo {
  display: block;
  width: 40px;
  height: 40px;
  margin-bottom: 14px;
}

.subscription-pending-notice h1 {
  margin: 0 0 10px;
  font-size: 22px;
  line-height: 1.25;
  font-weight: 600;
}

.subscription-pending-notice p {
  margin: 0 0 8px;
  color: #495057;
  font-size: 15px;
  line-height: 1.55;
}

.subscription-pending-notice a {
  color: #0b7285;
  font-weight: 600;
}

.subscription-pending-notice .btn {
  margin-top: 12px;
}

/* A filter option's picture (user avatar, tenant default avatar), sized to
   sit where the kind icon would. TargetSelect swaps back to the icon if the
   image 404s, so this never renders empty. */
.target-select-box__avatar {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  object-fit: cover;
  flex: 0 0 auto;
}

/* Bulk select by name — the Cloud Files modal's paste-a-list dialog.
   Classes rather than inline styles: mintegral's R0 fidelity gate caps
   inline-style count per file against the fork, and it was right to — this
   is a panel with a dozen elements, which is what stylesheets are for. */
.files-load-parameters__bulk {
  /* .files-load-parameters is a flex row; this pushes the button to its
     right edge, away from the two reload buttons. It does not fetch
     anything, it selects. */
  margin-left: auto;
}

.bulk-select-panel {
  margin-top: 14px;
  margin-bottom: 18px;
  padding: 16px;
  border: 1px solid #cfd8dc;
  border-radius: 8px;
  background: #f8fbff;
}

.bulk-select-title {
  font-weight: 700;
  margin-bottom: 8px;
}

.bulk-select-hint {
  color: #5f6368;
  margin-bottom: 12px;
  line-height: 1.4;
}

.bulk-select-textarea {
  width: 100%;
  font-family: monospace;
  font-size: 12px;
  padding: 8px;
}

.bulk-select-count {
  color: #6c757d;
  margin-top: 4px;
}

.bulk-select-error {
  color: #c62828;
  margin-top: 8px;
}

.bulk-select-results {
  margin-top: 12px;
}

.bulk-select-summary {
  font-weight: 600;
}

.bulk-select-truncated {
  color: #8a6d3b;
  margin-top: 6px;
}

/* user-select:all so one click grabs the whole list to paste back into
   whatever produced it — these are the names that found nothing, which is
   what people came to this dialog for. */
.bulk-select-unmatched {
  color: #c62828;
  margin-top: 6px;
  font-family: monospace;
  font-size: 12px;
  user-select: all;
}

.bulk-select-list {
  max-height: 220px;
  overflow-y: auto;
  margin-top: 8px;
  border: 1px solid #e0e0e0;
  border-radius: 6px;
  padding: 6px;
}

.bulk-select-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 2px 4px;
}

.bulk-select-name {
  font-family: monospace;
  font-size: 12px;
}

.bulk-select-actions {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  margin-top: 14px;
}

/* Drafts tab: an auto-saved draft's author is dimmed, and this badge says why.
   Full contrast on purpose — it explains the dimming. Same rule as meta. */
.auto-save-badge {
  border: solid 1px #ee8800;
  border-radius: 20px;
  padding: 2px 5px;
  background: #fff;
  white-space: nowrap;
  color: #ee8800;
}

/* The Drafts tab. An auto-layout table already gives a long name the room and a
   short chip little, so this sizes NOTHING. It says only what the browser cannot
   know — which cells stay on one line, how a name wraps, where a header sits —
   and says it by CLASS, never by position, so reordering or adding a column
   cannot silently restyle another. */
.drafts-table th {
  text-align: left;
}
.drafts-table th.draft-th-actions {
  text-align: right;
}
.draft-td-fit {
  white-space: nowrap;
  padding-left: 14px;
}
/* `.jobs-panel td` sets word-break: break-all panel-wide and outranks a bare
   class, so a long draft name broke mid-word. Still by class, never by
   position -- it only needs the panel in the selector to win. */
.jobs-panel td.draft-td-name,
.draft-td-name {
  word-break: normal;
  overflow-wrap: break-word;
}

/* Drafts: everything the components used to say inline. */
.draft-none { color: #6c757d; }
.draft-kind-chip { margin-right: 14px; white-space: nowrap; }
.draft-author { display: flex; align-items: center; gap: 8px; }
.draft-author-identity { min-width: 0; }
/* Only the identity dims; the Auto-save badge beside it explains the dimming. */
.draft-author-identity--auto { opacity: 0.7; }
.draft-details { padding: 10px 16px; }
.draft-details-error { margin: 10px 16px; }
.draft-details-list { margin: 0; padding-left: 18px; line-height: 1.7; }
.draft-details-sublist { margin: 0; padding-left: 18px; }
.draft-code { font-family: monospace; }
.draft-expand-button { background: none; border: none; cursor: pointer; color: #007bff; }
.draft-name { font-weight: 600; }
.draft-submitted-note { font-size: 12px; color: #28a745; }
.draft-row--submitted { opacity: 0.65; }
.draft-row--submitted .draft-name::before { content: "\2713"; color: #28a745; font-weight: 700; margin-right: 6px; }
.draft-td-actions { text-align: right; }
.draft-actions { display: flex; align-items: stretch; gap: 6px; flex-wrap: nowrap; justify-content: flex-end; }
.draft-actions .btn { white-space: nowrap; }
.draft-td-detail { padding: 0; border: none; }
.draft-pagination { display: flex; justify-content: center; align-items: center; gap: 6px; margin: 12px 0; }
.draft-pagination-label { margin: 0 12px; font-size: 12px; color: #666; }
.draft-button-icon { margin-right: 6px; }
.draft-save-modal { max-width: 460px; width: 92%; }
.draft-save-modal-inner { padding: 16px; display: grid; gap: 14px; }
.draft-save-name-input { width: 100%; }

/* Drafts tab: the same table as meta_copilot's Drafts tab. Meta's declarations
   verbatim (.data-table, .data-table thead/th/td, .jobs-panel .data-table th,
   .side-panel .data-table td), scoped to this one table so the app's other
   .data-table tables keep their own look. */
.side-panel .drafts-table.data-table { width: 100%; border-collapse: collapse; margin-bottom: 16px; font-size: 12px; background: transparent; }
.side-panel .drafts-table.data-table thead { position: sticky; top: 0; z-index: 10; background: #f8f9fa; }
.side-panel .drafts-table.data-table th { background: #fff; padding: 6px 8px; text-align: left; font-size: 12px; font-weight: 600; color: #495057; border-bottom: 2px solid #dee2e6; white-space: nowrap; vertical-align: top; text-transform: none; letter-spacing: normal; position: static; }
.side-panel .drafts-table.data-table td { padding: 6px 8px; border-bottom: 1px solid #fff; line-height: 1.3; color: #000; text-align: start; vertical-align: middle; }
/* Meta's Author cell is .td-name-text (font-weight 500). */
.side-panel .drafts-table.data-table td:nth-child(3) { font-weight: 500; }

/* Step 1 "+ AppLovin assets" button: the product logo at icon size. */
.files-step-library-logo {
  height: 18px;
  object-fit: contain;
  width: 18px;
}

/* The keyboard's position in an open picker. It has to read differently from
   `.is-selected` (the value the filter currently holds) because both are on
   screen at once and they are usually different rows: the same tint for both
   would say the list has two selected values. An outline rather than another
   fill, so a row can be highlighted AND selected without the colours mixing.
   Attribute rather than a class: the className literals on these options are
   whole-matched by the downstream repos' fidelity gates. */
.target-select-box__option[data-highlighted="true"] {
  outline: 2px solid #1565c0;
  outline-offset: -2px;
}

/* Post-deploy "reload when convenient" toast (PostDeployRefreshBanner) */
.post-deploy-banner {
  position: fixed;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 9999;
  background: #0d6efd;
  color: #fff;
  padding: 10px 16px;
  border-radius: 6px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  max-width: min(1000px, calc(100vw - 24px));
  width: max-content;
}

.post-deploy-banner button {
  background: #fff;
  color: #0d6efd;
  border: none;
  border-radius: 4px;
  padding: 2px 8px;
  margin: 0 4px;
  font-weight: 600;
  font-size: 13px;
  cursor: pointer;
  font-family: inherit;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  vertical-align: baseline;
}

/* The "Shared · N" chip's campaign list (SharedSetBadge): sized to its
   content up to 400px, so a short list doesn't sit in a wide empty box. */
.shared-set-popover {
  /* Portaled to <body>; top/left set inline. Above the side panels. */
  position: fixed;
  z-index: 1100;
  background: #fff;
  border: 1px solid #d0d7de;
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
  padding: 8px 10px;
  /* Fixed, not em: hosts differ (11px job page, 12px tables). */
  font-size: 11px;
  text-align: left;
  white-space: normal;
  width: max-content;
  max-width: 400px;
}

/* Running / Paused / Removed pill in the shared-set popover and the
   shared-set scope dialog (StatusPill). Font size inherits from the host. */
.shared-set-status-pill {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 4px;
  font-weight: 600;
}
.shared-set-status-pill--running {
  background: rgba(46, 164, 79, 0.1);
  color: rgb(46, 164, 79);
}
.shared-set-status-pill--paused {
  background: rgba(249, 115, 22, 0.1);
  color: rgb(249, 115, 22);
}
.shared-set-status-pill--removed {
  background: rgba(220, 53, 69, 0.1);
  color: rgb(220, 53, 69);
}
.shared-set-status-pill--unknown {
  background: rgba(108, 117, 125, 0.1);
  color: rgb(108, 117, 125);
}
/* Setup Help — registry-driven help column, bullseyes, spotlight. */

/* ── Round Help button (next to the "Account setup" header) ── */
.setup-help-button {
  grid-area: button;
  width: 38px;
  height: 38px;
  flex: 0 0 auto;
  padding: 0;
  border-radius: 50%;
  border: 1px solid #ced4da;
  background: #fff;
  color: #ff6666;
  cursor: pointer;
  font-size: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.setup-help-button:hover { background: #f1f3f5; border-color: #adb5bd; }

/* Light-black dim shown with the bullseyes (below the circles + the column). */
.setup-help-dim {
  position: fixed;
  inset: 0;
  z-index: 4040;
  background: rgba(0, 0, 0, 0.35);
  animation: setupHelpFade 0.18s ease-out;
}

/* ── Attention flash on the Help button: an expanding ripple (a ring grows
      outward + fades with an ease-out, like a radar ping) followed by a ~2s
      quiet pause before the next ripple. ── */
@keyframes setupHelpFlash {
  0%   { box-shadow: 0 0 0 0 rgba(255, 102, 102, 0.6); }
  27%  { box-shadow: 0 0 0 22px rgba(255, 102, 102, 0); }
  100% { box-shadow: 0 0 0 22px rgba(255, 102, 102, 0); }
}
/* Flashes regardless of prefers-reduced-motion — it's a deliberate attention
   cue for incomplete mandatory setup, so it is intentionally NOT silenced by
   the reduced-motion guard below. */
.setup-help-flash { animation: setupHelpFlash 3s ease-out infinite; }

/* ── Docked right column (dark theme) ── */
.setup-help-column {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 340px;
  min-width: 340px;
  max-width: 90vw;
  z-index: 4100;
  background: #1e2128;
  color: #e9ecef;
  border-left: 1px solid #11131a;
  box-shadow: -8px 0 30px rgba(0, 0, 0, 0.4);
  display: flex;
  flex-direction: column;
  animation: setupHelpSlideIn 0.18s ease-out;
}
@keyframes setupHelpSlideIn {
  from { transform: translateX(100%); }
  to   { transform: translateX(0); }
}

/* Left-edge resize handle. */
.setup-help-resize {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 6px;
  cursor: ew-resize;
  background: transparent;
  z-index: 2;
}
.setup-help-resize:hover { background: rgba(13, 110, 253, 0.55); }

.setup-help-column-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 14px;
  border-bottom: 1px solid #2c313c;
}
.setup-help-column-title {
  font-weight: 600;
  font-size: 15px;
  margin-right: auto;
  color: #f1f3f5;
}
.setup-help-langs { display: flex; gap: 4px; }
.setup-help-lang {
  border: 1px solid #3a4150;
  background: #2a2f3a;
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  color: #adb5bd;
  padding: 2px 6px;
  border-radius: 4px;
}
.setup-help-lang.active { color: #fff; background: #0d6efd; border-color: #0d6efd; }
.setup-help-close {
  border: none;
  background: none;
  cursor: pointer;
  font-size: 16px;
  color: #adb5bd;
  padding: 4px 6px;
  border-radius: 4px;
}
.setup-help-close:hover { background: rgba(255, 255, 255, 0.1); color: #fff; }

.setup-help-cards { overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 10px; }
.setup-help-empty { color: #adb5bd; font-size: 13px; }

/* Cards: dark surfaces; help text is gray (#bbb) on the dark panel. */
.setup-help-card {
  background: #262b34;
  border: 1px solid #333a45;
  border-radius: 8px;
  padding: 10px 12px;
  cursor: help; /* hover to spotlight its element */
  transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;
}
.setup-help-child { cursor: help; }
.setup-help-card-head { display: flex; align-items: center; gap: 6px; }
.setup-help-card-title {
  border: none;
  background: none;
  cursor: pointer;
  font-weight: 600;
  font-size: 14px;
  color: #bbb;
  text-align: left;
  padding: 0;
  margin-right: auto;
}
.setup-help-accordion-toggle {
  border: none; background: none; cursor: pointer; color: #888; padding: 2px 4px;
}
.setup-help-card-body { margin: 6px 0 0; font-size: 13px; line-height: 1.5; color: #bbb; }

.setup-help-children {
  margin-top: 10px;
  padding-left: 10px;
  border-left: 4px solid #666;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.setup-help-child-title {
  border: none; background: none; cursor: pointer; font-weight: 600; font-size: 13px;
  color: #bbb; text-align: left; padding: 0;
}
.setup-help-child-body { margin: 3px 0 0; font-size: 12px; line-height: 1.45; color: #bbb; }

/* Selected card (clicked, or via its bullseye) — text turns WHITE and the card
   lights up against the other (gray-text) cards. */
.setup-help-card.is-selected,
.setup-help-child.is-selected {
  background: rgba(13, 110, 253, 0.22);
  border-radius: 8px;
  box-shadow: 0 0 0 2px rgba(13, 110, 253, 0.6);
}
.setup-help-card.is-selected { border-color: #0d6efd; }
.setup-help-child.is-selected { padding: 4px 6px; }
.setup-help-card.is-selected .setup-help-card-title,
.setup-help-card.is-selected .setup-help-card-body,
.setup-help-card.is-selected .setup-help-accordion-toggle,
.setup-help-child.is-selected .setup-help-child-title,
.setup-help-child.is-selected .setup-help-child-body {
  color: #fff;
}

/* ── Bullseye markers: larger, semi-transparent red concentric circles,
      centered on the target element. ── */
.setup-help-bullseye {
  position: fixed;
  transform: translate(-50%, -50%);
  z-index: 4050;
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 50%;
  border: 2px solid rgba(220, 38, 38, 0.7);
  background: rgba(220, 38, 38, 0.16);
  cursor: pointer;
  box-shadow: 0 0 0 6px rgba(220, 38, 38, 0.1);
  animation: setupHelpBullseyePulse 1.6s ease-in-out infinite;
}
.setup-help-bullseye::before {
  content: "";
  position: absolute;
  inset: 11px;
  border-radius: 50%;
  border: 2px solid rgba(220, 38, 38, 0.85);
  background: rgba(220, 38, 38, 0.34);
}
@keyframes setupHelpBullseyePulse {
  0%, 100% { box-shadow: 0 0 0 6px rgba(220, 38, 38, 0.1), 0 0 0 0 rgba(220, 38, 38, 0); }
  50%      { box-shadow: 0 0 0 6px rgba(220, 38, 38, 0.1), 0 0 0 12px rgba(220, 38, 38, 0.16); }
}
@media (prefers-reduced-motion: reduce) {
  .setup-help-bullseye { animation: none; }
}

/* ── Spotlight (4 dim panels + ring; the hole is left open for click-through) ── */
/* The container spans the whole screen but must NOT capture clicks — otherwise
   it swallows the click meant for the element sitting in the open cutout. Only
   the dim PANELS capture (to keep the rest of the page inert); the hole has no
   panel, so a click there lands on the real element (e.g. the nav link). */
.setup-help-spotlight { position: fixed; inset: 0; z-index: 4000; pointer-events: none; }
.setup-help-spotlight-panel {
  position: fixed;
  pointer-events: auto;
  /* Same light-black as the bullseye dim — the cutout is just carved out of
     the same overlay (no second, darker layer when a spotlight appears). */
  background: rgba(0, 0, 0, 0.35);
}
.setup-help-ring {
  position: fixed;
  border-radius: 8px;
  box-shadow: inset 0 0 0 2px #0d6efd;
  pointer-events: none;
}
@keyframes setupHelpFade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.ia-step {
  display: flex;
  flex-direction: column;
  gap: 12px;
  /*padding: 16px;*/
  /* Fill the step-body so chart/causes can flex to its height.
     The parent rule `.step-body > *` sets flex-shrink: 0; override so
     we can also shrink when the viewport is short. */
  flex: 1 1 auto !important;
  min-height: 0;
  height: 100%;
  box-sizing: border-box;
}

.ia-target-select {
  display: flex;
  align-items: center;
  gap: 10px;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 10px 12px;
  flex: 0 0 auto;
}
.ia-target-select label {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #475569;
  font-weight: 600;
}
.ia-target-select select {
  flex: 1;
  padding: 6px 8px;
  border: 1px solid #cbd5e1;
  border-radius: 4px;
  font-size: 13px;
  background: #fff;
}
.ia-target-select select:disabled { background: #f1f5f9; }

.ia-spark-row {
  display: grid;
  /* grid-template-columns is set inline by MetricSparklineTabs from the
     number of metric buttons actually rendered (varies per copilot). */
  gap: 6px;
  width: 100%;
  /* Share a fraction of the step-body's vertical space, bounded so the
     sparkline tabs never become too compressed nor steal too much room
     from the main chart / causes list below. */
  flex: 0 1 auto;
  min-height: 60px;
  max-height: 110px;
  overflow: hidden;
}
.ia-spark {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 6px;
  padding: 8px;
  text-align: left;
  cursor: pointer;
  /* Allow the grid track to shrink below the chart's intrinsic size. */
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  overflow: hidden;
}
.ia-spark--active {
  border-color: #2563eb;
  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.1);
}
.ia-spark--locked { background: #eff6ff; }
.ia-spark__label {
  font-size: 10px;
  color: #475569;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Chart.js responsive mode needs a positioned, sized parent — without
   `position: relative` + an explicit width, it falls back to a fixed
   canvas size and the row overflows. The min/max-height keeps the
   sparkline readable but doesn't let it dominate when the viewport is
   tall. */
.ia-spark__chart {
  flex: 1;
  position: relative;
  width: 100%;
  min-width: 0;
  min-height: 25px;
  max-height: 90px;
}
.ia-spark__chart > canvas {
  width: 100% !important;
  height: 100% !important;
}

.ia-chart {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 12px;
  /* Flex to share remaining height with .ia-causes; honour a sensible
     minimum so the chart stays readable on short viewports. */
  flex: 2 1 220px;
  min-height: 150px;
  max-height: 300px;
  position: relative;
  overflow: hidden;
}
.ia-chart--manual { cursor: crosshair; user-select: none; }
.ia-chart__marquee {
  position: absolute;
  top: 12px;
  bottom: 12px;
  pointer-events: none;
  background: rgba(37, 99, 235, 0.12);
  border-left: 1px solid rgba(37, 99, 235, 0.6);
  border-right: 1px solid rgba(37, 99, 235, 0.6);
}
.ia-chart__manual-hint {
  position: absolute;
  top: 4px;
  right: 16px;
  font-size: 10px;
  color: #64748b;
  background: rgba(255, 255, 255, 0.85);
  padding: 2px 6px;
  border-radius: 3px;
  pointer-events: none;
}

.ia-chart-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
}
.ia-mode-toggle {
  display: inline-flex;
  background: #f8fafc;
  border: 1px solid #e5e7eb;
  border-radius: 6px;
  padding: 2px;
  gap: 2px;
}
.ia-mode-toggle__btn {
  background: transparent;
  border: 0;
  padding: 4px 10px;
  font-size: 12px;
  color: #475569;
  border-radius: 4px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.ia-mode-toggle__btn:hover { background: #e2e8f0; }
.ia-mode-toggle__btn--active {
  background: #1d4ed8;
  color: #fff;
  font-weight: 600;
}
.ia-chart-header__clear {
  background: transparent;
  border: 1px solid #cbd5e1;
  color: #475569;
  border-radius: 4px;
  padding: 3px 8px;
  font-size: 11px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.ia-chart-header__clear:hover { background: #f1f5f9; }
.ia-chart > canvas {
  width: 100% !important;
  height: 100% !important;
}

.ia-empty, .ia-loading, .ia-error {
  padding: 24px;
  text-align: center;
  color: #64748b;
}
.ia-error { color: #dc2626; }

.ia-banner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 13px;
}
.ia-banner--yellow { background: #fef3c7; color: #92400e; }
.ia-banner--blue { background: #dbeafe; color: #1e40af; }
.ia-banner button {
  background: rgba(255, 255, 255, 0.6);
  border: 1px solid currentColor;
  color: inherit;
  padding: 4px 8px;
  border-radius: 4px;
  cursor: pointer;
}
.ia-banner button:disabled { opacity: 0.6; cursor: progress; }

.ia-causes-wrap {
  /* Automatic vertical allocation: this shares remaining space with the
     chart, then scrolls internally when the anomaly list outgrows the
     space the stack can spare. */
  display: flex;
  flex-direction: column;
  flex: 1 1 180px;
  min-height: 0;
  max-height: 100%;
  overflow-y: auto;
}

.ia-causes {
  background: #fff;
/*  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 12px;*/
  /* Fill the wrapper's height without owning the scroll container. */
  flex: 1 1 auto;
  min-height: 0;
  overflow: visible;
}
.ia-causes__head {
  font-size: 10px;
  color: #64748b;
  letter-spacing: 0.08em;
  margin-bottom: 8px;
}
.ia-causes--empty {
  text-align: center;
  color: #16a34a;
  padding: 24px;
}
/* The dashed bottom border is set inline (per-anomaly color matches its
   chart marker). This rule sets the baseline padding/spacing only. */
.ia-anomaly { padding: 6px 0; }
.ia-anomaly__head {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  background: transparent;
  border: 0;
  cursor: pointer;
  padding: 6px;
}
.ia-anomaly__date {
  font-family: monospace;
  font-size: 11px;
  color: #475569;
}
.ia-anomaly__metric {
  font-size: 11px;
  text-transform: uppercase;
  color: #64748b;
}
.ia-anomaly__pct--drop { color: #dc2626; font-weight: 600; }
.ia-anomaly__pct--spike { color: #f59e0b; font-weight: 600; }
.ia-anomaly--hovered {
  background: #fff7ed;
  outline: 2px solid #f59e0b;
  outline-offset: -2px;
  border-radius: 4px;
}
.ia-anomaly--clicked {
  background: #fffced;
  outline: 2px solid gold;
  outline-offset: -2px;
  border-radius: 4px;
}
.ia-anomaly__body {
  padding: 6px 0 6px 24px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.ia-anomaly__empty { font-size: 12px; color: #94a3b8; padding: 4px 0; }

.ia-cause-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 2px 8px;
  border: 1px solid transparent;
  border-radius: 6px;
  transition: background-color 120ms ease, opacity 120ms ease,
              color 120ms ease;
  color: #1e293b;
}
.ia-cause-chip--stacked {
  /* row background comes from inline style (matches chart band) */
  color: #fff;
}
.ia-cause-chip--stacked .ia-cause-chip__name,
.ia-cause-chip--stacked .ia-cause-chip__pct {
  color: #fff;
}
.ia-cause-chip--excluded {
  background: #f1f5f9;
  opacity: 0.55;
}

.ia-cause-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: #f8fafc;
  border: 1px solid #cbd5e1;
  color: #475569;
  border-radius: 4px;
  padding: 3px 8px;
  font-size: 11px;
  cursor: pointer;
  white-space: nowrap;
}
.ia-cause-btn:hover { background: #e2e8f0; }
.ia-cause-btn--show.ia-cause-btn--active {
  /* Same solid dark gray as the "Hide impact" active state — the visual
     emphasis is on "this button is selected", not on the action's color. */
  background: #475569;
  border-color: #475569;
  color: #fff;
  font-weight: 600;
}
.ia-cause-btn--hide.ia-cause-btn--active {
  background: #475569;
  border-color: #475569;
  color: #fff;
  font-weight: 600;
}
.ia-cause-chip--excluded .ia-cause-btn--hide.ia-cause-btn--active {
  /* keep the active "Hide" button readable even when the row is dimmed */
  opacity: 1;
}

.ia-cause-chip__name {
  flex: 0 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 0.9em;
}
.ia-cause-chip__bar {
  height: 4px;
  background: rgba(37, 99, 235, 0.4);
  border-radius: 2px;
  margin-left: 8px;
  min-width: 4px;
  flex: 1 1 0;
}
.ia-cause-chip--stacked .ia-cause-chip__bar {
  background: rgba(255, 255, 255, 0.6);
}
.ia-cause-chip__pct {
  font-family: monospace;
  font-size: 11px;
  color: #475569;
  min-width: 32px;
  text-align: right;
}
.ia-cause-chip__info {
  background: transparent;
  border: 0;
  cursor: pointer;
  color: inherit;
  padding: 2px;
}
.ia-cause-chip--excluded .ia-cause-chip__info,
.ia-cause-chip--excluded .ia-cause-btn { opacity: 1; }

.ia-sheet-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: stretch;
  justify-content: flex-end;
  z-index: 1000;
}
.ia-sheet {
  background: #fff;
  /* width is set inline from the resizable state; this is just the
     fallback when CauseDetailSheet doesn't apply its inline style. */
  width: 480px;
  height: 100%;
  padding: 16px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
  position: relative; /* anchor for .ia-sheet__resize-handle */
}
/* Drag handle on the left edge of the sheet — same UX pattern as the
   Jobs side panel. The visible thumb appears on hover; the full strip
   is the active hit area. */
.ia-sheet__resize-handle {
  position: absolute;
  top: 0;
  left: 0;
  width: 8px;
  height: 100%;
  cursor: col-resize;
  background: transparent;
  z-index: 10;
}
.ia-sheet__resize-handle::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 3px;
  height: 40px;
  background: #cbd5e1;
  border-radius: 2px;
  transition: background-color 120ms ease;
}
.ia-sheet__resize-handle:hover::before {
  background: #94a3b8;
}
/* ON / OFF status badges next to object status-change summaries. ON = green
   (Active), OFF = neutral red-tinted gray (Inactive). */
.ia-sheet__status-badge {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  vertical-align: middle;
}
.ia-sheet__status-badge--on {
  background: #dcfce7;
  color: #166534;
}
.ia-sheet__status-badge--off {
  background: #fee2e2;
  color: #991b1b;
}
.ia-sheet__status-badge--deleted {
  background: #1f2937;
  color: #f9fafb;
}
/* Strike through summary/object name when the event is a deletion. */
.ia-sheet__event--deleted {
  opacity: 0.4;
}
.ia-sheet__event--deleted .ia-sheet__event-summary,
.ia-sheet__event--deleted .ia-sheet__event-objname {
  text-decoration: line-through;
  text-decoration-color: #9ca3af;
  color: #6b7280;
}
.ia-sheet__event--deleted .ia-sheet__status-badge--deleted {
  text-decoration: none;
}
.ia-sheet__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.ia-sheet__head button {
  background: transparent;
  border: 0;
  cursor: pointer;
  font-size: 18px;
}
.ia-sheet__label {
  font-size: 10px;
  color: #64748b;
  letter-spacing: 0.08em;
  margin-bottom: 6px;
}
.ia-sheet__kv { font-size: 13px; padding: 2px 0; }
.ia-sheet__empty { font-size: 12px; color: #94a3b8; }
.ia-sheet__event {
  display: grid;
  grid-template-columns: 18px 1fr;
  gap: 8px;
  margin: 8px 0;
  padding-left: 0;
  border-left: 0;
}
.ia-sheet__event-rail {
  position: relative;
  width: 18px;
}
.ia-sheet__event-rail::before {
  content: '';
  position: absolute;
  left: 8px;
  top: -8px;
  bottom: -8px;
  width: 2px;
  background: #e5e7eb;
}
.ia-sheet__event-rail-dot {
  position: absolute;
  left: 4px;
  top: 6px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid #94a3b8;
}
.ia-sheet__event-body { min-width: 0; }
.ia-sheet__event-title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 600;
}
.ia-sheet__event-date {
  font-family: monospace;
  color: #334155;
}
.ia-sheet__event-head {
  display: flex;
  gap: 10px;
  font-size: 11px;
  color: #475569;
}
.ia-sheet__event-cat {
  background: #eef2ff;
  color: #4338ca;
  padding: 1px 6px;
  border-radius: 3px;
  font-weight: 600;
}
.ia-sheet__event-summary { font-size: 13px; margin: 4px 0; }
.ia-sheet__event-meta { font-size: 11px; color: #64748b; }
.ia-sheet__event-objname {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 6px;
  border-radius: 3px;
  background: #f1f5f9;
  color: #334155;
  font-family: monospace;
  font-size: 11px;
  font-weight: 600;
  word-break: break-all;
}

/* Sibling events tied to the same AppLovin object_id render indented and
   compact under their parent (creation event, or earliest event). */
.ia-sheet__event-group { margin: 8px 0; }
.ia-sheet__event-group--dim { opacity: 0.4; }
.ia-sheet__event-group--clickable { cursor: pointer; }
.ia-sheet__event-group-sep {
  border: 0;
  border-top: 1px solid #e5e7eb;
  margin: 12px 0;
}
.ia-sheet__event-group > .ia-sheet__event { margin: 0; }
.ia-sheet__event-children {
  margin-left: 26px;
  padding-left: 0;
  border-left: 0;
}
.ia-sheet__event-children > .ia-sheet__event {
  border-left-color: #f1f5f9;
  margin: 4px 0;
}
.ia-sheet__event-children > .ia-sheet__event .ia-sheet__event-summary {
  font-size: 12px;
}

/* ─── Impact Analysis premium teaser (shown to users without access) ─── */
.ia-teaser {
  max-width: 560px;
  margin: 8px auto;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
}
.ia-teaser__chart {
  position: relative;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 10px 10px 6px;
  background: linear-gradient(180deg, #fff, #f8fafc);
}
.ia-teaser__chart svg {
  display: block;
  width: 100%;
  height: auto;
}
.ia-teaser__chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 6px;
  font-size: 10px;
  color: #64748b;
}
.ia-teaser__chart-legend span {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.ia-teaser__chart-legend i {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  display: inline-block;
}
.ia-teaser__body {
  text-align: center;
  padding: 0 8px 4px;
}
.ia-teaser__crown {
  font-size: 22px;
  color: #f59f00;
  margin-bottom: 6px;
}
.ia-teaser__title {
  margin: 0 0 8px;
  font-size: 17px;
  font-weight: 700;
  color: #1e293b;
}
.ia-teaser__text {
  margin: 0 auto 8px;
  max-width: 42ch;
  font-size: 13px;
  line-height: 1.5;
  color: #475569;
}
.ia-teaser__text--muted {
  color: #64748b;
  font-weight: 600;
}
.ia-teaser__cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
  padding: 9px 18px;
  border-radius: 8px;
  background: #2563eb;
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
}
.ia-teaser__cta:hover {
  background: #1d4ed8;
}
