/* ============================================================================
   Stellar Canvas v2 — Prototype styles
   Isolation: only used by prototype-v2/. Never imported by Stellar.
   ============================================================================ */

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
  font-family: -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", Roboto,
               "Helvetica Neue", Arial, sans-serif;
  font-size: 14px;
  color: #1a1a1a;
  background: #f5f5f5;
  user-select: none;
  -webkit-font-smoothing: antialiased;
}

/* ============================================================================
   Top bar — logo, project name, save status, library/debug actions
   ============================================================================ */
.topbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 48px;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 16px 0 14px;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid #ededed;
}
.topbar-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.hamburger-btn {
  width: 30px;
  height: 30px;
  border: 0;
  background: transparent;
  border-radius: 6px;
  color: #1a1a1a;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-right: 2px;
}
.hamburger-btn:hover { background: #f0f0f0; }
.hamburger-btn.active { background: #1a1a1a; color: #ffffff; }
.hamburger-btn svg { width: 16px; height: 16px; }
.topbar-org {
  font-size: 10.5px;
  color: #9a9a9a;
  letter-spacing: 0.04em;
  font-weight: 500;
}
.topbar-logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  color: #1a1a1a;
}
.topbar-logo svg {
  width: 18px;
  height: 18px;
}
.topbar-product {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: #1a1a1a;
}
.topbar-divider {
  width: 1px;
  height: 18px;
  background: #e5e5e5;
  margin: 0 4px;
}
.topbar-project {
  font-size: 12.5px;
  color: #3a3a3a;
  padding: 4px 8px;
  border-radius: 5px;
  outline: none;
  cursor: text;
  letter-spacing: 0.01em;
  min-width: 80px;
  max-width: 280px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.topbar-project:hover { background: #f5f5f5; }
.topbar-project:focus { background: #ffffff; box-shadow: 0 0 0 1px #1a1a1a; }

/* v0.20: project switcher chevron + dropdown */
.project-switcher-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 22px;
  padding: 0;
  margin-left: -2px;
  background: transparent;
  border: 0;
  border-radius: 4px;
  color: #6a6a6a;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}
.project-switcher-btn svg { width: 14px; height: 14px; }
.project-switcher-btn:hover { background: #ececec; color: #1a1a1a; }
.project-switcher-btn.active { background: #1a1a1a; color: #fff; }

/* v0.54.1: open-in-new-window button, matches switcher chrome */
.project-popout-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 22px;
  padding: 0;
  margin-left: 0;
  background: transparent;
  border: 0;
  border-radius: 4px;
  color: #6a6a6a;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}
.project-popout-btn svg { width: 13px; height: 13px; }
.project-popout-btn:hover { background: #ececec; color: #1a1a1a; }
.project-popout-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.project-switcher-menu {
  position: fixed;
  top: 44px;
  left: 130px;
  min-width: 280px;
  max-width: 360px;
  background: #ffffff;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.10), 0 2px 6px rgba(0,0,0,0.06);
  padding: 6px 0;
  z-index: 1300;
  display: none;
  flex-direction: column;
  font-size: 12.5px;
}
.project-switcher-menu.visible { display: flex; }
.psm-head {
  padding: 6px 12px 4px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #8a8a8a;
}
.psm-count {
  display: inline-block;
  margin-left: 4px;
  font-size: 10px;
  color: #b0b0b0;
}
.psm-list {
  max-height: 260px;
  overflow-y: auto;
  padding: 0 6px;
}
.psm-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 8px;
  border-radius: 5px;
  cursor: pointer;
  user-select: none;
}
.psm-item:hover { background: #f5f5f5; }
.psm-item.active {
  background: #fbeaec;
  color: #1a1a1a;
}
.psm-item.active::before {
  content: '●';
  color: #e21a2c;
  font-size: 9px;
  margin-right: 0;
}
.psm-item-name {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: 500;
}
.psm-item-meta {
  font-size: 10.5px;
  color: #9a9a9a;
  flex-shrink: 0;
}
.psm-item-del {
  display: none;
  width: 22px; height: 22px;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  border-radius: 4px;
  color: #9a9a9a;
  cursor: pointer;
  padding: 0;
}
.psm-item:hover .psm-item-del { display: inline-flex; }
.psm-item-del:hover { background: #f4d8da; color: #c4101e; }
.psm-divider {
  height: 1px;
  background: #ececec;
  margin: 6px 8px;
}
.psm-action {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 6px;
  padding: 8px 10px;
  border: 0;
  background: transparent;
  border-radius: 5px;
  font-size: 12.5px;
  color: #1a1a1a;
  cursor: pointer;
  text-align: left;
  width: calc(100% - 12px);
}
.psm-action:hover { background: #f5f5f5; }
.psm-action .psm-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  font-size: 13px;
  color: #6a6a6a;
}

/* v1.4.0 SHARING — "Shared projects" group inside the switcher list */
.psm-shared-head {
  padding: 10px 8px 4px;
  margin-top: 4px;
  border-top: 1px solid #f0e7d4;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #a8741a; /* amber section label */
}
.psm-item-shared .psm-item-name { font-weight: 500; }
.psm-share-owner {
  font-size: 10.5px;
  color: #a8741a;
  max-width: 110px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex-shrink: 0;
}
.psm-access-badge {
  flex-shrink: 0;
  font-size: 9.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 1px 6px;
  border-radius: 9px;
  border: 1px solid;
}
.psm-access-badge.view {
  color: #8a6d1f;
  border-color: #e6cf8a;
  background: #fdf6e2;
}
.psm-access-badge.edit {
  color: #1a7a43;
  border-color: #a9dfc0;
  background: #ecf9f1;
}

/* v1.4.0 SHARING — topbar pill: "Shared — view only" / "Shared by x@ — can edit" */
.share-mode-pill {
  display: inline-flex;
  align-items: center;
  margin-left: 8px;
  padding: 2px 9px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  border-radius: 10px;
  white-space: nowrap;
  color: #1a7a43;
  background: #ecf9f1;
  border: 1px solid #a9dfc0;
}
.share-mode-pill.view {
  color: #8a6d1f;
  background: #fdf6e2;
  border-color: #e6cf8a;
}

/* v1.4.0 SHARING — share dialog */
.share-dialog-backdrop {
  position: fixed;
  inset: 0;
  z-index: 2100;
  display: none;
  align-items: flex-start;
  justify-content: center;
  padding-top: 16vh;
  background: rgba(20, 20, 20, 0.34);
  backdrop-filter: blur(2px);
}
.share-dialog-backdrop.visible { display: flex; }
.share-dialog {
  width: min(440px, 92vw);
  background: #ffffff;
  border-radius: 12px;
  box-shadow: 0 22px 56px rgba(0,0,0,0.22), 0 4px 12px rgba(0,0,0,0.08);
  padding: 14px 16px 16px;
  font-size: 12.5px;
}
.share-dialog-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 12px;
}
.share-dialog-title { font-weight: 600; font-size: 14px; }
.share-dialog-project {
  flex: 1;
  color: #9a9a9a;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.share-dialog-close {
  border: 0;
  background: transparent;
  font-size: 18px;
  line-height: 1;
  color: #9a9a9a;
  cursor: pointer;
  padding: 0 2px;
}
.share-dialog-close:hover { color: #1a1a1a; }
.share-dialog-row {
  display: flex;
  gap: 8px;
  align-items: center;
}
.share-email-input {
  flex: 1;
  padding: 7px 10px;
  border: 1px solid #d8d8d8;
  border-radius: 6px;
  font-size: 12.5px;
  outline: none;
}
.share-email-input:focus { border-color: #a8741a; }
.share-access-select {
  padding: 7px 6px;
  border: 1px solid #d8d8d8;
  border-radius: 6px;
  font-size: 12px;
  background: #fff;
  cursor: pointer;
}
.share-submit-btn {
  padding: 7px 14px;
  border: 0;
  border-radius: 6px;
  background: #1a1a1a;
  color: #fff;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}
.share-submit-btn:hover { background: #3a3a3a; }
.share-submit-btn:disabled { opacity: 0.5; cursor: default; }
.share-dialog-err {
  min-height: 16px;
  margin-top: 6px;
  font-size: 11.5px;
  color: #c4101e;
}
.share-list-head {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid #ececec;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #8a8a8a;
}
.share-list { max-height: 200px; overflow-y: auto; margin-top: 6px; }
.share-list-empty { padding: 8px 2px; color: #9a9a9a; font-size: 12px; }
.share-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 2px;
  border-bottom: 1px solid #f4f4f4;
}
.share-row:last-child { border-bottom: 0; }
.share-row-email {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.share-revoke {
  width: 22px; height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: #9a9a9a;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
}
.share-revoke:hover { background: #f4d8da; color: #c4101e; }
.share-revoke:disabled { opacity: 0.4; cursor: default; }

/* v1.5.3 DELETE GUARDS — typed-confirmation modal for project delete.
   Reuses the .share-dialog-backdrop / .share-dialog shell + .share-email-input;
   below are only the delete-specific bits, on the existing danger palette
   (#c4101e / #f4d8da from .share-revoke:hover). */
.delete-project-dialog { width: min(400px, 92vw); }
.delete-project-dialog .share-email-input { width: 100%; box-sizing: border-box; }
.delete-project-warning {
  margin: 2px 0 12px;
  padding: 8px 10px;
  background: #fdf1f2;
  border: 1px solid #f4d8da;
  border-radius: 6px;
  color: #8a1620;
  font-size: 12px;
  line-height: 1.45;
}
.delete-project-instruction {
  display: block;
  margin-bottom: 6px;
  font-size: 12px;
  color: #5a5a5a;
}
.delete-project-instruction code {
  padding: 1px 5px;
  background: #f4f4f4;
  border: 1px solid #e0e0e0;
  border-radius: 4px;
  font-size: 11.5px;
  color: #1a1a1a;
}
.delete-project-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 12px;
}
.delete-project-cancel {
  padding: 7px 14px;
  border: 1px solid #d8d8d8;
  border-radius: 6px;
  background: #ffffff;
  color: #1a1a1a;
  font-size: 12.5px;
  cursor: pointer;
}
.delete-project-cancel:hover { background: #f0f0f0; }
.delete-project-go {
  padding: 7px 14px;
  border: 0;
  border-radius: 6px;
  background: #c4101e;
  color: #ffffff;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}
.delete-project-go:hover:not(:disabled) { background: #a30d19; }
.delete-project-go:disabled { opacity: 0.45; cursor: not-allowed; }

/* v1.5.3 DELETE GUARDS — two-step inline confirm ("<label> ✓ ✕") that the ×
   morphs into: share revoke, character Look remove, chat clear. */
.twostep-confirm {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  color: #8a1620;
  white-space: nowrap;
}
.twostep-label { font-weight: 600; }
.twostep-confirm button {
  width: 18px;
  height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid transparent;
  border-radius: 4px;
  background: transparent;
  font-size: 12px;
  line-height: 1;
  padding: 0;
  cursor: pointer;
}
.twostep-confirm .twostep-yes {
  color: #c4101e;
  border-color: #f4d8da;
  background: #fdf1f2;
}
.twostep-confirm .twostep-yes:hover { background: #f4d8da; }
.twostep-confirm .twostep-no { color: #5a5a5a; }
.twostep-confirm .twostep-no:hover { background: #f0f0f0; }

/* v0.22: cmd+K command palette — modal overlay, fuzzy-filtered actions */
.cmd-palette {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: none;
  align-items: flex-start;
  justify-content: center;
  padding-top: 14vh;
}
.cmd-palette.visible { display: flex; }
.cmdp-overlay {
  position: absolute;
  inset: 0;
  background: rgba(20, 20, 20, 0.34);
  backdrop-filter: blur(2px);
}
.cmdp-modal {
  position: relative;
  width: min(580px, 90vw);
  background: #ffffff;
  border-radius: 12px;
  box-shadow: 0 22px 56px rgba(0,0,0,0.22), 0 4px 12px rgba(0,0,0,0.08);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  max-height: 70vh;
  animation: cmdp-pop 0.14s ease-out;
}
@keyframes cmdp-pop {
  from { opacity: 0; transform: translateY(-6px) scale(0.99); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.cmdp-input {
  border: 0;
  outline: none;
  padding: 16px 20px;
  font-size: 15px;
  letter-spacing: 0.005em;
  color: #1a1a1a;
  background: #ffffff;
  border-bottom: 1px solid #ececec;
}
.cmdp-results {
  overflow-y: auto;
  flex: 1;
  padding: 6px 0;
}
.cmdp-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 16px;
  cursor: pointer;
  user-select: none;
}
.cmdp-row:hover, .cmdp-row.cmdp-active {
  background: #f5f5f5;
}
.cmdp-row.cmdp-active {
  background: #fbeaec;
}
.cmdp-icon {
  width: 18px; height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #6a6a6a;
  flex-shrink: 0;
}
.cmdp-icon svg { width: 14px; height: 14px; }
.cmdp-label {
  flex: 1;
  font-size: 13px;
  color: #1a1a1a;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cmdp-cat {
  font-size: 10.5px;
  color: #9a9a9a;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  flex-shrink: 0;
  margin-right: 6px;
}
.cmdp-shortcut {
  font-size: 11px;
  color: #b0b0b0;
  flex-shrink: 0;
}
.cmdp-shortcut kbd {
  background: #f0f0f0;
  border-radius: 3px;
  padding: 1px 5px;
  font-family: -apple-system, sans-serif;
  font-size: 10px;
  border: 1px solid #e0e0e0;
}
.cmdp-empty {
  padding: 16px 20px;
  color: #9a9a9a;
  font-size: 12px;
  text-align: center;
}
.cmdp-footer {
  border-top: 1px solid #ececec;
  padding: 8px 16px;
  display: flex;
  gap: 18px;
  font-size: 10.5px;
  color: #9a9a9a;
}
.cmdp-footer kbd {
  background: #f5f5f5;
  border-radius: 3px;
  padding: 0 4px;
  font-family: -apple-system, sans-serif;
  font-size: 10px;
  border: 1px solid #ececec;
  margin-right: 3px;
}

/* v0.35: script-doc node front */
.script-doc-body {
  flex: 1;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: linear-gradient(180deg, #fef7ec 0%, #fdf0db 100%);
}
.script-doc-empty {
  text-align: center;
  color: #7a5a3a;
  padding: 16px 8px;
}
.script-doc-title {
  font-size: 14px;
  font-weight: 600;
  color: #2a1a08;
  line-height: 1.25;
}
.script-doc-summary {
  font-size: 11.5px;
  color: #7a5a3a;
}
.script-doc-styles { display: flex; flex-wrap: wrap; gap: 4px; }
.script-doc-chip {
  display: inline-block;
  padding: 2px 8px;
  background: rgba(255,255,255,0.5);
  border: 1px solid #e0c89a;
  border-radius: 10px;
  font-size: 10px;
  color: #4a3018;
}
.script-doc-counts {
  display: flex;
  gap: 14px;
  font-size: 11px;
  color: #5a4018;
  padding-top: 4px;
  border-top: 1px solid rgba(228, 180, 100, 0.3);
}
.script-doc-open-btn, .script-doc-bind-btn, .script-doc-build-btn {
  padding: 8px 12px;
  background: #1a1a1a;
  color: #fff;
  border: 0;
  border-radius: 5px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
}
.script-doc-open-btn { margin-top: auto; }
.script-doc-bind-btn { margin-top: auto; }
.script-doc-open-btn:hover, .script-doc-bind-btn:hover, .script-doc-build-btn:hover { background: #2d2d2d; }
.script-doc-actions {
  margin-top: auto;
  display: flex;
  gap: 6px;
}
.script-doc-actions .script-doc-open-btn,
.script-doc-actions .script-doc-build-btn {
  margin-top: 0;
  flex: 1;
  padding: 8px 8px;
}
.script-doc-build-btn {
  background: #e21a2c;          /* Macy's red — high-signal "go" action */
  border: 1px solid #c0152a;
}
.script-doc-build-btn:hover { background: #c0152a; }
.script-doc-movie-btn {
  margin-top: 6px;
  padding: 9px 12px;
  background: #1a1a1a;
  color: #fff;
  border: 1px solid #1a1a1a;
  border-radius: 5px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  letter-spacing: 0.01em;
}
.script-doc-movie-btn:hover { background: #2d2d2d; }

/* v0.43j: movie-level audio toggle on script-doc body (between Build canvas
   and Make full movie). Reuses the same toggle pill style as video node. */
.script-doc-audio-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 0 2px;
  font-size: 11px;
  color: #5a4018;
}
.script-doc-audio-label {
  font-weight: 600;
  letter-spacing: 0.02em;
}
.script-doc-audio-row .setting-toggle .toggle-state {
  color: #5a4018;
}
.script-doc-audio-row .setting-toggle.on .toggle-state {
  color: #1a8a4f;
}

/* v0.44: auth gate — covers everything until session is established. */
.auth-gate {
  position: fixed; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: radial-gradient(circle at 30% 20%, #f9f6ef 0%, #ece6d8 70%);
  z-index: 9999;
}
body.authed .auth-gate { display: none; }
.auth-card {
  width: 360px; max-width: 92vw;
  padding: 32px 28px 26px;
  background: #fff;
  border-radius: 14px;
  box-shadow: 0 18px 50px rgba(0,0,0,0.12);
  display: flex; flex-direction: column; align-items: stretch;
  gap: 14px;
}
.auth-brand {
  display: flex; align-items: center; gap: 8px;
  justify-content: center;
}
.auth-logo { width: 22px; height: 22px; color: #e21a2c; }
.auth-logo svg { width: 100%; height: 100%; }
.auth-product { font-size: 15px; font-weight: 600; letter-spacing: 0.02em; color: #1a1a1a; }
.auth-subtitle { text-align: center; font-size: 12px; color: #6a6a6a; margin-bottom: 6px; }
.auth-google { display: flex; justify-content: center; min-height: 40px; }
.auth-divider {
  display: flex; align-items: center; gap: 10px;
  color: #a8a8a8; font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em;
  margin: 4px 0;
}
.auth-divider::before, .auth-divider::after {
  content: ''; flex: 1; height: 1px; background: #e0e0e0;
}
.auth-form { display: flex; flex-direction: column; gap: 8px; }
.auth-input {
  padding: 9px 11px;
  border: 1px solid #d8d8d8; border-radius: 6px;
  font-size: 13px; outline: none;
  transition: border-color 0.12s;
}
.auth-input:focus { border-color: #8a8a8a; }
.auth-submit {
  margin-top: 4px;
  padding: 10px 14px;
  background: #1a1a1a; color: #fff;
  border: 0; border-radius: 6px;
  font-size: 13px; font-weight: 500; cursor: pointer;
  transition: background 0.12s;
}
.auth-submit:hover { background: #2d2d2d; }
.auth-error { color: #c41e2a; font-size: 11.5px; min-height: 14px; text-align: center; }
.auth-footer-note { font-size: 10.5px; color: #9a9a9a; text-align: center; margin-top: 4px; }
.auth-footer-note code { font-family: 'SF Mono', Menlo, monospace; color: #5a5a5a; }

/* v0.45: hamburger account row + logout. Sits in its own section at the
   bottom of the menu so the user can verify which account they're using
   before clicking "Sign out". */
.hm-account-section { border-top: 1px solid rgba(0,0,0,0.08); }
.hm-account-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  font-size: 11.5px;
  color: #5a5a5a;
}
.hm-account-name {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: 500;
  color: #2a2a2a;
}
.hm-item.hm-logout { color: #c41e2a; }
.hm-item.hm-logout:hover { background: rgba(196, 30, 42, 0.06); }

/* v0.43k: Auto-fill + Assemble on Sequence node — distinct from the standard
   Generate button so the user sees it's the "do everything" path. Macy's red. */
.generate-btn.auto-fill-btn {
  margin-top: 6px;
  background: #e21a2c;
  border: 1px solid #c0152a;
}
.generate-btn.auto-fill-btn:hover { background: #c0152a; }

/* v0.43f: setting group header + textarea (for video audio block) */
.setting-row.setting-group-header {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid rgba(0,0,0,0.06);
}
.setting-row.setting-group-header:first-of-type { border-top: 0; margin-top: 0; }
.setting-group-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #6a6a6a;
}
.setting-row.setting-textarea-row {
  flex-direction: column;
  align-items: stretch;
}
.setting-row.setting-textarea-row .setting-label { margin-bottom: 4px; }
.setting-input.setting-textarea {
  padding: 0;
  border: 0;
  background: transparent;
}
.setting-textarea-input {
  width: 100%;
  min-height: 38px;
  padding: 6px 8px;
  background: #fff;
  border: 1px solid #d8d8d8;
  border-radius: 4px;
  font-family: inherit;
  font-size: 11px;
  color: #2a2a2a;
  resize: vertical;
  outline: none;
  box-sizing: border-box;
}
.setting-textarea-input:focus { border-color: #a8a8a8; }

/* v0.43g: toggle pill switch */
.setting-input.setting-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  user-select: none;
}
.setting-toggle .toggle-track {
  position: relative;
  width: 32px;
  height: 18px;
  border-radius: 9px;
  background: #d8d8d8;
  transition: background 0.18s;
}
.setting-toggle .toggle-thumb {
  position: absolute;
  top: 2px; left: 2px;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 2px rgba(0,0,0,0.18);
  transition: transform 0.18s;
}
.setting-toggle.on .toggle-track { background: #1a8a4f; }
.setting-toggle.on .toggle-thumb { transform: translateX(14px); }
.setting-toggle .toggle-state {
  font-size: 11px;
  color: #6a6a6a;
  font-weight: 500;
}
.setting-toggle.on .toggle-state { color: #1a8a4f; }

/* When Audio toggle is OFF, hide the sub-settings (soundscape / voiceover / direction) */
.settings.audio-off .setting-row.audio-only { display: none; }

/* v0.43i: used-prompt panel — shows the actual prompt that hit Veo/Imagen
   for the selected gen. Lets the user iterate by reading what was rendered
   from. Sits between settings and gallery on the back of asset cards. */
.used-prompt-panel {
  margin: 8px 16px 4px;
  padding: 10px 12px;
  background: #fafafa;
  border: 1px solid #e8e8e8;
  border-radius: 6px;
}
.used-prompt-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 4px;
}
.used-prompt-title {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #6a6a6a;
}
.used-prompt-copy {
  padding: 2px 8px;
  background: #fff;
  border: 1px solid #d8d8d8;
  border-radius: 4px;
  font-size: 10px;
  font-weight: 500;
  color: #3a3a3a;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.used-prompt-copy:hover { background: #f0f0f0; border-color: #b8b8b8; }
.used-prompt-body {
  max-height: 96px;
  overflow-y: auto;
  font-size: 11px;
  line-height: 1.5;
  color: #2a2a2a;
  white-space: pre-wrap;
  word-break: break-word;
  font-family: 'SF Mono', Menlo, monospace;
}

/* v0.43: document node — generic file wrapper. Slightly cooler tone than
   script-doc so the two read as distinct concepts side by side. */
.document-body {
  flex: 1;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: linear-gradient(180deg, #f6f3ec 0%, #ece6d8 100%);
}

/* v0.66: audio node — synthesized VO / dialogue line */
.audio-body {
  flex: 1;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: linear-gradient(180deg, #f1eef8 0%, #e6e0f3 100%);
}
.audio-line {
  font-size: 12.5px;
  line-height: 1.45;
  color: #2a2438;
  font-style: italic;
}
.audio-line-empty { color: #9a93ad; font-style: normal; }
.audio-player { width: 100%; height: 34px; }
.audio-status {
  font-size: 11px;
  color: #6a6280;
  display: flex;
  align-items: center;
  gap: 6px;
}
.audio-status-error { color: #b03a3a; }
.audio-spinner {
  width: 12px; height: 12px;
  border: 2px solid #c9bfe0;
  border-top-color: #6a4fb0;
  border-radius: 50%;
  display: inline-block;
  animation: docSpin 0.7s linear infinite;
}
.audio-chips { display: flex; flex-wrap: wrap; gap: 4px; }
.audio-chip {
  font-size: 10px;
  padding: 2px 7px;
  border-radius: 9px;
  background: #ffffff;
  border: 1px solid #d8d0e8;
  color: #5a5270;
  white-space: nowrap;
}
.audio-chip-narration { background: #ece7f7; border-color: #cdbfe8; color: #5a3f9a; }
.audio-chip-dialogue  { background: #e7f0f7; border-color: #bfd4e8; color: #3f6a9a; }
.node.minimized .audio-body { display: none; }
.document-empty {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 18px 12px;
  border: 1.5px dashed #c8bfa8;
  border-radius: 8px;
  color: #6a5a3a;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.document-empty:hover {
  background: rgba(255,255,255,0.4);
  border-color: #a89868;
}
.document-empty-icon {
  width: 28px; height: 28px;
  color: #8a7848;
  margin-bottom: 6px;
}
.document-empty-icon svg { width: 100%; height: 100%; }
.document-empty-title {
  font-size: 12.5px;
  font-weight: 500;
  color: #4a3818;
  margin-bottom: 4px;
}
.document-empty-hint {
  font-size: 10.5px;
  color: #8a7848;
  line-height: 1.45;
  max-width: 240px;
}
.document-uploading {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
}
.document-spinner {
  width: 22px; height: 22px;
  border: 2px solid rgba(120, 90, 30, 0.2);
  border-top-color: #8a6818;
  border-radius: 50%;
  animation: docSpin 0.7s linear infinite;
}
@keyframes docSpin { to { transform: rotate(360deg); } }
.document-uploading-label {
  font-size: 11.5px;
  color: #7a5a3a;
}
.document-meta { display: flex; flex-direction: column; gap: 4px; }
.document-filename {
  font-size: 13.5px;
  font-weight: 600;
  color: #2a1a08;
  line-height: 1.3;
  word-break: break-all;
}
.document-meta-row {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: #6a5a3a;
}
.document-size { color: #7a6a4a; }
.document-chip {
  display: inline-block;
  padding: 1px 7px;
  background: rgba(255,255,255,0.55);
  border: 1px solid #d4c8a8;
  border-radius: 10px;
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #4a3818;
}
.document-chip-script    { background: #fef4e0; border-color: #e8c878; color: #6a4818; }
.document-chip-text      { background: #f0f0f0; border-color: #c8c8c8; color: #3a3a3a; }
.document-chip-markdown  { background: #e8f0ff; border-color: #aac0e8; color: #2a4870; }
.document-chip-json      { background: #f0e8ff; border-color: #c8b8e8; color: #4a2870; }
.document-chip-pdf       { background: #ffe8e0; border-color: #e8a888; color: #682818; }
.document-chip-unknown   { background: #e8e8e8; border-color: #b8b8b8; color: #585858; }
.document-chip-parsed    { background: #e0f0e0; border-color: #88c088; color: #1a5818; }
.document-preview {
  background: rgba(255,255,255,0.55);
  border: 1px solid rgba(180, 160, 100, 0.3);
  border-radius: 5px;
  padding: 8px 10px;
  max-height: 80px;
  overflow: hidden;
  font-size: 10px;
  line-height: 1.45;
  color: #3a2a18;
}
.document-preview pre {
  margin: 0;
  font-family: inherit;
  white-space: pre-wrap;
}
.document-action-btn {
  margin-top: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 12px;
  background: rgba(255,255,255,0.6);
  border: 1px solid #c8bfa8;
  border-radius: 5px;
  font-size: 12px;
  font-weight: 500;
  color: #2a1a08;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.12s, border-color 0.12s;
}
.document-action-btn:hover { background: rgba(255,255,255,0.9); border-color: #a89868; }
.document-action-btn svg { width: 14px; height: 14px; }
.document-action-btn.primary {
  background: #1a1a1a;
  border-color: #1a1a1a;
  color: #fff;
}
.document-action-btn.primary:hover { background: #2d2d2d; }

/* Document back-of-card */
.document-back {
  flex: 1;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  background: linear-gradient(180deg, #f6f3ec 0%, #ece6d8 100%);
  overflow-y: auto;
}
.document-back-empty {
  text-align: center;
  color: #6a5a3a;
  padding: 16px 8px;
}
.document-back-section { display: flex; flex-direction: column; gap: 5px; }
.document-back-label {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #8a7848;
  font-weight: 600;
}
.document-back-title {
  width: 100%;
  padding: 6px 8px;
  background: rgba(255,255,255,0.7);
  border: 1px solid #d4c8a8;
  border-radius: 4px;
  font-size: 13px;
  color: #2a1a08;
  outline: none;
}
.document-back-title:focus { border-color: #a89868; background: #fff; }
.document-back-meta {
  background: rgba(255,255,255,0.4);
  border: 1px solid rgba(180, 160, 100, 0.3);
  border-radius: 5px;
  padding: 4px 8px;
  display: flex;
  flex-direction: column;
}
.document-back-meta-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 4px 0;
  font-size: 11px;
  color: #6a5a3a;
  border-bottom: 1px solid rgba(180, 160, 100, 0.2);
}
.document-back-meta-row:last-child { border-bottom: 0; }
.document-back-meta-val {
  color: #2a1a08;
  font-weight: 500;
  max-width: 60%;
  text-align: right;
  word-break: break-all;
}
.document-preview-full {
  background: rgba(255,255,255,0.55);
  border: 1px solid rgba(180, 160, 100, 0.3);
  border-radius: 5px;
  padding: 8px 10px;
  max-height: 200px;
  overflow-y: auto;
  font-size: 10.5px;
  line-height: 1.5;
  color: #3a2a18;
}
.document-preview-full pre {
  margin: 0;
  font-family: 'SF Mono', Menlo, monospace;
  white-space: pre-wrap;
  word-break: break-word;
}
.document-back-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: auto;
  padding-top: 8px;
  border-top: 1px solid rgba(180, 160, 100, 0.3);
}
.document-back-actions .document-action-btn {
  flex: 1 1 auto;
  min-width: 110px;
  margin-top: 0;
}

.node.minimized .document-body { display: none; }

/* v0.43: OS file drop visual cue — slightly different tint vs internal lib drag,
   plus a centered banner explaining what'll happen ('Drop to upload'). */
#viewport.drop-target-file::after {
  border-color: rgba(80, 140, 220, 0.55);
  background: rgba(80, 140, 220, 0.05);
}
#viewport.drop-target-file::before {
  content: 'Drop files — images → image node · video → video node · other → document node';
  position: absolute;
  left: 50%;
  top: 64px;          /* clear of the topbar */
  transform: translateX(-50%);
  padding: 10px 18px;
  background: rgba(80, 140, 220, 0.94);
  color: #fff;
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.02em;
  border-radius: 18px;
  pointer-events: none;
  z-index: 1000;       /* above topbar so it's never clipped */
  box-shadow: 0 4px 18px rgba(0,0,0,0.22);
}

/* v0.35: Editable Prompting Script Editor — fullscreen modal */
.script-editor {
  position: fixed;
  inset: 0;
  z-index: 2500;
  display: none;
  flex-direction: column;
  background: #fafafa;
}
.script-editor.visible { display: flex; }
.script-editor-head {
  padding: 14px 24px;
  background: #1a1a1a;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid #2d2d2d;
  flex-shrink: 0;
}
.script-editor-head h2 {
  margin: 0;
  font-size: 16px;
  font-weight: 500;
  letter-spacing: 0.01em;
}
.script-editor-actions { display: flex; gap: 8px; }
.script-editor-actions button {
  padding: 6px 14px;
  background: #ffffff;
  color: #1a1a1a;
  border: 0;
  border-radius: 5px;
  font-size: 12.5px;
  cursor: pointer;
}
.script-editor-actions button:hover { background: #ececec; }
#script-editor-close {
  background: transparent;
  color: #ffffff;
  font-size: 22px;
  padding: 2px 12px;
  width: 36px;
}
#script-editor-close:hover { background: rgba(255,255,255,0.12); }
.script-editor-body {
  flex: 1;
  overflow-y: auto;
  padding: 24px;
}
.se-section {
  background: #ffffff;
  border: 1px solid #e6e6e6;
  border-radius: 8px;
  padding: 16px;
  margin-bottom: 16px;
}
.se-section-title {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #6a6a6a;
  font-weight: 500;
  margin-bottom: 10px;
}
.se-style-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.se-style-cell { display: flex; flex-direction: column; gap: 4px; }
.se-style-label { font-size: 10px; color: #8a8a8a; text-transform: uppercase; letter-spacing: 0.06em; }
.se-style-input, .se-entity-name, .se-entity-input, .se-entity-select, .se-shot-name, .se-shot-heading, .se-scene-name, .se-scene-heading, .se-clip-name {
  padding: 6px 8px;
  border: 1px solid #d0d0d0;
  border-radius: 4px;
  font-size: 12px;
  font-family: inherit;
}
.se-roster {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
}
.se-entity-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px;
  background: #fafafa;
  border: 1px solid #ececec;
  border-radius: 6px;
}
.se-entity-card .se-entity-name { font-weight: 500; }
.se-entity-desc {
  padding: 6px 8px;
  border: 1px solid #d0d0d0;
  border-radius: 4px;
  font-size: 11.5px;
  font-family: inherit;
  resize: vertical;
  min-height: 50px;
}
.se-entity-meta { font-size: 9.5px; color: #9a9a9a; letter-spacing: 0.02em; }
.se-empty { padding: 12px; color: #9a9a9a; font-size: 12px; }
.se-scene {
  background: #fafafa;
  border: 1px solid #ececec;
  border-radius: 6px;
  padding: 12px;
  margin-bottom: 12px;
}
.se-scene-head {
  display: grid;
  grid-template-columns: 200px 1fr auto;
  gap: 8px;
  align-items: center;
  margin-bottom: 10px;
}
.se-scene-name { font-weight: 600; }
.se-scene-id, .se-shot-id, .se-clip-id { font-size: 10px; color: #9a9a9a; font-family: ui-monospace, monospace; }
.se-shot {
  background: #ffffff;
  border: 1px solid #e6e6e6;
  border-radius: 5px;
  padding: 10px;
  margin: 8px 0;
}
.se-shot-head { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 6px; }
.se-shot-name { font-weight: 500; flex: 0 0 200px; }
.se-shot-meta { font-size: 10.5px; color: #7a7a7a; }
.se-shot-action {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid #ececec;
  border-radius: 4px;
  font-size: 11.5px;
  font-family: inherit;
  resize: vertical;
  min-height: 36px;
  margin-bottom: 8px;
}
.se-clips-row { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px; }
.se-clip {
  flex: 0 0 240px;
  background: #fafafa;
  border: 1px solid #ececec;
  border-radius: 5px;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.se-clip-head { display: flex; gap: 6px; align-items: center; }
.se-clip-name { flex: 1; font-size: 11.5px; font-weight: 500; }
.se-clip-cell {
  width: 100%;
  padding: 4px 6px;
  border: 1px solid #d8d8d8;
  border-radius: 3px;
  font-size: 11px;
  font-family: inherit;
  resize: vertical;
  min-height: 32px;
}
.se-clip-cell:focus { outline: 1px solid #1a1a1a; border-color: #1a1a1a; }
.se-clip-foot {
  display: flex;
  gap: 10px;
  align-items: center;
  font-size: 10.5px;
  color: #6a6a6a;
}
.se-clip-num { width: 32px; padding: 2px 4px; border: 1px solid #d0d0d0; border-radius: 3px; font-size: 11px; }
.se-clip-junction { padding: 2px 4px; border: 1px solid #d0d0d0; border-radius: 3px; font-size: 11px; }

/* v0.30: character / place reference-set back-card body */
.refset-back {
  padding: 12px 14px;
  font-size: 12px;
  line-height: 1.4;
  overflow-y: auto;
  flex: 1;
}
.refset-section-title {
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #9a9a9a;
  margin-top: 10px;
  margin-bottom: 4px;
  font-weight: 500;
}
.refset-section-title:first-child { margin-top: 0; }
.refset-name.editable, .refset-desc.editable {
  outline: none;
  cursor: text;
  white-space: pre-wrap;
  padding: 6px 8px;
  border: 1px solid #ececec;
  border-radius: 4px;
  background: #fafafa;
}
.refset-name.editable:focus, .refset-desc.editable:focus {
  background: #ffffff;
  border-color: #1a1a1a;
}
.refset-name.editable:empty::before, .refset-desc.editable:empty::before {
  content: attr(data-placeholder);
  color: #b0b0b0;
  font-style: italic;
}
.refset-name.editable { font-weight: 500; }
.refset-desc.editable { min-height: 50px; font-size: 11.5px; color: #3a3a3a; }
.refset-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  margin-top: 4px;
}
.refset-cell {
  position: relative;
  aspect-ratio: 4/5;
  background: #fff;
  border-radius: 4px;
  overflow: hidden;
  border: 1px solid #ececec;
  cursor: pointer;
}
.refset-cell:hover { border-color: #1a1a1a; }
.refset-cell img {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.refset-cell-del {
  position: absolute;
  top: 3px; right: 3px;
  width: 18px; height: 18px;
  background: rgba(0,0,0,0.6);
  color: #fff;
  border: 0;
  border-radius: 9px;
  cursor: pointer;
  font-size: 11px;
  line-height: 1;
  padding: 0;
  display: none;
}
.refset-cell:hover .refset-cell-del { display: block; }
.refset-cell-del:hover { background: rgba(228,30,46,0.85); }
.refset-cell-label {
  position: absolute;
  bottom: 0; left: 0; right: 0;
  background: rgba(0,0,0,0.55);
  color: #fff;
  font-size: 9px;
  padding: 2px 4px;
  text-align: center;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.refset-actions {
  display: flex;
  gap: 6px;
  margin-top: 12px;
}
.refset-actions .generate-btn { flex: 1; }
.refset-actions .generate-btn.ghost {
  flex: 0 0 auto;
  background: #ffffff;
  color: #1a1a1a;
  border: 1px solid #d0d0d0;
}
.refset-actions .generate-btn.ghost:hover { background: #f5f5f5; }

/* v0.82.0: character seed-images section — user-provided photos that anchor
   the model's likeness. Slightly green-tinted cells differentiate them
   visually from the model-generated reference grid below. */
.refset-seeds-hint {
  font-size: 10px;
  color: #7a7a7a;
  margin: -4px 0 8px 0;
  line-height: 1.4;
}
.refset-grid-seeds {
  margin-bottom: 14px;
}
.refset-cell-seed {
  border: 1px solid #c4d9c8;
  background: #f6faf7;
}
.refset-cell-add {
  border: 1px dashed #b0b0b0;
  background: #fafafa;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: #7a7a7a;
}
.refset-cell-add:hover {
  border-color: #1a1a1a;
  background: #f0f0f0;
  color: #1a1a1a;
}
.refset-cell-add-icon {
  font-size: 20px;
  font-weight: 300;
  line-height: 1;
}

/* v0.42.1-fa: Character v2 — structured CharacterDescription form on the
   character node back card. DESIGN.md tokens throughout — labels use
   --text-label uppercase letter-spacing, inputs use --surface-input, dividers
   match the existing refset section pattern. Tight density so all 5 sections
   fit comfortably in a 280px card back. */
.charv2-section {
  border-top: 1px solid #ededed;            /* --border-section */
  padding-top: 8px;
  margin-top: 8px;
}
.charv2-section:first-of-type { border-top: 0; padding-top: 0; margin-top: 6px; }
.charv2-section-head {
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #5a5a5a;                            /* --text-tertiary */
  margin-bottom: 6px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
/* v0.42.2-fb: Auto-tag button inline with the Tags section header. Calm,
   secondary affordance — doesn't compete with the primary Generate CTA. */
.charv2-autotag-btn {
  background: #fcfcfc;                        /* --surface-input */
  border: 1px solid #e6e6e6;                  /* --border-input */
  border-radius: 6px;
  padding: 2px 8px;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: #5a5a5a;                             /* --text-tertiary */
  cursor: pointer;
  text-transform: none;
  transition: border-color 120ms cubic-bezier(0.4, 0.1, 0.2, 1), color 120ms;
}
.charv2-autotag-btn:hover {
  border-color: #5a8d6d;                      /* --type-character */
  color: #5a8d6d;
}
.charv2-sublabel {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #7a7a7a;                            /* --text-muted */
  margin-top: 6px;
  margin-bottom: 4px;
}
.charv2-row {
  display: flex;
  gap: 6px;
  margin-bottom: 4px;
}
.charv2-field {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}
.charv2-field-full { flex-basis: 100%; }
.charv2-label {
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #9a9a9a;                            /* --text-placeholder */
  margin-bottom: 2px;
}
.charv2-input {
  background: #fcfcfc;                       /* --surface-input */
  border: 1px solid #e6e6e6;                 /* --border-input */
  border-radius: 6px;
  padding: 5px 7px;
  font: 400 12px/1.3 -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", Roboto, sans-serif;
  color: #1a1a1a;                            /* --text-primary */
  outline: none;
  width: 100%;
  box-sizing: border-box;
  transition: border-color 120ms cubic-bezier(0.4, 0.1, 0.2, 1);
}
.charv2-input:hover { border-color: #c0c0c0; }    /* --border-input-hover */
.charv2-input:focus { border-color: #5a8d6d; }    /* --type-character on focus */
.charv2-input::placeholder { color: #c0c0c0; }    /* --text-disabled — subtle */

.charv2-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-bottom: 4px;
}
.charv2-tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 10.5px;
  letter-spacing: 0.02em;
  color: #3a3a3a;                            /* --text-secondary */
  background: #f0f6f2;                       /* tinted toward --type-character */
  border: 1px solid #d8e5dc;
  border-radius: 6px;
  padding: 2px 6px;
}
.charv2-tag-del {
  background: none;
  border: 0;
  color: #7a7a7a;
  font-size: 13px;
  line-height: 1;
  padding: 0 0 0 2px;
  cursor: pointer;
  transition: color 120ms;
}
.charv2-tag-del:hover { color: #e21a2c; }     /* --brand-red on delete intent */

.charv2-tag-input {
  font-size: 11px;
  padding: 4px 7px;
}

.charv2-notes {
  background: #fcfcfc;                       /* --surface-input */
  border: 1px solid #e6e6e6;                 /* --border-input */
  border-radius: 6px;
  padding: 6px 8px;
  font: 400 12px/1.4 -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", Roboto, sans-serif;
  color: #1a1a1a;
  outline: none;
  width: 100%;
  min-height: 48px;
  box-sizing: border-box;
  resize: vertical;
  transition: border-color 120ms cubic-bezier(0.4, 0.1, 0.2, 1);
}
.charv2-notes:hover { border-color: #c0c0c0; }
.charv2-notes:focus { border-color: #5a8d6d; }
.charv2-notes::placeholder { color: #c0c0c0; }

/* v0.42.3-fe: Character front-card profile meta. Sits between the ref
   thumb and the footer. Subtle off-white surface (--surface-card-section-back
   per DESIGN.md) so it reads as supporting chrome, not content. Summary truncates
   at one line; tags render as a tight row with a +N overflow chip. */
.charv2-front-meta {
  background: #fbfbfa;                         /* --surface-card-section-back */
  border-top: 1px solid #ededed;               /* --border-section */
  padding: 6px 10px 7px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.charv2-front-summary {
  font: 400 11px/1.35 -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", Roboto, sans-serif;
  color: #5a5a5a;                              /* --text-tertiary */
  letter-spacing: 0.01em;
  /* Single line truncation — the title= attr surfaces the full prose on hover */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.charv2-front-tags {
  display: flex;
  flex-wrap: nowrap;        /* keep on one line, overflow chip handles the rest */
  gap: 4px;
  overflow: hidden;
}
.charv2-front-tag {
  flex-shrink: 0;
  font: 500 10px/1.2 -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", Roboto, sans-serif;
  letter-spacing: 0.02em;
  color: #3a3a3a;                              /* --text-secondary */
  background: #f0f6f2;                         /* tinted to --type-character */
  border: 1px solid #d8e5dc;
  border-radius: 5px;
  padding: 2px 6px;
  max-width: 140px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.charv2-front-tag-more {
  flex-shrink: 0;
  font: 500 10px/1.2 -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", Roboto, sans-serif;
  letter-spacing: 0.02em;
  color: #7a7a7a;                              /* --text-muted */
  background: #f5f5f5;
  border: 1px solid #e6e6e6;
  border-radius: 5px;
  padding: 2px 6px;
  cursor: default;
}

/* v0.42.7-fd: QA verdict chip on character front meta. Three states by
   verdict: pass (calm green), borderline (amber), fail (desaturated red).
   Tight 10px chip — supporting, not competing with tags. */
.charv2-front-qa {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  width: fit-content;
  font: 500 10px/1.2 -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", Roboto, sans-serif;
  letter-spacing: 0.02em;
  border: 1px solid transparent;
  border-radius: 5px;
  padding: 2px 6px;
  cursor: help;
  margin-top: 2px;
}
.charv2-front-qa.charv2-qa-pass       { color: #2f6b41; background: #ecf6ef; border-color: #cee0d4; }
.charv2-front-qa.charv2-qa-borderline { color: #8a5a16; background: #fbf3e5; border-color: #e9d9b7; }
.charv2-front-qa.charv2-qa-fail       { color: #b41b2a; background: #faecec; border-color: #e7c4c4; }
.charv2-front-qa.charv2-qa-unknown    { color: #7a7a7a; background: #f5f5f5; border-color: #e6e6e6; }

/* v0.42.6-fc: secondary actions row on character back card — visual hierarchy
   below primary actions so "Generate sheet" reads as a structured-mode tool. */
.refset-actions-secondary {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid #ededed;                /* --border-section */
}

/* v0.42.8-ff: Looks subsystem UI on the character back card. Each look is a
   compact card-row inside the Looks section. Tight density to fit multiple
   looks comfortably. */
.charv2-section-looks .charv2-look-row {
  background: #fbfbfa;                          /* --surface-card-section-back */
  border: 1px solid #ededed;
  border-radius: 6px;
  padding: 6px 7px;
  margin-bottom: 6px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.charv2-look-head {
  display: flex;
  align-items: center;
  gap: 4px;
}
.charv2-look-head .charv2-look-name {
  flex: 1;
  font-weight: 500;
}
.charv2-look-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  margin-top: 2px;
}
.charv2-look-meta {
  font: 400 10px/1.2 -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", Roboto, sans-serif;
  color: #7a7a7a;                              /* --text-muted */
  letter-spacing: 0.02em;
}
.charv2-look-empty {
  font-size: 11px;
  color: #9a9a9a;                              /* --text-placeholder */
  line-height: 1.4;
  padding: 4px 0;
}

/* v0.29: prompt body editable — empty-state placeholder, focus styles */
.prompt-body.editable {
  outline: none;
  cursor: text;
  user-select: text;
  -webkit-user-select: text;
  white-space: pre-wrap;
}
.prompt-body.editable:empty::before {
  content: attr(data-placeholder);
  color: #b0b0b0;
  font-style: italic;
}
.prompt-body.editable:focus {
  background: #fafafa;
  outline: 1px solid #1a1a1a;
  border-radius: 4px;
}

/* v0.29: product node front carousel — click left/right halves to navigate */
.thumb-product-carousel { position: relative; }
.carousel-zone {
  position: absolute;
  top: 0; bottom: 0;
  width: 50%;
  background: transparent;
  border: 0;
  cursor: pointer;
  z-index: 5;
}
.carousel-zone.left  { left: 0; }
.carousel-zone.right { right: 0; }
.carousel-zone:hover {
  background: linear-gradient(to right, rgba(0,0,0,0.18), transparent 60%);
}
.carousel-zone.right:hover {
  background: linear-gradient(to left, rgba(0,0,0,0.18), transparent 60%);
}
.carousel-zone.disabled { cursor: default; opacity: 0; pointer-events: none; }
.carousel-indicator {
  position: absolute;
  bottom: 8px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0,0,0,0.55);
  color: #fff;
  font-size: 10px;
  padding: 2px 8px;
  border-radius: 10px;
  letter-spacing: 0.04em;
  pointer-events: none;
  z-index: 6;
}

/* v0.29: product node back-of-card body — full XAPI data display */
.product-back {
  padding: 12px 14px;
  font-size: 12px;
  line-height: 1.4;
  overflow-y: auto;
  flex: 1;
}
.product-back-empty {
  padding: 24px 12px;
  text-align: center;
  color: #9a9a9a;
}
.product-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 4px;
}
.product-brand {
  font-size: 10.5px;
  color: #9a9a9a;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 500;
}
.product-price {
  font-size: 13px;
  color: #1a1a1a;
  font-weight: 600;
}
.product-name {
  font-size: 13px;
  color: #1a1a1a;
  font-weight: 500;
  margin-bottom: 4px;
}
.product-meta {
  font-size: 10.5px;
  color: #9a9a9a;
  margin-bottom: 10px;
}
.product-section-title {
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #9a9a9a;
  margin-top: 10px;
  margin-bottom: 4px;
  font-weight: 500;
}
.product-desc {
  font-size: 11.5px;
  color: #4a4a4a;
}
.product-features {
  margin: 0;
  padding-left: 16px;
  font-size: 11px;
  color: #3a3a3a;
}
.product-features li { margin-bottom: 2px; }
.product-colors {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.product-color-chip {
  font-size: 10px;
  padding: 2px 8px;
  background: #f5f5f5;
  border-radius: 10px;
  color: #3a3a3a;
}
.product-image-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
  margin-top: 4px;
}
.product-image-cell {
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: 4px;
  background: #fff;
  border: 1px solid #ececec;
  cursor: pointer;
  padding: 0;
  position: relative;
}
.product-image-cell:hover { border-color: #1a1a1a; }
.product-image-cell img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* v1.5.0-product-xapi: hero/reference image selection in the gallery */
.product-image-cell.is-hero {
  border-color: #a01525;
  box-shadow: 0 0 0 2px rgba(160, 21, 37, 0.25);
}
.product-hero-badge {
  position: absolute;
  bottom: 2px;
  left: 2px;
  background: #a01525;
  color: #fff;
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.06em;
  padding: 1px 4px;
  border-radius: 3px;
  pointer-events: none;
}
/* v1.5.0-product-xapi: webID / UPC / URL lookup box on the product node */
.product-lookup {
  display: flex;
  gap: 6px;
  margin-top: 4px;
  align-items: center;
}
.product-lookup-input {
  flex: 1;
  min-width: 0;
  font-size: 11px;
  padding: 5px 8px;
  border: 1px solid #d8d8d8;
  border-radius: 6px;
  background: #fff;
  color: #1a1a1a;
}
.product-lookup-input:focus {
  outline: none;
  border-color: #a01525;
}
.product-lookup-btn {
  font-size: 11px;
  font-weight: 600;
  padding: 5px 10px;
  border: none;
  border-radius: 6px;
  background: #a01525;
  color: #fff;
  cursor: pointer;
  white-space: nowrap;
}
.product-lookup-btn:hover { background: #87101f; }
.product-lookup-status { min-height: 14px; margin-top: 3px; }
.product-lookup-error { font-size: 10.5px; color: #a01525; }
.product-lookup-loading { font-size: 10.5px; color: #7a7a7a; }
.product-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 14px;
}
.product-link {
  font-size: 11px;
  color: #e21a2c;
  text-decoration: none;
}
.product-link:hover { text-decoration: underline; }

/* v0.29: lightbox modal — near-fullscreen image/video viewer */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: none;
  align-items: center;
  justify-content: center;
}
.lightbox.visible { display: flex; }
.lightbox-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 15, 15, 0.85);
  backdrop-filter: blur(6px);
  cursor: zoom-out;
}
.lightbox-content {
  position: relative;
  max-width: 92vw;
  max-height: 88vh;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1;
  animation: lightbox-pop 0.18s ease-out;
}
.lightbox-content img,
.lightbox-content video {
  max-width: 92vw;
  max-height: 88vh;
  border-radius: 6px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.4);
  background: #1a1a1a;
}
.lightbox-close {
  position: absolute;
  top: 18px;
  right: 18px;
  width: 36px; height: 36px;
  background: rgba(255,255,255,0.12);
  border: 0;
  border-radius: 18px;
  color: #fff;
  font-size: 20px;
  cursor: pointer;
  z-index: 2;
}
.lightbox-close:hover { background: rgba(255,255,255,0.22); }
.lightbox-meta {
  position: absolute;
  bottom: 88px;  /* lifted above the thumb strip */
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0,0,0,0.55);
  color: rgba(255,255,255,0.9);
  font-size: 12px;
  padding: 6px 14px;
  border-radius: 14px;
  z-index: 2;
  max-width: 80vw;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* v0.41: gallery-navigator additions */
.lightbox-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 56px; height: 56px;
  background: rgba(255,255,255,0.12);
  border: 0;
  border-radius: 28px;
  color: #fff;
  font-size: 36px;
  line-height: 1;
  cursor: pointer;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-bottom: 4px;
}
.lightbox-nav:hover:not(:disabled) { background: rgba(255,255,255,0.22); }
.lightbox-nav:disabled { opacity: 0.25; cursor: default; }
.lightbox-nav-prev { left: 24px; }
.lightbox-nav-next { right: 24px; }
.lightbox-strip {
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  display: flex;
  gap: 6px;
  max-width: 92vw;
  overflow-x: auto;
  padding: 8px 12px;
  background: rgba(0,0,0,0.4);
  border-radius: 10px;
  backdrop-filter: blur(6px);
}
.lb-thumb {
  position: relative;
  flex: 0 0 64px;
  width: 64px; height: 64px;
  background: #1a1a1a;
  border: 2px solid transparent;
  border-radius: 5px;
  overflow: hidden;
  padding: 0;
  cursor: pointer;
  transition: border-color 0.1s, transform 0.1s;
}
.lb-thumb:hover { transform: scale(1.06); }
.lb-thumb.active { border-color: #e21a2c; }
.lb-thumb img, .lb-thumb video {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.lb-thumb-tag {
  position: absolute;
  bottom: 2px; right: 2px;
  background: rgba(0,0,0,0.7);
  color: #fff;
  font-size: 8px;
  padding: 1px 4px;
  border-radius: 3px;
}
@keyframes lightbox-pop {
  from { opacity: 0; transform: scale(0.96); }
  to   { opacity: 1; transform: scale(1); }
}

/* v0.38: gallery cells render real assets when available */
.cell-thumb.cell-real { background: #1a1a1a; overflow: hidden; }
.cell-thumb.cell-real img, .cell-thumb.cell-real video {
  width: 100%; height: 100%; object-fit: cover; display: block;
}

/* v0.38: minimized node — compact card showing only title + thumb */
.node.minimized .card-front .prompt-body,
.node.minimized .card-front .script-body,
.node.minimized .card-front .card-footer,
.node.minimized .card-front .thumb,
.node.minimized .script-doc-body { display: none; }
/* v0.43h: keep the hover actions visible on minimized nodes so the minimize
   button is still clickable — used to be hidden, leaving no way to expand.
   Compact them so they don't overflow the smaller title row. */
.node.minimized .card-front .hover-actions {
  top: 4px; right: 4px;
}
.node.minimized .card,
.node.minimized .card-face { height: auto; min-height: 0; }
.node.minimized .card-front { padding: 0; }
.node.minimized .title-row { padding: 8px 12px; border-bottom: 0; }
.node.minimized { transform: scale(0.85); transform-origin: top left; }
.node.minimized:hover { transform: scale(1); }

/* v0.36: Object node — described-mode back-card UI */
.object-mode-banner {
  font-size: 11px;
  color: #7a7a7a;
  padding: 6px 10px;
  background: #fafafa;
  border: 1px solid #ececec;
  border-radius: 4px;
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.object-mode-switch {
  background: transparent;
  border: 0;
  color: #e21a2c;
  cursor: pointer;
  font-size: 11px;
  font-weight: 500;
  padding: 0;
}
.object-mode-switch:hover { text-decoration: underline; }
.object-section-title {
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #9a9a9a;
  font-weight: 500;
  margin-top: 12px;
  margin-bottom: 4px;
}
.object-name-input, .object-desc-input {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid #d0d0d0;
  border-radius: 4px;
  font-size: 12px;
  font-family: inherit;
}
.object-name-input { font-weight: 500; }
.object-desc-input { min-height: 52px; resize: vertical; font-size: 11.5px; color: #3a3a3a; }
.object-name-input:focus, .object-desc-input:focus { outline: 1px solid #1a1a1a; border-color: #1a1a1a; }
.object-refs-row {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 4px;
}
.object-ref-thumb {
  position: relative;
  width: 56px; height: 56px;
  border-radius: 4px;
  overflow: hidden;
  background: #fff;
  border: 1px solid #ececec;
}
.object-ref-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.object-ref-del {
  position: absolute;
  top: 2px; right: 2px;
  width: 16px; height: 16px;
  background: rgba(0,0,0,0.6);
  color: #fff;
  border: 0;
  border-radius: 8px;
  cursor: pointer;
  font-size: 10px;
  padding: 0;
  line-height: 1;
  display: none;
}
.object-ref-thumb:hover .object-ref-del { display: block; }
.object-ref-add {
  width: 56px; height: 56px;
  border: 1.5px dashed #c0c0c0;
  background: transparent;
  border-radius: 4px;
  color: #9a9a9a;
  font-size: 22px;
  font-weight: 200;
  line-height: 1;
  cursor: pointer;
}
.object-ref-add:hover { border-color: #1a1a1a; color: #1a1a1a; }
.object-angles-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 5px;
  margin-top: 4px;
}
.object-angle-cell {
  position: relative;
  aspect-ratio: 1;
  border-radius: 4px;
  overflow: hidden;
  background: #fafafa;
  border: 1px solid #ececec;
}
.object-angle-cell img { width: 100%; height: 100%; object-fit: cover; }
.object-angle-label {
  position: absolute;
  bottom: 0; left: 0; right: 0;
  background: rgba(0,0,0,0.55);
  color: #fff;
  font-size: 9px;
  padding: 1px 4px;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.object-actions {
  display: flex;
  gap: 6px;
  margin-top: 12px;
}
.object-actions .generate-btn { flex: 1; }
.object-actions .generate-btn.ghost {
  flex: 0 0 auto;
  background: #ffffff;
  color: #1a1a1a;
  border: 1px solid #d0d0d0;
}

/* v0.27: product library card + product node thumbnail */
.library-product-icon {
  background: #ffffff;
  border-radius: 5px;
  overflow: hidden;
  width: 36px; height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid #ececec;
}
.library-product-icon img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* v0.26: real generated image inside a thumb */
.thumb.thumb-real {
  background: #1a1a1a;
}
.thumb-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* v0.21: library drag-to-canvas — drag visuals + drop target */
.library-item.dragging {
  opacity: 0.5;
  transform: scale(0.97);
  transition: opacity 0.1s, transform 0.1s;
}
body.lib-drag-in-flight #viewport {
  cursor: copy;
}
#viewport.drop-target::after {
  content: '';
  position: absolute;
  inset: 8px;
  pointer-events: none;
  border: 2px dashed rgba(226, 26, 44, 0.4);
  border-radius: 14px;
  background: rgba(226, 26, 44, 0.025);
  z-index: 10;
}

.save-status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-left: 4px;
  font-size: 11px;
  color: #9a9a9a;
  letter-spacing: 0.02em;
}
.save-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #5a8d6d;
  transition: background 0.18s, transform 0.18s;
}
.save-status.saving .save-dot {
  background: #b8853d;
  transform: scale(1.3);
}
.save-status.saving .save-text { color: #b8853d; }
.save-status.dirty .save-dot {
  background: #c0c0c0;
}
.save-status.dirty .save-text { color: #9a9a9a; }
.save-status.just-saved .save-dot {
  background: #5a8d6d;
  box-shadow: 0 0 0 4px rgba(90, 141, 109, 0.18);
}

.topbar-actions {
  display: flex;
  align-items: center;
  gap: 4px;
}
.topbar-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  font-size: 11.5px;
  color: #3a3a3a;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.topbar-btn svg { width: 14px; height: 14px; }
.topbar-btn:hover { background: #f0f0f0; color: #1a1a1a; }
.topbar-btn.active { background: #1a1a1a; color: #ffffff; border-color: #1a1a1a; }

/* ============================================================================
   Hamburger dropdown menu
   ============================================================================ */
.hamburger-menu {
  position: fixed;
  top: 44px;
  left: 12px;
  min-width: 240px;
  background: #ffffff;
  border: 1px solid #e6e6e6;
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.10);
  z-index: 95;
  padding: 6px;
  display: none;
  flex-direction: column;
  gap: 1px;
  animation: hm-in 0.16s cubic-bezier(0.4, 0.1, 0.2, 1);
}
.hamburger-menu.visible { display: flex; }
@keyframes hm-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.hm-section {
  display: flex;
  flex-direction: column;
  padding: 4px 0;
  border-bottom: 1px solid #ededed;
}
.hm-section:last-child { border-bottom: 0; }
.hm-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  background: transparent;
  border: 0;
  border-radius: 6px;
  font-size: 12.5px;
  color: #1a1a1a;
  cursor: pointer;
  text-align: left;
  width: 100%;
}
.hm-item:hover { background: #f0f0f0; }
.hm-item .hm-icon {
  width: 18px;
  height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #5a5a5a;
  font-size: 13px;
  font-weight: 500;
}
.hm-item span:nth-child(2) { flex: 1; }
.hm-item .hm-shortcut {
  font-size: 10.5px;
  color: #9a9a9a;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
}

/* Push viewport so it doesn't sit under the topbar visually */
#viewport { top: 0; }

/* ============================================================================
   Queue indicator (top-right) — Billy 2026-05-09: replaces version chip,
   mirrors current Stellar queue affordance. Lines progressively transparent.
   ============================================================================ */
.queue-indicator {
  position: fixed;
  top: 60px;
  right: 14px;
  z-index: 100;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px 6px 8px;
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(8px);
  border: 1px solid #e5e5e5;
  border-radius: 999px;
  font-size: 11px;
  letter-spacing: 0.02em;
  color: #1a1a1a;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.queue-indicator:hover { background: #ffffff; border-color: #c0c0c0; }
.queue-indicator.active { background: #1a1a1a; color: #ffffff; border-color: #1a1a1a; }
.queue-indicator svg {
  width: 14px;
  height: 14px;
  color: currentColor;
  flex-shrink: 0;
}
.queue-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: #ededed;
  color: #1a1a1a;
  font-size: 10.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.queue-indicator.active .queue-count { background: #ffffff; color: #1a1a1a; }
.queue-indicator.has-active .queue-count {
  /* When at least one generation is in flight, glow Macy's-red */
  background: #e21a2c;
  color: #ffffff;
  animation: queue-pulse 1.6s ease-in-out infinite;
}
@keyframes queue-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(226, 26, 44, 0); }
  50%      { box-shadow: 0 0 0 4px rgba(226, 26, 44, 0.20); }
}
.queue-label {
  color: #5a5a5a;
  letter-spacing: 0.04em;
  font-weight: 500;
}
.queue-indicator.active .queue-label { color: #ffffff; }

.queue-panel {
  position: fixed;
  top: 100px;
  right: 14px;
  width: 320px;
  max-height: 420px;
  background: #ffffff;
  border: 1px solid #e6e6e6;
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  z-index: 99;
  display: none;
  flex-direction: column;
  overflow: hidden;
  animation: hm-in 0.16s cubic-bezier(0.4, 0.1, 0.2, 1);
}
.queue-panel.visible { display: flex; }
.queue-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  border-bottom: 1px solid #ededed;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  background: #fafafa;
}
.queue-panel-sub {
  font-size: 10.5px;
  font-weight: 400;
  color: #9a9a9a;
  letter-spacing: 0.04em;
}
.queue-panel-body {
  padding: 8px 6px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.queue-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 6px;
}
.queue-row:hover { background: #f5f5f5; cursor: pointer; }
.queue-row .qr-icon {
  width: 22px;
  height: 22px;
  border-radius: 5px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #f0f0f0;
}
.queue-row .qr-meta { flex: 1; min-width: 0; }
.queue-row .qr-title {
  font-size: 12px;
  color: #1a1a1a;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.queue-row .qr-status {
  font-size: 10.5px;
  color: #7a7a7a;
  margin-top: 2px;
}
.queue-row.generating .qr-status { color: #b8853d; }
.queue-row.done .qr-status { color: #5a8d6d; }

.queue-panel-empty {
  padding: 24px 14px;
  text-align: center;
  color: #9a9a9a;
  font-size: 11.5px;
  letter-spacing: 0.02em;
}

/* ============================================================================
   Version chip (bottom-left, small, less prominent) — moved from top-right
   ============================================================================ */
.version-chip {
  position: fixed;
  bottom: 16px;
  left: 16px;
  z-index: 99;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px 4px 8px;
  background: rgba(255, 255, 255, 0.85);
  backdrop-filter: blur(6px);
  border: 1px solid #e5e5e5;
  border-radius: 999px;
  font-size: 10px;
  letter-spacing: 0.02em;
  color: #7a7a7a;
  pointer-events: none;
}
.version-chip .dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #e21a2c;
  box-shadow: 0 0 0 2px rgba(226, 26, 44, 0.16);
}

/* ----- Viewport + stage ------------------------------------------------- */
#viewport {
  position: fixed;
  inset: 0;
  overflow: hidden;
  cursor: grab;
  /* Subtle dot pattern on the stage background — neutral cool grey */
  background-color: #f5f5f5;
  background-image: radial-gradient(circle at 1px 1px, #d6d6d6 1px, transparent 0);
  background-size: 24px 24px;
}
#viewport.panning { cursor: grabbing; }

#stage {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  transform-origin: 0 0;
  will-change: transform;
  /* v0.26: stage above cables so node cards always win the z-index fight
     (Billy 2026-05-10: "cables should always run underneath node panels") */
  z-index: 2;
}

#cables {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 1;  /* below #stage = below all nodes */
}

/* ----- HUD (bottom-CENTER toolbar — Billy 2026-05-09) -------------------- */
.hud {
  position: fixed;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 100;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px;
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(8px);
  border: 1px solid #e5e5e5;
  border-radius: 10px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
}
.hud-btn {
  width: 32px;
  height: 32px;
  border: 0;
  background: transparent;
  border-radius: 6px;
  font-size: 16px;
  color: #3a3a3a;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.hud-btn:hover { background: #f0f0f0; }
.hud-zoom {
  min-width: 48px;
  text-align: center;
  font-size: 12px;
  color: #5a5a5a;
  font-variant-numeric: tabular-nums;
}
.hud-divider {
  width: 1px;
  height: 18px;
  background: #e5e5e5;
  margin: 0 4px;
  display: inline-block;
}
.mode-btn { padding: 0; }
.mode-btn svg {
  width: 15px;
  height: 15px;
  pointer-events: none;
}
.mode-btn.active {
  background: #1a1a1a;
  color: #ffffff;
}
.mode-btn.active:hover {
  background: #2d2d2d;
}

/* In mouse mode, the cursor shows the user must hold spacebar to pan */
body[data-input-mode="mouse"] #viewport { cursor: default; }
body[data-input-mode="mouse"][data-space-held="1"] #viewport { cursor: grab; }
body[data-input-mode="mouse"][data-space-held="1"] #viewport.panning { cursor: grabbing; }

/* ============================================================================
   Mini-map (appears during drag/pan)
   ============================================================================ */
.minimap {
  position: fixed;
  bottom: 16px;
  right: 16px;
  width: 240px;
  height: 150px;
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(8px);
  border: 1px solid #e5e5e5;
  border-radius: 10px;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.08);
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition: opacity 0.18s, transform 0.18s;
  z-index: 100;
  overflow: hidden;
}
.minimap.visible {
  opacity: 1;
  transform: translateY(0);
}
.minimap svg {
  width: 100%;
  height: 100%;
  display: block;
}
.minimap-node {
  fill: #ffffff;
  stroke: #c0c0c0;
  stroke-width: 0.6;
}
.minimap-node.lit { fill: #ddd; }
.minimap-viewport {
  fill: rgba(226, 26, 44, 0.08);
  stroke: #e21a2c;
  stroke-width: 1;
  stroke-dasharray: 2 2;
}

/* Spacebar mode hint */
.mode-hint {
  position: fixed;
  bottom: 64px;
  left: 50%;
  transform: translateX(-50%);
  padding: 8px 14px;
  background: rgba(26, 26, 26, 0.92);
  color: #ffffff;
  font-size: 11.5px;
  border-radius: 8px;
  backdrop-filter: blur(8px);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s;
  z-index: 200;
  letter-spacing: 0.02em;
}
.mode-hint.visible { opacity: 1; }
.mode-hint kbd {
  display: inline-block;
  padding: 1px 5px;
  margin: 0 2px;
  background: #fff;
  color: #1a1a1a;
  border-radius: 3px;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 10px;
  font-weight: 600;
}

/* ============================================================================
   NODE — the card paradigm
   ============================================================================ */

.node {
  position: absolute;
  width: 280px;
  perspective: 1400px;        /* enables 3D card flip */
  z-index: 10;
}
.node.dragging { z-index: 30; }
/* Selection ring (v0.16) — shift+click toggles selection. Ring uses Macy's red. */
.node.selected .card-face {
  box-shadow:
    0 0 0 2px #e21a2c,
    0 1px 2px rgba(0, 0, 0, 0.04),
    0 4px 14px rgba(0, 0, 0, 0.08),
    0 0 0 6px rgba(226, 26, 44, 0.15);
}

/* Marquee selection rect (v0.17) — shift+drag in empty canvas */
.marquee {
  position: fixed;
  border: 1px dashed #1a1a1a;
  background: rgba(226, 26, 44, 0.06);
  pointer-events: none;
  z-index: 60;
  display: none;
}
.marquee.visible { display: block; }
/* Auto-organize: smooth animated transition to new positions */
.node.organizing {
  transition: transform 0.5s cubic-bezier(0.65, 0, 0.35, 1);
}

.card {
  position: relative;
  width: 100%;
  transform-style: preserve-3d;
  /* Snappier ease-in-out-quart bezier for weighty card flip.
     IMPORTANT: never apply `filter` to .card — it flattens the 3D context
     and breaks backface-visibility on .card-face children, causing the front
     content to be visible (mirrored) during the rotation. */
  transition: transform 0.65s cubic-bezier(0.65, 0, 0.35, 1);
}
.card.flipped { transform: rotateY(180deg); }
/* While a flip is in progress, bump z-index so the rotating card sits
   above its neighbors. .flipping is added in JS for the duration. */
.card.flipping { z-index: 30; }

/* When card lands on the back face, settings rows cascade in one by one.
   Adds a small breath of life to the flip — settings appear like they're
   composing on a freshly-turned page. */
.card.flipped .settings .setting-row {
  animation: setting-cascade 0.4s cubic-bezier(0.4, 0.1, 0.2, 1) backwards;
}
.card.flipped .settings .setting-row:nth-child(1) { animation-delay: 0.32s; }
.card.flipped .settings .setting-row:nth-child(2) { animation-delay: 0.37s; }
.card.flipped .settings .setting-row:nth-child(3) { animation-delay: 0.42s; }
.card.flipped .settings .setting-row:nth-child(4) { animation-delay: 0.47s; }
.card.flipped .settings .setting-row:nth-child(5) { animation-delay: 0.52s; }
.card.flipped .settings .setting-row:nth-child(6) { animation-delay: 0.57s; }
.card.flipped .settings .generate-btn {
  animation: setting-cascade 0.4s cubic-bezier(0.4, 0.1, 0.2, 1) backwards;
  animation-delay: 0.6s;
}
@keyframes setting-cascade {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

.card.flipped .gallery-section {
  animation: gallery-fade-in 0.4s cubic-bezier(0.4, 0.1, 0.2, 1) backwards;
  animation-delay: 0.5s;
}
@keyframes gallery-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.card-face {
  position: relative;
  width: 100%;
  background: #ffffff;
  border: 1px solid #e6e6e6;
  border-radius: 12px;
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.04),
    0 4px 14px rgba(0, 0, 0, 0.05);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  /* overflow:visible so ports can extend outside the card edges as full circles.
     Inner elements (title-row, footer, gallery-section, last settings) get matching
     border-radius so the rounded card outline is preserved without clipping ports. */
  overflow: visible;
  transition: box-shadow 0.18s;
}
.card-front:hover {
  /* Subtle Macy's-red brand hint on hover — almost imperceptible */
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.04),
    0 4px 14px rgba(0, 0, 0, 0.06),
    0 0 0 1px rgba(226, 26, 44, 0.08);
}
.card-back {
  position: absolute;
  top: 0;
  left: 0;
  /* v0.47 (Billy 2026-05-12): match the front card's width exactly so the
     back footprint never extends past the front's silhouette. width:100% on
     a position:absolute element resolves against the offset parent (.card),
     which itself is 100% of the 280px-wide .node — so the back stays pinned
     at 280px regardless of content. */
  width: 100%;
  transform: rotateY(180deg);
  display: flex;
  flex-direction: column;
  /* v0.47 (Billy 2026-05-12): grow no taller than 2× the front card's actual
     rendered height. --front-card-height is set in JS on the .node element
     when the user flips; falls back to 700px for the initial paint (or any
     edge case where measurement fails). overflow-y:auto means the user
     scrolls the back content rather than having Gallery pushed off-screen.
     The inner gallery-section still has its own scroll for very long lists. */
  max-height: calc(var(--front-card-height, 700px) * 2);
  overflow-y: auto;
  overflow-x: hidden;
}
.card-back .title-row { flex-shrink: 0; }
.card-back .settings  { flex-shrink: 0; }
/* v0.47 (Billy 2026-05-12): nested scroll removed. The outer .card-back now
   scrolls the whole back, which is what the user wants — short content shows
   the Gallery without any scroll, long content scrolls the whole back so the
   Gallery is reachable. Inner overflow on .gallery-section was creating a
   nested scrollbar competing with the outer one. */
.card-back .gallery-section {
  flex-shrink: 0;
}
.card-back .card-footer { flex-shrink: 0; }

/* v0.69: drag-to-resize grip on the back face. Sticky-bottom so it stays
   reachable even when the back content scrolls. Dragging it sets an inline
   max-height on .card-back (via n.backHeight in JS), overriding the 2× cap. */
.card-back-resize {
  position: sticky;
  bottom: 0;
  left: 0;
  right: 0;
  height: 13px;
  flex-shrink: 0;
  cursor: ns-resize;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(180deg, rgba(255,255,255,0) 0%, rgba(245,245,245,0.96) 55%);
  border-bottom-left-radius: 12px;
  border-bottom-right-radius: 12px;
}
.card-back-resize::after {
  content: '';
  width: 28px;
  height: 3px;
  border-radius: 2px;
  background: rgba(0, 0, 0, 0.16);
  transition: background 0.15s;
}
.card-back-resize:hover::after { background: rgba(226, 26, 44, 0.45); }

/* ----- Title row (front + back) ---------------------------------------- */
.title-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px 9px 12px;
  background: #fafafa;
  border-bottom: 1px solid #ededed;
  font-size: 12.5px;
  font-weight: 500;
  color: #1a1a1a;
  cursor: grab;
  /* Round top corners so the card-face's rounded outline survives without overflow:hidden */
  border-top-left-radius: 11px;
  border-top-right-radius: 11px;
}
.node.dragging .title-row { cursor: grabbing; }

.title-icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: #7a7a7a;
}
.title-text {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* v0.43h: editable node title — click to rename. Subtle hover hint; full
   focus state when actively editing. */
.title-text.editable {
  cursor: text;
  border-radius: 3px;
  padding: 1px 4px;
  margin: -1px -4px;
  outline: none;
  transition: background 0.12s, box-shadow 0.12s;
}
.title-text.editable:hover { background: rgba(0,0,0,0.04); }
.title-text.editable:focus {
  background: #fff;
  box-shadow: inset 0 0 0 1px #5a8db8;
  text-overflow: clip;
  overflow: visible;
}
.title-meta {
  font-size: 10.5px;
  color: #9a9a9a;
  font-weight: 400;
}

/* ----- Thumbnail / body ------------------------------------------------- */
.thumb {
  position: relative;
  width: 100%;
  background: #f0f0f0;
  overflow: hidden;
}
.thumb-16-9  { aspect-ratio: 16 / 9; }
.thumb-2-3   { aspect-ratio: 2 / 3; }
.thumb-1-1   { aspect-ratio: 1 / 1; }
.thumb-4-5   { aspect-ratio: 4 / 5; }

.thumb-fill {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(255, 255, 255, 0.92);
  font-size: 13px;
  letter-spacing: 0.02em;
}

/* placeholder gradients for "rendered" thumbs */
.thumb-grad-1 { background: linear-gradient(135deg, #2c3e50 0%, #4a6f8c 50%, #c08a5e 100%); }
.thumb-grad-2 { background: linear-gradient(160deg, #1a1a2e 0%, #533a7b 60%, #d97757 100%); }
.thumb-grad-3 { background: linear-gradient(140deg, #f4d4a8 0%, #d4a574 40%, #6b4226 100%); }
.thumb-grad-4 { background: linear-gradient(135deg, #2d4a3e 0%, #6b8e7f 50%, #d4c5a3 100%); }

/* "generating" — shimmer */
.thumb-generating {
  background:
    linear-gradient(110deg, #ededed 30%, #f8f8f8 50%, #ededed 70%);
  background-size: 200% 100%;
  animation: shimmer 1.6s linear infinite;
}
.thumb-generating .thumb-fill {
  color: #707070;
  font-size: 12px;
}
@keyframes shimmer {
  from { background-position: 100% 0; }
  to   { background-position: -100% 0; }
}

/* v1.0.0 (Billy / Luma-style estimated progress bar) — shown in the generating
   placeholder over the shimmer. The fill is time-estimate driven (Veo gives no
   real %), eases to ~95%, holds until the result lands. */
.gen-progress {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 0 16px;
}
.gen-progress-track {
  width: 78%;
  max-width: 200px;
  height: 6px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.10);
  overflow: hidden;
}
.gen-progress-fill {
  height: 100%;
  width: 0%;
  border-radius: 999px;
  background: linear-gradient(90deg, #7c5cff, #5b8cff);
  transition: width 0.9s ease-out;
}
.gen-progress-label {
  font-size: 11px;
  color: #707070;
  letter-spacing: 0.2px;
}

/* "empty" — subtle pattern + hint */
.thumb-empty {
  background-color: #f0f0f0;
  background-image: radial-gradient(circle at 1px 1px, #d8d8d8 1px, transparent 0);
  background-size: 12px 12px;
}
.thumb-empty .thumb-fill {
  flex-direction: column;
  gap: 6px;
  color: #9a9a9a;
  font-size: 11.5px;
  letter-spacing: 0.04em;
}
.thumb-empty .thumb-fill svg {
  width: 22px;
  height: 22px;
  opacity: 0.55;
}

/* v1.5.2 IMG-PERSIST (Billy): a gen left in `error` must surface a clear retry
   affordance instead of a silent blank gradient. Muted red wash + warn glyph +
   message + a Retry button (data-action="generate" → re-fires the node). */
.thumb-error {
  background-color: #fcefee;
  background-image: radial-gradient(circle at 1px 1px, #f3d6d4 1px, transparent 0);
  background-size: 12px 12px;
}
.thumb-error-fill {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 10px;
  text-align: center;
}
.thumb-error-icon { color: #c0392b; line-height: 0; }
.thumb-error-icon svg { width: 22px; height: 22px; }
.thumb-error-msg {
  color: #8a3a33;
  font-size: 11px;
  line-height: 1.35;
  letter-spacing: 0.02em;
  max-width: 92%;
  overflow-wrap: anywhere;
}
.thumb-retry-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 11px;
  border: 1px solid #e0b4af;
  border-radius: 7px;
  background: #fff;
  color: #c0392b;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, box-shadow 0.15s;
}
.thumb-retry-btn svg { width: 12px; height: 12px; }
.thumb-retry-btn:hover {
  background: #c0392b;
  border-color: #c0392b;
  color: #fff;
  box-shadow: 0 1px 4px rgba(192, 57, 43, 0.25);
}
/* gallery cell for a failed take */
.cell-thumb.cell-error {
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fcefee;
}
.cell-thumb.cell-error .cell-error-icon { color: #c0392b; line-height: 0; }
.cell-thumb.cell-error .cell-error-icon svg { width: 14px; height: 14px; }

/* prompt-node body — text instead of thumb */
.prompt-body {
  padding: 14px 14px 16px 14px;
  font-size: 12.5px;
  line-height: 1.5;
  color: #3a3a3a;
  background: #fcfcfc;
  border-top: 1px solid #ededed;
  border-bottom: 1px solid #ededed;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 11.5px;
  max-height: 180px;
  overflow: hidden;
  position: relative;
}
.prompt-body::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 30px;
  background: linear-gradient(to bottom, transparent, #fcfcfc);
  pointer-events: none;
}

/* play overlay on rendered video */
.play-btn {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(6px);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.2s;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
}
.thumb:hover .play-btn { opacity: 1; }
.play-btn::before {
  content: "";
  display: block;
  margin-left: 4px;
  border-style: solid;
  border-width: 9px 0 9px 14px;
  border-color: transparent transparent transparent #1a1a1a;
}

/* v0.92 (POLARIS #386 item 1): explicit fullscreen control, separate from the
   inline play. Sits top-right of the thumb so it never overlaps the centered
   play button. */
.expand-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 28px;
  height: 28px;
  border: none;
  border-radius: 7px;
  background: rgba(20, 20, 20, 0.55);
  backdrop-filter: blur(4px);
  color: #fff;
  font-size: 14px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.2s, background 0.2s;
  z-index: 3;
}
.thumb:hover .expand-btn { opacity: 1; }
.expand-btn:hover { background: rgba(20, 20, 20, 0.8); }

/* v1.0.1 (Billy A): the video fills the card edge-to-edge — base .thumb-img is
   already object-fit:cover, so there's no letterbox black bar. (The old
   .playing-inline contain+black rule that caused the top/bottom bars is gone.) */

/* v1.0.1 (Billy B): CUSTOM inline video controls overlaid on the clip, fading in
   on hover — replaces Chrome's opaque native bar. */
.vid-ctrls {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px 9px;
  background: linear-gradient(to top, rgba(0,0,0,0.55), rgba(0,0,0,0));
  opacity: 0;
  transition: opacity 0.18s ease;
  z-index: 4;
}
.thumb:hover .vid-ctrls,
.thumb.vid-playing .vid-ctrls { opacity: 1; }
.vid-toggle {
  flex: 0 0 auto;
  width: 20px; height: 20px;
  border: none; background: transparent; padding: 0;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.vid-toggle::before {
  content: "▶";
  color: #fff;
  font-size: 12px;
  line-height: 1;
  text-shadow: 0 1px 2px rgba(0,0,0,0.5);
}
.thumb.vid-playing .vid-toggle::before { content: "❚❚"; font-size: 10px; letter-spacing: 1px; }
.vid-scrub {
  flex: 1 1 auto;
  height: 5px;
  border-radius: 999px;
  background: rgba(255,255,255,0.32);
  cursor: pointer;
  overflow: hidden;
  touch-action: none;
}
.vid-scrub-fill {
  height: 100%;
  width: 0%;
  background: #fff;
  border-radius: 999px;
}
.vid-time {
  flex: 0 0 auto;
  color: #fff;
  font-size: 10px;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 2px rgba(0,0,0,0.5);
}
/* Center play-btn hides once playback starts (custom toggle takes over). */
.thumb.vid-playing .play-btn { display: none !important; }

/* ----- Footer (specs + actions) ---------------------------------------- */
.card-footer {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: #fafafa;
  border-top: 1px solid #ededed;
  /* Round bottom corners to preserve the card outline (front face has footer last) */
  border-bottom-left-radius: 11px;
  border-bottom-right-radius: 11px;
}
.specs {
  flex: 1;
  font-size: 11px;
  color: #707070;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}
.footer-btn {
  width: 26px;
  height: 26px;
  border: 0;
  background: transparent;
  border-radius: 6px;
  cursor: pointer;
  color: #5a5a5a;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.footer-btn:hover { background: #f0f0f0; color: #1a1a1a; }
.footer-btn svg { width: 14px; height: 14px; }

/* ----- Hover actions (top-right of card) ------------------------------- */
.hover-actions {
  position: absolute;
  top: 8px;
  right: 8px;
  display: flex;
  gap: 4px;
  opacity: 0;
  transform: translateY(-2px);
  transition: opacity 0.15s, transform 0.15s;
  z-index: 5;
}
.card-front:hover .hover-actions {
  opacity: 1;
  transform: translateY(0);
}
.hover-btn {
  width: 24px;
  height: 24px;
  border: 0;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(6px);
  border-radius: 6px;
  cursor: pointer;
  color: #3a3a3a;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
}
.hover-btn:hover { background: #ffffff; color: #1a1a1a; }
.hover-btn.delete:hover { color: #c44525; }
.hover-btn svg { width: 12px; height: 12px; }

/* ----- Ports ----------------------------------------------------------- */
.port {
  position: absolute;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #ffffff;
  border: 2px solid #c0c0c0;
  cursor: crosshair;
  z-index: 6;
  transition: transform 0.12s, border-color 0.12s, background 0.12s;
}
.port:hover {
  transform: scale(1.25);
  border-color: #1a1a1a;
}
.port.port-prompt    { border-color: #8b6fb8; }
.port.port-prompt:hover, .port.port-prompt.active { background: #8b6fb8; }
.port.port-character { border-color: #5a8d6d; }
.port.port-character:hover, .port.port-character.active { background: #5a8d6d; }
.port.port-asset     { border-color: #c97f4a; }
.port.port-asset:hover, .port.port-asset.active { background: #c97f4a; }
.port.port-document  { border-color: #a89868; }
.port.port-document:hover, .port.port-document.active { background: #a89868; }
.port.port-out       { right: -8px; top: 50%; transform: translateY(-50%); }
.port.port-out:hover { transform: translateY(-50%) scale(1.25); }
.port.port-in        { left: -8px; }
.port.port-in.in-1   { top: 38%; }
.port.port-in.in-2   { top: 62%; }
.port.port-in.in-only { top: 50%; transform: translateY(-50%); }
.port.port-in.in-only:hover { transform: translateY(-50%) scale(1.25); }
/* v0.43c: N≥3 inputs — JS sets inline top:%, we center vertically via transform */
.port.port-in[class*="in-"][class*="-of-"]        { transform: translateY(-50%); }
.port.port-in[class*="in-"][class*="-of-"]:hover  { transform: translateY(-50%) scale(1.25); }

/* port label tooltip on hover */
.port-label {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%) translateY(-4px);
  padding: 3px 6px;
  background: #1a1a1a;
  color: #fff;
  font-size: 10px;
  border-radius: 4px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s;
}
.port:hover .port-label { opacity: 1; }

/* LIT output port — node has at least one generation, ready to push downstream */
.port.lit                  { background: #5a5a5a; border-color: #1a1a1a; }
.port.lit.port-prompt      { background: #8b6fb8; border-color: #6b4e9a; box-shadow: 0 0 0 4px rgba(139,111,184,0.18); }
.port.lit.port-character   { background: #5a8d6d; border-color: #3f6f50; box-shadow: 0 0 0 4px rgba(90,141,109,0.18); }
.port.lit.port-asset,
.port.lit.port-video       { background: #c97f4a; border-color: #a86230; box-shadow: 0 0 0 4px rgba(201,127,74,0.20); }
.port.lit.port-image       { background: #4a8db8; border-color: #2f6f99; box-shadow: 0 0 0 4px rgba(74,141,184,0.20); }
.port.lit.port-document    { background: #a89868; border-color: #87783f; box-shadow: 0 0 0 4px rgba(168,152,104,0.18); }
.port.lit.port-out         {
  animation: portPulse 2.4s ease-in-out infinite;
}
@keyframes portPulse {
  0%, 100% { filter: brightness(1); }
  50%      { filter: brightness(1.18); }
}

/* ============================================================================
   Front-side gallery cycle arrows (hover on thumb)
   ============================================================================ */
.cycle-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 30px;
  height: 50px;
  background: rgba(0, 0, 0, 0.42);
  backdrop-filter: blur(6px);
  border: 0;
  border-radius: 6px;
  color: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.18s, background 0.12s;
  z-index: 4;
}
.thumb:hover .cycle-arrow,
.prompt-body:hover .cycle-arrow { opacity: 1; }
.cycle-arrow:hover { background: rgba(0, 0, 0, 0.62); }
.cycle-arrow:disabled { opacity: 0 !important; cursor: default; }
.cycle-arrow.left  { left: 8px; }
.cycle-arrow.right { right: 8px; }
.cycle-arrow svg { width: 16px; height: 16px; }

/* gen indicator pill — bottom-center of thumb, shows "2 / 3" */
.gen-indicator {
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
  padding: 3px 8px;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(6px);
  color: #fff;
  font-size: 10.5px;
  font-variant-numeric: tabular-nums;
  border-radius: 999px;
  letter-spacing: 0.04em;
  opacity: 0;
  transition: opacity 0.18s;
  pointer-events: none;
  z-index: 4;
}
.thumb:hover .gen-indicator { opacity: 1; }

/* ============================================================================
   Back-side gallery
   ============================================================================ */
.gallery-section {
  border-top: 1px solid #ededed;
  padding: 12px 14px 14px 14px;
  background: #fbfbfa;
  /* Bottom radius is now owned by the back's card-footer (always present),
     so gallery-section doesn't need its own. */
}
.gallery-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}
.gallery-title {
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #9a9a9a;
  font-weight: 500;
}
.gallery-count {
  font-size: 10.5px;
  color: #9a9a9a;
  font-variant-numeric: tabular-nums;
}
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
}
.gallery-cell {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: 6px;
  overflow: hidden;
  cursor: pointer;
  border: 2px solid transparent;
  transition: border-color 0.12s, transform 0.08s;
}
.gallery-cell:hover { transform: translateY(-1px); }
.gallery-cell.selected {
  border-color: #1a1a1a;
  /* subtle red glint marking the active selection */
  box-shadow: 0 0 0 1px rgba(226, 26, 44, 0.3);
}
.gallery-cell .cell-thumb {
  position: absolute;
  inset: 0;
}
.gallery-cell.generating .cell-thumb {
  background: linear-gradient(110deg, #ededed 30%, #f8f8f8 50%, #ededed 70%);
  background-size: 200% 100%;
  animation: shimmer 1.6s linear infinite;
}
.gallery-cell .cell-num {
  position: absolute;
  bottom: 2px;
  right: 4px;
  font-size: 9px;
  color: rgba(255, 255, 255, 0.92);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
  letter-spacing: 0.04em;
}
.gallery-cell.generating .cell-num {
  color: #707070;
  text-shadow: none;
}
.gallery-cell .pop-out {
  position: absolute;
  top: 3px;
  right: 3px;
  width: 20px;
  height: 20px;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(6px);
  border: 0;
  border-radius: 4px;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s;
}
.gallery-cell:hover .pop-out { opacity: 1; }
.gallery-cell .pop-out:hover { background: rgba(0, 0, 0, 0.78); }
.gallery-cell .pop-out svg { width: 11px; height: 11px; }

.gallery-empty {
  padding: 16px 10px;
  text-align: center;
  color: #9a9a9a;
  font-size: 11.5px;
  letter-spacing: 0.02em;
  background: #f0f0f0;
  border-radius: 6px;
  border: 1px dashed #d8d8d8;
}

/* popped-asset badge in title row */
.title-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 6px;
  font-size: 9.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #6b4e9a;
  background: #f4eef9;
  border: 1px solid #e7dcf2;
  border-radius: 4px;
  margin-left: 4px;
  flex-shrink: 0;
}

/* ============================================================================
   CARD BACK — settings panel
   ============================================================================ */
.card-back .title-row {
  cursor: default;
  /* v0.86 (Billy 2026-05-29): pin the back title row to the top of the
     scrolling .card-back so its flip-back button is ALWAYS reachable without
     scrolling down to the footer — the whole point of the top button on tall
     product/character/place gallery cards. The base .title-row already sets an
     opaque #fafafa background, so scrolled body content passes cleanly beneath. */
  position: sticky;
  top: 0;
  z-index: 3;
}
/* v0.86: top flip-back button — right-aligned in the back title row (margin
   pushes it past the title text), mirroring the footer flip-back. Same
   .footer-btn styling + flipBack icon so it reads as the known flip control. */
.card-back .title-flip-back {
  margin-left: auto;
  flex-shrink: 0;
}
/* .back-arrow removed in v0.8 — flip-back affordance moved to back-side footer
   in the same position as the front's gear (cleaner toggle pattern, no more
   confusion with delete). v0.86 re-adds a flip-back at the TOP too, but
   right-aligned + identical to the footer control, so the delete confusion
   that killed the original top-left back-arrow does not apply. */

.settings {
  padding: 14px 14px 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.setting-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.setting-label {
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #9a9a9a;
  font-weight: 500;
}
.setting-input {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  background: #fafafa;
  border: 1px solid #e6e6e6;
  border-radius: 7px;
  font-size: 12.5px;
  color: #1a1a1a;
  cursor: pointer;
  transition: border-color 0.12s, background 0.12s;
}
.setting-input:hover {
  border-color: #c0c0c0;
  background: #ffffff;
}
.setting-input.connected {
  background: #ffffff;
  border-color: #d8d8d8;
}
.setting-input .conn-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #c0c0c0;
  flex-shrink: 0;
}
.setting-input.connected.prompt    .conn-dot { background: #8b6fb8; }
.setting-input.connected.character .conn-dot { background: #5a8d6d; }
.setting-input .label-text { flex: 1; }
.setting-input .arrow { color: #9a9a9a; font-size: 12px; }

.setting-input.dropdown {
  background: #ffffff;
  position: relative;
}
.setting-input.dropdown.open {
  border-color: #1a1a1a;
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}
.setting-input.dropdown.open .arrow {
  transform: rotate(180deg);
  color: #1a1a1a;
}
.setting-input.dropdown .arrow {
  transition: transform 0.18s, color 0.12s;
}

.dropdown-options {
  display: none;
  position: absolute;
  top: 100%;
  left: -1px;
  right: -1px;
  background: #ffffff;
  border: 1px solid #1a1a1a;
  border-top: 0;
  border-bottom-left-radius: 7px;
  border-bottom-right-radius: 7px;
  z-index: 20;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08);
  max-height: 200px;
  overflow-y: auto;
  cursor: default;
}
.setting-input.dropdown.open .dropdown-options {
  display: block;
  /* Subtle slide-in */
  animation: dropdown-slide 0.16s cubic-bezier(0.4, 0.1, 0.2, 1);
}
@keyframes dropdown-slide {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

.dropdown-option {
  padding: 8px 10px;
  font-size: 12.5px;
  color: #1a1a1a;
  cursor: pointer;
  transition: background 0.08s;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.dropdown-option:hover { background: #f5f5f5; }
.dropdown-option.selected {
  font-weight: 500;
  color: #1a1a1a;
  background: #fafafa;
}
.dropdown-option.selected::after {
  content: "•";
  color: #e21a2c;
  font-size: 14px;
  margin-left: 8px;
}

.generate-btn {
  margin-top: 4px;
  width: 100%;
  padding: 10px 14px;
  background: #1a1a1a;
  color: #ffffff;
  border: 0;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background 0.12s, transform 0.06s, box-shadow 0.18s;
}
.generate-btn:hover {
  background: #2d2d2d;
  /* faint Macy's-red shadow on hover */
  box-shadow: 0 2px 8px rgba(226, 26, 44, 0.15);
}
.generate-btn:active { transform: scale(0.98); }

/* ============================================================================
   NODE-TYPE color accents
   ============================================================================ */
.node[data-type="prompt"] .card-face {
  border-color: #d6cce4;
}
.node[data-type="prompt"] .title-row {
  background: #f4eef9;
  border-bottom-color: #e7dcf2;
}
.node[data-type="prompt"] .title-icon { color: #8b6fb8; }

.node[data-type="character"] .card-face {
  border-color: #cee0d4;
}
.node[data-type="character"] .title-row {
  background: #eef6f1;
  border-bottom-color: #dfeae3;
}
.node[data-type="character"] .title-icon { color: #5a8d6d; }

/* ============================================================================
   v0.3 — connect-by-drag, cable delete, script node type
   ============================================================================ */

/* Connect-by-drag — visual feedback while wiring */
body.connecting #viewport { cursor: crosshair; }
body.connecting .port-in {
  opacity: 0.35;
  transition: opacity 0.12s, transform 0.12s, box-shadow 0.12s;
}
body.connecting .port-in.connect-valid {
  opacity: 1;
  box-shadow: 0 0 0 5px rgba(42, 42, 40, 0.18);
}
body.connecting .port-in.connect-valid.in-only {
  transform: translateY(-50%) scale(1.35);
}
body.connecting .port-in.connect-valid:not(.in-only) {
  transform: scale(1.35);
}
body.connecting .port-out:not([data-active-source="1"]) {
  opacity: 0.4;
}

.cable-temp { pointer-events: none; }

/* While connecting, cables become inert — mouseup must hit ports cleanly */
body.connecting .cable-group,
body.connecting .cable-hit,
body.connecting .cable-delete-group { pointer-events: none !important; }

/* Cable delete affordance — small × at midpoint, on hover */
.cable-group { pointer-events: none; }
.cable-hit {
  pointer-events: stroke;
  cursor: pointer;
}
.cable-delete-group {
  cursor: pointer;
  pointer-events: auto;
  opacity: 0;
  transition: opacity 0.14s;
}
.cable-group:hover .cable-delete-group { opacity: 1; }
.cable-delete-bg {
  fill: #ffffff;
  stroke: #c44525;
  stroke-width: 1.5;
}
.cable-delete-x {
  stroke: #c44525;
  stroke-width: 2;
  stroke-linecap: round;
}
.cable-delete-group:hover .cable-delete-bg { fill: #c44525; }
.cable-delete-group:hover .cable-delete-x  { stroke: #ffffff; }

/* ----- Script node type ----- */
.node[data-type="script"] .card-face {
  border-color: #e0d2b8;
}
.node[data-type="script"] .title-row {
  background: #f9f2e6;
  border-bottom-color: #ecdfc6;
}
.node[data-type="script"] .title-icon { color: #b8853d; }

.script-body {
  background: #fdfaf2;
  border-top: 1px solid #f0eadb;
  border-bottom: 1px solid #f0eadb;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 11px;
  line-height: 1.55;
  color: #4a4030;
  max-height: 220px;
  overflow: hidden;
  position: relative;
}
.script-scene {
  padding: 8px 14px 6px 14px;
  border-top: 1px solid #f0eadb;
}
.script-scene:first-child { border-top: 0; }
.script-scene-head {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 9.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #b8853d;
  font-weight: 600;
  font-family: -apple-system, BlinkMacSystemFont, sans-serif;
  margin-bottom: 3px;
}
.script-scene-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 14px;
  padding: 0 4px;
  background: #f1e2c2;
  color: #7d5a26;
  border-radius: 3px;
  font-size: 9px;
  font-family: -apple-system, BlinkMacSystemFont, sans-serif;
}
.script-body::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 30px;
  background: linear-gradient(to bottom, transparent, #fdfaf2);
  pointer-events: none;
}

/* Script port color (same family as prompt but warmer) */
.port.port-script              { border-color: #b8853d; }
.port.port-script:hover,
.port.port-script.active       { background: #b8853d; }
.port.lit.port-script          {
  background: #b8853d;
  border-color: #8c6020;
  box-shadow: 0 0 0 4px rgba(184, 133, 61, 0.20);
}

/* ============================================================================
   v0.9 — FAB, context menu, library drawer, debug panel
   ============================================================================ */

/* ============================================================================
   Library — top-left morphing FAB (per Billy 2026-05-09)
   Collapsed: 40×40 button. Expanded: button + tabs + content drawer.
   The whole thing lives in one container with rounded corners so the
   button visually expands INTO the library.
   ============================================================================ */
.library-container {
  position: fixed;
  top: 60px;
  left: 12px;
  background: #ffffff;
  border: 1px solid #e6e6e6;
  border-radius: 10px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.06);
  z-index: 80;
  overflow: hidden;
  transition:
    width 0.28s cubic-bezier(0.4, 0.1, 0.2, 1),
    height 0.28s cubic-bezier(0.4, 0.1, 0.2, 1),
    box-shadow 0.28s cubic-bezier(0.4, 0.1, 0.2, 1);
}
.library-container.collapsed {
  width: 40px;
  height: 40px;
}
.library-container.expanded {
  /* v1.7.0 (Billy: "library tab menu is too wide for the library panel"):
     280 → 320px so the 5-tab row (Nodes / Generated / Uploads / Templates /
     Team assets) sits on ONE line without wrap/clip. The 2-col asset grid and
     the palette/workflow lists all still fit comfortably at this width.
     332px gives ~65px per tab slot — clears the longest label ("Team assets",
     ~64px at 10.5px) with margin so no tab clips. */
  width: 332px;
  height: calc(100vh - 100px);
  max-height: 640px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}
.library-trigger {
  width: 40px;
  height: 40px;
  background: transparent;
  border: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #1a1a1a;
  flex-shrink: 0;
  transition: background 0.12s, color 0.12s;
}
.library-trigger:hover { background: #f5f5f5; }
.library-container.expanded .library-trigger {
  background: #1a1a1a;
  color: #ffffff;
}
.library-container.expanded .library-trigger:hover { background: #2d2d2d; }
.library-trigger svg { width: 18px; height: 18px; }

.library-content {
  /* Always rendered but only visible when expanded; opacity transition for nice fade-in */
  display: flex;
  flex-direction: column;
  height: calc(100% - 40px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s 0.08s;
}
.library-container.expanded .library-content {
  opacity: 1;
  pointer-events: auto;
}

/* Right-click context menu */
.context-menu {
  position: fixed;
  z-index: 200;
  min-width: 180px;
  background: #ffffff;
  border: 1px solid #e6e6e6;
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  padding: 6px;
  display: none;
  flex-direction: column;
  gap: 1px;
}
.context-menu.visible { display: flex; }
.context-menu-header {
  padding: 6px 10px 8px 10px;
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #9a9a9a;
  font-weight: 500;
  border-bottom: 1px solid #ededed;
  margin-bottom: 4px;
}
/* v0.62: divider between pipeline nodes and annotation nodes in add menu */
.context-menu-divider {
  height: 1px;
  background: #ededed;
  margin: 4px 0;
}
.context-menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  background: transparent;
  border: 0;
  border-radius: 6px;
  font-size: 12.5px;
  color: #1a1a1a;
  cursor: pointer;
  text-align: left;
  width: 100%;
}
.context-menu-item:hover { background: #f0f0f0; }
.context-menu-item .cm-icon {
  width: 16px;
  height: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #5a5a5a;
}
.context-menu-item .cm-icon svg { width: 14px; height: 14px; }

/* Color the icons by node-type identity */
.context-menu-item[data-add-type="prompt"]    .cm-icon { color: #8b6fb8; }
.context-menu-item[data-add-type="script"]    .cm-icon { color: #b8853d; }
.context-menu-item[data-add-type="character"] .cm-icon { color: #5a8d6d; }
.context-menu-item[data-add-type="video"]     .cm-icon { color: #c97f4a; }
.context-menu-item[data-add-type="image"]     .cm-icon { color: #4a8db8; }

/* (legacy .library/.library-head rules unused — replaced by .library-container) */
.library-close {
  width: 22px;
  height: 22px;
  background: transparent;
  border: 0;
  color: #5a5a5a;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  border-radius: 4px;
}
.library-close:hover { background: #f0f0f0; color: #1a1a1a; }

.library-tabs {
  display: flex;
  gap: 0;
  padding: 4px 5px 0 5px;
  border-bottom: 1px solid #ededed;
}
.library-tab {
  flex: 1;
  /* v1.7.0: tighter horizontal padding + letter-spacing so all 5 tabs fit one
     row at the 320px panel width (longest label "Team assets" ≈ 64px slot). */
  padding: 6px 2px 8px 2px;
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  font-size: 10.5px;
  color: #5a5a5a;
  cursor: pointer;
  letter-spacing: 0;
  white-space: nowrap;
  text-align: center;
}
.library-tab:hover { color: #1a1a1a; }
.library-tab.active {
  color: #1a1a1a;
  border-bottom-color: #1a1a1a;
  font-weight: 500;
}

.library-body {
  padding: 12px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* v1.1.0 Asset Library — Generated / Uploads tabs (read-only grid) */
.lib-assets-msg { padding: 18px 8px; font-size: 12px; color: #9a9a9a; text-align: center; }
.lib-assets-head {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 10px; color: #9a9a9a; letter-spacing: 0.06em; text-transform: uppercase;
  font-weight: 500; padding: 0 2px 2px;
}
.lib-assets-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 7px;
}
.lib-asset {
  position: relative;
  aspect-ratio: 1;
  border-radius: 8px;
  overflow: hidden;
  cursor: pointer;
  background: #f0f0f0;
  border: 1px solid #ececec;
  transition: transform 0.12s, box-shadow 0.12s;
}
.lib-asset:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(0,0,0,0.14); }
.lib-asset-thumb { width: 100%; height: 100%; object-fit: cover; display: block; }
.lib-asset-badge {
  position: absolute; bottom: 5px; right: 5px;
  width: 18px; height: 18px; border-radius: 5px;
  background: rgba(20,20,20,0.62); color: #fff;
  font-size: 9px; display: flex; align-items: center; justify-content: center;
}
.lib-reindex, .lib-reindex-wrap > .lib-reindex {
  border: 1px solid #e0e0e0; background: #fafafa; color: #555;
  font-size: 10.5px; padding: 4px 9px; border-radius: 6px; cursor: pointer;
}
.lib-reindex:hover { background: #f0f0f0; }
.lib-reindex-wrap { display: flex; justify-content: center; margin-top: 10px; }
.library-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: #ffffff;
  border: 1px solid #e6e6e6;
  border-radius: 8px;
  cursor: pointer;
  transition: border-color 0.12s, background 0.12s;
}
.library-item:hover {
  border-color: #1a1a1a;
  background: #fafafa;
}
.library-item-icon {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  background: #f5f5f5;
}
.library-item-icon svg { width: 16px; height: 16px; }
.library-item-meta { flex: 1; min-width: 0; }
.library-item-title {
  font-size: 12.5px;
  color: #1a1a1a;
  font-weight: 500;
  letter-spacing: 0.01em;
}
.library-item-sub {
  font-size: 10.5px;
  color: #7a7a7a;
  margin-top: 2px;
}
/* Type-color hint on the icon background */
.library-item[data-add-type="prompt"]    .library-item-icon { background: #f4eef9; color: #8b6fb8; }
.library-item[data-add-type="script"]    .library-item-icon { background: #f9f2e6; color: #b8853d; }
.library-item[data-add-type="character"] .library-item-icon { background: #eef6f1; color: #5a8d6d; }
.library-item[data-add-type="video"]     .library-item-icon { background: #faeee2; color: #c97f4a; }
.library-item[data-add-type="image"]     .library-item-icon { background: #eaf2f8; color: #4a8db8; }
/* v1.7.0: new palette types — scene (amber, the doc/script family), product/
   object (slate), place (teal-green), sequence (warm, the video family). */
.library-item[data-add-type="prompt-script"] .library-item-icon { background: #f9f2e6; color: #b8853d; }
.library-item[data-add-type="product"]   .library-item-icon { background: #eef0f4; color: #5a6b8d; }
.library-item[data-add-type="place"]     .library-item-icon { background: #eaf4f1; color: #4a9d8d; }
.library-item[data-add-type="sequence"]  .library-item-icon { background: #faeee2; color: #c97f4a; }

/* Debug panel — corner overlay */
/* v0.26: full-height debug drawer (Billy: queue was covering it).
   When open, queue indicator + panel are hidden via body.debug-open. */
.debug-panel {
  position: fixed;
  top: 0;
  right: 0;
  width: 440px;
  height: 100vh;
  max-height: 100vh;
  background: rgba(20, 20, 20, 0.97);
  backdrop-filter: blur(10px);
  color: #ededed;
  border-left: 1px solid #2d2d2d;
  box-shadow: -8px 0 24px rgba(0, 0, 0, 0.25);
  z-index: 1500;
  display: none;
  flex-direction: column;
  overflow: hidden;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 11px;
}
.debug-panel.visible { display: flex; }
body.debug-open .queue-indicator,
body.debug-open .queue-panel,
body.debug-open .chat-container { display: none !important; }
.debug-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  padding: 10px 12px;
  border-bottom: 1px solid #2d2d2d;
  flex-shrink: 0;
}
.debug-head h3 {
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.06em;
  color: #ededed;
  text-transform: uppercase;
  font-family: -apple-system, sans-serif;
  flex-shrink: 0;
}
.debug-head-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 1;
  justify-content: flex-end;
}
.debug-filter {
  width: 100px;
  padding: 4px 8px;
  background: #1a1a1a;
  border: 1px solid #2d2d2d;
  border-radius: 4px;
  color: #ededed;
  font-family: inherit;
  font-size: 10.5px;
  outline: none;
}
.debug-filter:focus { border-color: #6a6a6a; }
.debug-action-btn {
  width: 24px; height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #2a2a2a;
  border: 0;
  border-radius: 4px;
  color: #c0c0c0;
  cursor: pointer;
  font-family: -apple-system, sans-serif;
  font-size: 12px;
  padding: 0;
}
.debug-action-btn:hover { background: #3a3a3a; color: #fff; }
.debug-action-btn.paused { background: #b8853d; color: #fff; }
.debug-head .library-close { color: #c0c0c0; flex-shrink: 0; }
.debug-head .library-close:hover { background: #2d2d2d; color: #ffffff; }
.debug-stats {
  padding: 6px 12px;
  border-bottom: 1px solid #2d2d2d;
  font-size: 10px;
  color: #7a7a7a;
  letter-spacing: 0.04em;
  flex-shrink: 0;
}
.debug-body {
  padding: 8px 0;
  overflow-y: auto;
  flex: 1;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 10.5px;
  line-height: 1.5;
}
.debug-row {
  padding: 3px 12px;
  display: grid;
  grid-template-columns: 70px 90px 1fr;
  gap: 8px;
  border-bottom: 1px solid #1a1a1a;
}
.debug-row:hover { background: #1f1f1f; }
.debug-row.lvl-error { background: #2a1414; color: #ff8a8a; }
.debug-row.lvl-error:hover { background: #3a1818; }
.debug-row.lvl-warn  { color: #ffc56a; }
.debug-row.lvl-info  { color: #ededed; }
.debug-row.lvl-debug { color: #8a8a8a; }
.debug-time { color: #6a6a6a; font-variant-numeric: tabular-nums; white-space: nowrap; }
.debug-channel {
  color: #b8853d;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.debug-row.lvl-error .debug-channel { color: #ff5a5a; }
.debug-row.lvl-warn  .debug-channel { color: #ffa040; }
.debug-msg {
  white-space: pre-wrap;
  word-break: break-word;
  color: inherit;
}
.debug-msg-data {
  color: #6a8aa0;
  font-size: 10px;
  margin-top: 2px;
}
/* Legacy debug-section / debug-key styles kept for back-compat */
.debug-key { color: #b8853d; }
.debug-val { color: #ededed; }
.debug-section { border-top: 1px solid #2d2d2d; padding-top: 8px; margin-top: 8px; padding-left: 12px; padding-right: 12px; }

/* The proto-badge moved down past the topbar, but keep the rest aligned.
   When library or debug is open, push the badge over a bit so it doesn't collide. */

/* ============================================================================
   Chat container (bottom-right) — agentic Stellar chat (placeholder for now)
   Same morphing pattern as Library: collapsed = trigger button, expanded =
   trigger + content drawer.
   ============================================================================ */
.chat-container {
  position: fixed;
  bottom: 16px;
  right: 16px;
  background: #ffffff;
  border: 1px solid #e6e6e6;
  border-radius: 10px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.06);
  z-index: 90;
  overflow: hidden;
  display: flex;
  flex-direction: column-reverse; /* button at bottom, content above */
  transition:
    width 0.28s cubic-bezier(0.4, 0.1, 0.2, 1),
    height 0.28s cubic-bezier(0.4, 0.1, 0.2, 1),
    box-shadow 0.28s cubic-bezier(0.4, 0.1, 0.2, 1);
}
.chat-container.collapsed {
  width: 48px;
  height: 48px;
}
.chat-container.expanded {
  width: 420px;
  /* v0.51: grow taller than before so prompts have room. Capped to viewport so
     long transcripts scroll inside .chat-body rather than push the panel off
     screen. min() lets us flex up to the calc cap.
     v0.86 (Billy 2026-05-29): was min(720px, 100vh - 80px) — its top reached
     ~64px from the viewport top and ran under the queue widget (fixed at
     top:60px). Shortened so the chat's top edge stays ~114px down (130px
     reserved minus the 16px bottom offset), clearing the queue pill with a
     clean gap. Cap also trimmed 720→660 so it sits a touch lower overall. */
  height: min(660px, calc(100vh - 130px));
  max-height: calc(100vh - 130px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14);
}
.chat-trigger {
  width: 48px;
  height: 48px;
  background: #1a1a1a;
  color: #ffffff;
  border: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.12s, box-shadow 0.18s;
}
.chat-trigger:hover {
  background: #2d2d2d;
  box-shadow: inset 0 0 0 4px rgba(226, 26, 44, 0.15);
}
.chat-container.expanded .chat-trigger { display: none; }
.chat-trigger svg { width: 20px; height: 20px; }

.chat-content {
  display: none;
  flex-direction: column;
  flex: 1;
  height: 100%;
}
.chat-container.expanded .chat-content { display: flex; }
.chat-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  border-bottom: 1px solid #ededed;
  background: #fafafa;
}
.chat-head-title {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  color: #1a1a1a;
  letter-spacing: 0.02em;
}
.chat-body {
  flex: 1;
  overflow-y: auto;
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-size: 12.5px;
  color: #1a1a1a;
  line-height: 1.5;
  /* v0.51: ensure all chat text is selectable — the canvas root sets
     user-select:none for drag/drop sanity, but chat needs copyability. */
  user-select: text;
  -webkit-user-select: text;
}
.chat-msg {
  border: 1px solid #ededed;
  background: #fafafa;
  border-radius: 8px;
  padding: 8px 10px;
  user-select: text;
  -webkit-user-select: text;
}
.chat-msg * { user-select: text; -webkit-user-select: text; }
.chat-msg-system {
  background: #f4eef9;
  border-color: #e7dcf2;
  color: #3a3a3a;
}
.chat-msg-user {
  background: #1a1a1a;
  color: #ffffff;
  border-color: #1a1a1a;
  align-self: flex-end;
  max-width: 85%;
}
.chat-msg-error {
  background: #fde8ea;
  border-color: #f3c8cd;
  color: #8a1a23;
}
.chat-msg-action {
  background: #fafaf6;
  border-color: #ededed;
}
/* v0.25: agent message styling — distinct from system, slightly warmer */
.chat-msg-agent {
  background: #fff7f1;
  border-color: #f4e3d2;
  color: #2a2a2a;
}
.chat-msg-agent .chat-msg-meta { color: #c97f4a; font-weight: 600; }
.chat-msg-agent-thinking {
  background: #fff7f1;
  border-color: #f4e3d2;
  padding: 10px 14px;
}
.chat-thinking {
  display: inline-flex;
  gap: 4px;
  padding: 4px 0;
}
.chat-thinking span {
  width: 6px; height: 6px;
  background: #c97f4a;
  border-radius: 50%;
  animation: chat-thinking-pulse 1.2s infinite;
  opacity: 0.4;
}
.chat-thinking span:nth-child(2) { animation-delay: 0.2s; }
.chat-thinking span:nth-child(3) { animation-delay: 0.4s; }
@keyframes chat-thinking-pulse {
  0%, 60%, 100% { opacity: 0.3; transform: scale(1); }
  30% { opacity: 1; transform: scale(1.3); }
}
/* v0.25: tool call indicators — small italic lines showing agent actions */
.chat-msg-tool {
  background: transparent;
  border: 0;
  border-left: 2px solid #d0d0d0;
  border-radius: 0;
  padding: 2px 8px;
  margin-left: 4px;
  font-size: 10.5px;
  color: #7a7a7a;
  font-style: italic;
}
.chat-tool-line.tool-err { color: #c4101e; font-style: normal; }
.chat-msg-meta {
  font-size: 9.5px;
  color: #9a9a9a;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 4px;
}
.chat-msg-user .chat-msg-meta { color: rgba(255,255,255,0.55); }
.chat-msg code {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 11px;
  color: #1a1a1a;
  background: rgba(0,0,0,0.06);
  padding: 1px 5px;
  border-radius: 3px;
}
.chat-msg-user code { background: rgba(255,255,255,0.18); color: #ffffff; }
.chat-action-row {
  display: flex;
  gap: 6px;
  margin-top: 8px;
}
.chat-action-btn {
  padding: 6px 12px;
  font-size: 11.5px;
  font-weight: 500;
  border-radius: 6px;
  border: 1px solid #1a1a1a;
  background: #1a1a1a;
  color: #ffffff;
  cursor: pointer;
}
.chat-action-btn.ghost {
  background: transparent;
  color: #1a1a1a;
}
.chat-action-btn:hover { background: #2d2d2d; color: #ffffff; }
.chat-action-btn.ghost:hover { background: #f0f0f0; color: #1a1a1a; }
.chat-noderef {
  display: inline-block;
  padding: 1px 6px;
  font-size: 11px;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  background: rgba(139, 111, 184, 0.14);
  color: #6b4e9a;
  border-radius: 3px;
  cursor: pointer;
  border: 1px solid transparent;
}
.chat-noderef:hover { border-color: #8b6fb8; }
.chat-input-row {
  display: flex;
  gap: 6px;
  padding: 10px 12px;
  border-top: 1px solid #ededed;
  background: #ffffff;
  align-items: flex-end; /* keep Send button anchored to the bottom as textarea grows */
}
.chat-input {
  flex: 1;
  padding: 8px 10px;
  border: 1px solid #e6e6e6;
  border-radius: 6px;
  font-size: 12.5px;
  color: #1a1a1a;
  outline: none;
  font-family: inherit;
  /* v0.51: textarea behavior — auto-resizes via JS to fit content; cap height
     before chat-body starts losing space. resize:none kills the corner grabber
     to keep the UI clean. line-height matches body so the rows look natural. */
  resize: none;
  min-height: 34px;
  max-height: 220px;
  line-height: 1.5;
  overflow-y: auto;
}
.chat-input:focus { border-color: #1a1a1a; }
.chat-input:disabled { background: #fafafa; color: #9a9a9a; cursor: not-allowed; }

/* v0.65: slash-command autocomplete menu — pops above the input row */
.chat-input-row { position: relative; }
.slash-menu {
  position: absolute;
  bottom: calc(100% + 4px);
  left: 12px;
  right: 12px;
  max-height: 240px;
  overflow-y: auto;
  background: #ffffff;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.16);
  padding: 4px;
  z-index: 60;
  display: none;
}
.slash-menu.open { display: block; }
.slash-menu-item {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 5px;
  cursor: pointer;
}
.slash-menu-item.active { background: #f1f1f3; }
.slash-menu-item .slash-cmd {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  color: #1a1a1a;
  font-weight: 600;
  flex-shrink: 0;
}
.slash-menu-item .slash-args {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  color: #a07a3a;
  flex-shrink: 0;
}
.slash-menu-item .slash-desc {
  font-size: 11px;
  color: #8a8a8a;
  margin-left: auto;
  padding-left: 10px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* v0.51: chat-head action group + download button */
.chat-head-actions {
  display: flex;
  align-items: center;
  gap: 4px;
}
.chat-head-btn {
  width: 24px;
  height: 24px;
  border: 0;
  background: transparent;
  color: #5a5a5a;
  border-radius: 4px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.12s, color 0.12s;
}
.chat-head-btn:hover { background: #f0f0f0; color: #1a1a1a; }
.chat-send {
  padding: 8px 14px;
  background: #1a1a1a;
  color: #ffffff;
  border: 0;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
}
.chat-send:disabled { background: #c0c0c0; cursor: not-allowed; }

/* When chat is open, slide minimap up so they don't collide */
.chat-container.expanded ~ .minimap.visible { right: 376px; transition: right 0.18s; }

/* v0.62: annotation nodes — text blocks + shapes. Pure canvas furniture:
   no card chrome, no ports, no shadow-lift. They sit visually BEHIND
   pipeline nodes (lower z) so labels/shapes frame rather than obscure. */
.node-text {
  position: absolute;
  z-index: 1;            /* below pipeline nodes (.node default is higher) */
  min-height: 28px;
  cursor: default;
}
.node-text-handle {
  height: 10px;
  margin: 0 0 2px 0;
  border-radius: 3px 3px 0 0;
  background: transparent;
  cursor: grab;
  transition: background 0.12s;
}
.node-text:hover .node-text-handle { background: rgba(0,0,0,0.08); }
.node-text-handle:active { cursor: grabbing; }
.node-text-body {
  outline: none;
  padding: 4px 6px;
  border-radius: 4px;
  line-height: 1.4;
  font-family: inherit;
  white-space: pre-wrap;
  word-break: break-word;
  min-height: 20px;
  transition: box-shadow 0.12s;
}
.node-text-body:focus {
  box-shadow: 0 0 0 1.5px rgba(90,141,109,0.5);  /* --type-character green, calm */
  background: rgba(255,255,255,0.6);
}

.node-shape {
  position: absolute;
  z-index: 1;
  cursor: grab;
}
.node-shape:active { cursor: grabbing; }
.node-shape svg { display: block; pointer-events: none; }
.node-shape-resize {
  position: absolute;
  right: -4px; bottom: -4px;
  width: 12px; height: 12px;
  border-radius: 3px;
  background: #ffffff;
  border: 1.5px solid #c0c0c0;
  cursor: nwse-resize;
  opacity: 0;
  transition: opacity 0.12s;
}
.node-shape:hover .node-shape-resize { opacity: 1; }

/* v0.59: session-spend chip — small running-total widget top-right under
   the auth UI. Tier colors stay calm per DESIGN.md. In-memory only,
   resets on reload. */
.session-spend-chip {
  position: fixed;
  top: 56px;
  right: 16px;
  z-index: 80;
  padding: 4px 10px;
  border-radius: 14px;
  background: #f0f7f2;
  border: 1px solid #cfe4d6;
  color: #2f5a3f;
  font-size: 11px;
  font-weight: 600;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  letter-spacing: 0.02em;
  cursor: default;
  user-select: none;
  white-space: pre-line;
  transition: background 0.18s, border-color 0.18s, color 0.18s;
}
.session-spend-chip[data-tier="mid"] {
  background: #f5f5f5;
  border-color: #e0e0e0;
  color: #555;
}
.session-spend-chip[data-tier="high"] {
  background: #fdf5e6;
  border-color: #f0d8a5;
  color: #8a5a00;
}

/* v0.72: build-progress panel — sticky top-right under the session-spend chip.
   Surfaces make_film_from_brief progress so a 3-4min run never looks frozen.
   Auto-renders + ticks 1s; status-colored border. */
.build-progress {
  position: fixed;
  top: 96px;
  right: 16px;
  width: 296px;
  background: #ffffff;
  border: 1px solid #e6e6e6;
  border-radius: 10px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
  padding: 12px 14px;
  font-size: 11.5px;
  color: #1a1a1a;
  z-index: 100;
  font-family: inherit;
  transition: border-color 0.2s, box-shadow 0.2s;
}
.build-progress[data-status="completed"] {
  border-color: #a3d2a8;
  box-shadow: 0 4px 16px rgba(120, 180, 120, 0.18);
}
.build-progress[data-status="failed"] {
  border-color: #e6a3a3;
  box-shadow: 0 4px 16px rgba(200, 80, 80, 0.18);
}
.build-progress[data-status="paused"] { border-color: #d8c890; }
.build-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}
.build-status {
  font-size: 14px;
  width: 18px;
  text-align: center;
  line-height: 1;
}
.build-status-running   { color: #c97f4a; }
.build-status-paused    { color: #a08540; }
.build-status-completed { color: #4a8d5a; }
.build-status-failed    { color: #c03030; }
.build-title {
  font-weight: 600;
  font-size: 11.5px;
  flex: 1;
}
.build-close {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 16px;
  color: #9a9a9a;
  padding: 0 4px;
  margin: -4px -4px -4px 0;
  line-height: 1;
}
.build-close:hover { color: #1a1a1a; }
.build-brief {
  font-style: italic;
  color: #6a6a6a;
  font-size: 10.5px;
  margin-bottom: 6px;
  line-height: 1.35;
}
.build-phase {
  font-size: 11px;
  color: #3a3a3a;
  margin-bottom: 6px;
  font-weight: 600;
}
.build-detail {
  color: #7a7a7a;
  font-weight: normal;
}
.build-dots {
  display: flex;
  gap: 4px;
  margin-bottom: 6px;
}
.build-phase-dot {
  font-size: 9px;
  color: #d8d8d8;
  line-height: 1;
}
.build-phase-dot.done   { color: #4a8d5a; }
.build-phase-dot.active {
  color: #c97f4a;
  animation: build-pulse 1.2s ease-in-out infinite;
}
@keyframes build-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.4; }
}
.build-meta {
  display: flex;
  justify-content: space-between;
  font-size: 10.5px;
  color: #7a7a7a;
}
.build-time {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.build-cost {
  font-weight: 600;
  color: #5a5a5a;
}
.build-fails {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid #ededed;
  font-size: 10px;
  color: #c08040;
}

/* v0.53: bootstrap status banner — surfaces project-load failures loudly so
   the user never silently sees an empty list when their data is actually
   safe on the server. Sits across the top of the page. */
.projects-bootstrap-banner {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 200;
  background: #fff7ed; /* warm warning, calm */
  border-bottom: 1px solid #f3d8b3;
  color: #8a4b00;
  padding: 8px 16px;
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 13px;
  line-height: 1.4;
  box-shadow: 0 1px 3px rgba(0,0,0,0.04);
  transition: transform 0.18s cubic-bezier(0.4, 0.1, 0.2, 1);
}
.projects-bootstrap-banner[data-level="error"] {
  background: #fde8ea;
  border-bottom-color: #f3c8cd;
  color: #8a1a23;
}
.projects-bootstrap-banner[data-level="info"] {
  background: #eef4fb;
  border-bottom-color: #d5e3f3;
  color: #2c5b8d;
}
.projects-bootstrap-banner.hidden {
  transform: translateY(-100%);
  pointer-events: none;
}
.projects-bootstrap-banner .pbb-msg {
  flex: 1;
  font-weight: 500;
}
.projects-bootstrap-banner .pbb-btn {
  padding: 4px 12px;
  font-size: 12px;
  font-weight: 600;
  background: transparent;
  border: 1px solid currentColor;
  color: inherit;
  border-radius: 4px;
  cursor: pointer;
}
.projects-bootstrap-banner .pbb-btn:hover { background: rgba(0,0,0,0.06); }
.projects-bootstrap-banner .pbb-close {
  width: 24px;
  height: 24px;
  border: 0;
  background: transparent;
  font-size: 16px;
  color: inherit;
  cursor: pointer;
  opacity: 0.7;
}
.projects-bootstrap-banner .pbb-close:hover { opacity: 1; }

/* v0.53: agentic chat — recovery action card. When sendToAgent hits a
   recoverable error, render a card with action buttons instead of the
   dead-end red error message. */
.chat-recovery-card {
  background: #fff7ed;
  border: 1px solid #f3d8b3;
  border-radius: 8px;
  padding: 10px 12px;
  margin: 6px 0;
  font-size: 12.5px;
  color: #5a3a00;
}
.chat-recovery-card .chat-recovery-msg { margin-bottom: 8px; }
.chat-recovery-card .chat-recovery-actions {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.chat-recovery-card .chat-recovery-btn {
  padding: 5px 12px;
  font-size: 11.5px;
  font-weight: 500;
  border-radius: 5px;
  border: 1px solid #c97f4a;
  background: #ffffff;
  color: #8a4b00;
  cursor: pointer;
}
.chat-recovery-card .chat-recovery-btn:hover { background: #fce7d2; }
.chat-recovery-card .chat-recovery-btn.primary {
  background: #c97f4a;
  color: #ffffff;
  border-color: #c97f4a;
}
.chat-recovery-card .chat-recovery-btn.primary:hover { background: #b06d3a; }

/* ============================================================================
   v1.3.0 — PROMPT-SCRIPT (scene) node. Billy's Figma: ONE node holds ALL of a
   scene's prompts (shots → clips → firstFrame/lastFrame/action). Amber/script
   family palette (matches the script node accents). Front = compact shot list
   + amber counts footer + the single combined output dot; back = the per-shot
   per-clip prompt editor, each row carrying its own orange port dot (the
   flip-side wire anchor — see getPortCenter).
   ============================================================================ */
.node[data-type="prompt-script"] .card-face { border-color: #e0d2b8; }
.node[data-type="prompt-script"] .title-row {
  background: #f9f2e6;
  border-bottom-color: #ecdfc6;
}
.node[data-type="prompt-script"] .title-icon { color: #b8853d; }
.node.minimized .card-front .pscript-body { display: none; }

/* ----- front: shot list ----- */
.pscript-body {
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  background: #fffdf8;
  border-bottom: 1px solid #f0eadb;
}
.pscript-shot-line {
  display: flex;
  gap: 6px;
  align-items: baseline;
  min-width: 0;
}
.pscript-shot-label {
  flex: 0 0 auto;
  color: #b8853d;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.pscript-shot-name {
  color: #2a2a28;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pscript-empty { font-size: 11px; color: #9a9a9a; }
/* amber live counts — front + back footers */
.card-footer .specs.pscript-counts {
  color: #b8853d;
  font-weight: 600;
  font-size: 9.5px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* ----- back: per-shot / per-clip prompt editor ----- */
.pscript-editor {
  padding: 10px 12px 4px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: #fffdf8;
}
/* v1.3.1: shots/clips nest in draggable blocks (shot-block > clip-block) so a
   header drag moves the whole section. Gaps reproduce the old flat rhythm:
   wrap gap 6 + block margin 8 = 14px above a new shot, label margin 4 + gap
   6 = 10px above a clip label — pixel-identical to the v1.3.0 layout. */
.pscript-shot-block {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.pscript-shot-block + .pscript-shot-block { margin-top: 8px; }
.pscript-clip-block {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.pscript-editor .pscript-shot-head {
  display: flex;
  gap: 6px;
  align-items: baseline;
  padding-bottom: 3px;
  border-bottom: 1px solid #f0e8d4;
  cursor: grab; /* v1.3.1: the header IS the shot drag handle */
}
.pscript-clip-label {
  margin-top: 4px;
  display: flex;          /* v1.3.1: prefix + editable name + grip */
  gap: 4px;
  align-items: baseline;
  font-size: 9.5px;
  font-weight: 600;
  color: #3a3a36;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  cursor: grab; /* v1.3.1: the label IS the clip drag handle (within-shot) */
}
.pscript-clip-prefix { flex: 0 0 auto; }
.pscript-clip-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* v1.3.1: the NAME portion of shot/clip headers is click-to-rename (the
   "SHOT n:" / "Cn:" prefixes stay static and renumber automatically). */
.pscript-editor .pscript-shot-name { flex: 0 1 auto; min-width: 0; }
.pscript-editor .pscript-shot-name.editable,
.pscript-clip-name.editable {
  cursor: text;
  outline: none;
  border-radius: 3px;
  padding: 0 2px;
  margin: 0 -2px;
}
.pscript-editor .pscript-shot-name.editable:hover,
.pscript-clip-name.editable:hover { background: rgba(184, 133, 61, 0.10); }
.pscript-editor .pscript-shot-name.editable:focus,
.pscript-clip-name.editable:focus {
  background: #fffef9;
  box-shadow: 0 0 0 1px #e8b84b;
  text-overflow: clip;
}
/* ≡ drag grip — visual affordance only; the whole header/label drags */
.pscript-drag-grip {
  flex: 0 0 auto;
  margin-left: auto;
  color: #cbb98e;
  font-size: 11px;
  line-height: 1;
  cursor: grab;
  user-select: none;
}
.pscript-prompt-row {
  position: relative;
  padding-right: 18px; /* room for the row's port dot (card-back clips overflow) */
}
.pscript-field-label {
  margin-bottom: 3px;
  font-size: 8.5px;
  font-weight: 600;
  color: #a1a098;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.pscript-field-label-inline { display: inline-block; margin: 0 8px 0 0; }
.pscript-field-line {
  display: flex;
  align-items: flex-start;
  gap: 6px;
}
/* the field block — amber LEFT ACCENT bar (prompt-card accent family) */
.pscript-field-wrap {
  flex: 1;
  min-width: 0;
  border-left: 3px solid #e8b84b;
  border-top: 1px solid #f0eadb;
  border-right: 1px solid #f0eadb;
  border-bottom: 1px solid #f0eadb;
  border-radius: 0 6px 6px 0;
  background: #fffdf6;
}
.pscript-field {
  padding: 6px 8px;
  min-height: 28px;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 11px;
  line-height: 1.45;
  color: #3a3a3a;
  outline: none;
  cursor: text;
  word-break: break-word;
  white-space: pre-wrap;
}
.pscript-field:empty::before {
  content: attr(data-placeholder);
  color: #b9b6ac;
  pointer-events: none;
}
.pscript-field:focus { background: #fffef9; border-radius: 0 6px 6px 0; }
/* trash — clears the field (junction firstFrame: removes back to +) */
.pscript-trash-btn {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin-top: 4px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 5px;
  background: transparent;
  color: #b5b2a8;
  cursor: pointer;
  transition: color 0.12s, background 0.12s;
}
.pscript-trash-btn:hover { color: #c44525; background: #faeae4; }
.pscript-trash-btn svg { width: 12px; height: 12px; }
/* junction "+ add first frame" — adds the optional fresh-start firstFrame
   override. v1.3.1: an obvious labelled amber CHIP (was a bare "+" glyph),
   same family as the title-row amber tint (#f9f2e6 / #b8853d). */
.pscript-add-btn {
  padding: 2px 9px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
  border: 1px dashed #d9c28e;
  border-radius: 999px;
  background: #f9f2e6;
  color: #b8853d;
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1.5;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.pscript-add-btn:hover { background: #f3e7cd; border-color: #b8853d; }
/* bottom "+ Add shot" — ADD A SHOT (with one full clip). v1.3.1: a clearly
   visible amber PILL with a persistent label (was a bare circled "+"). */
.pscript-add-shot {
  align-self: center;
  margin: 6px 0 8px;
  padding: 5px 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px dashed #d9c28e;
  border-radius: 999px;
  background: #f9f2e6;
  color: #b8853d;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, transform 0.06s;
}
.pscript-add-shot:hover { background: #f3e7cd; border-color: #b8853d; }
.pscript-add-shot:active { transform: scale(0.96); }
/* the row's own ORANGE port dot — flip-side wire anchor. Sits INSIDE the row's
   right edge (.card-back clips horizontal overflow, so no -8px overhang). */
.pscript-prompt-row .port.pscript-port {
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 12px;
  height: 12px;
}
.pscript-prompt-row .port.pscript-port:hover { transform: translateY(-50%) scale(1.3); }
.port.pscript-port { border-color: #e8a33d; }
.port.pscript-port:hover, .port.pscript-port.active { background: #e8a33d; }
.port.pscript-port.lit {
  background: #e8a33d;
  border-color: #c9821f;
  box-shadow: 0 0 0 3px rgba(232, 163, 61, 0.18);
}
