/* Database workspace — scoped for single-SPA shell */
#ws-database {
  flex: 1;
  display: none;
  flex-direction: column;
  min-height: 0;
  font-family: system-ui, -apple-system, Segoe UI, sans-serif;
  font-size: 14px;
}
body.app-database #ws-database { display: flex; }
body.app-database #ws-maps { display: none !important; }
body.app-database #maps-chrome { display: none !important; }
body.app-database #selection { display: none !important; }
body.app-maps #db-chrome { display: none !important; }
body.app-maps #ws-database { display: none !important; }

#ws-database .db-layout {
  flex: 1;
  display: grid;
  grid-template-columns:
    var(--db-nav-track, 184px)
    var(--db-list-track, 272px)
    minmax(0, 1fr);
  min-height: 0;
}

#ws-database .header-brand {
  display: flex;
  align-items: center;
  gap: 8px;
}

#ws-database header h1 {
  font-size: 16px;
  margin: 0;
  font-weight: 600;
  letter-spacing: 0.02em;
}

#ws-database .dirty-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--warn);
  flex-shrink: 0;
}
#ws-database .dirty-dot.hidden { display: none; }

#ws-database .status-line {
  font-size: 12px;
  color: var(--muted);
  flex: 1;
  min-width: 120px;
}
#ws-database .status-line.ok { color: var(--ok); }
#ws-database .status-line.warn { color: var(--warn); }
#ws-database .status-line.err { color: var(--danger); }

#db-portable-pending.portable-pending {
  margin: 0;
  padding: 6px 12px;
  font-size: 12px;
  line-height: 1.35;
  color: var(--warn);
  background: color-mix(in srgb, var(--warn) 12%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--warn) 35%, transparent);
}
#db-portable-pending.portable-pending.hidden { display: none; }

#db-btn-rebuild.needs-attention {
  outline: 1px solid var(--warn);
  color: var(--warn);
}

#ws-database .inline-validation {
  margin: 0 0 14px;
  padding: 10px 12px;
  color: #ffd2cc;
  background: color-mix(in srgb, var(--danger) 12%, #141a24);
  border: 1px solid color-mix(in srgb, var(--danger) 55%, var(--border));
  border-radius: 7px;
}
#ws-database .inline-validation strong { display: block; margin-bottom: 5px; }
#ws-database .inline-validation ul { margin: 0; padding-left: 20px; }
#ws-database .inline-validation li + li { margin-top: 3px; }

#ws-database .warn-note { color: var(--warn); }

#ws-database .art-preview {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
#ws-database .art-preview-frames {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-end;
}
#ws-database .art-preview-frame {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
/* The pack's frames are a picker: clicking one says "this species is that
   frame", instead of reading the number off a contact sheet and typing it into
   a dropdown. Dim until chosen, so the portrait this species actually uses is
   the one that stands out. */
#ws-database .art-frame-pick {
  padding: 4px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  opacity: 0.55;
}
#ws-database .art-frame-pick:hover { opacity: 0.85; }
#ws-database .art-frame-pick.picked {
  opacity: 1;
  border-color: #7fd1ff;
}
#ws-database .art-preview-img {
  image-rendering: pixelated;
  max-width: 100%;
  background: #1a1c22;
  border: 1px solid var(--border, #2a2e38);
}
#ws-database .art-preview-battle { width: 64px; height: 64px; }
#ws-database .art-preview-strip { height: 48px; width: auto; }

#ws-database .toolbar {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

#ws-database button, #ws-database select, #ws-database input[type="search"], #ws-database input[type="text"], #ws-database input[type="number"], #ws-database textarea {
  background: var(--panel2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 12px;
  font-size: 13px;
  font-family: inherit;
}

#ws-database select {
  color-scheme: dark;
}
#ws-database select option,
#ws-database select optgroup {
  color: #e8edf6;
  background-color: #192130;
}
#ws-database input:disabled,
#ws-database textarea:disabled,
#ws-database select:disabled {
  color: var(--muted);
  background: #10151e;
  border-style: dashed;
  cursor: not-allowed;
  opacity: .82;
}

#ws-database button {
  cursor: pointer;
  transition: border-color 0.12s, background 0.12s;
}
#ws-database button:hover:not(:disabled) { border-color: var(--accent); }
#ws-database button:disabled { opacity: 0.5; cursor: not-allowed; }
#ws-database button.primary {
  background: #2a5a9e;
  border-color: #3d74c4;
  color: #fff;
}
#ws-database button.primary:hover:not(:disabled) { background: #3568b0; }

#ws-database input:focus, #ws-database select:focus, #ws-database textarea:focus, #ws-database button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
#ws-database input:invalid,
#ws-database textarea:invalid,
#ws-database select:invalid {
  border-color: var(--danger);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--danger) 35%, transparent);
}

#ws-database .panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
  border-right: 1px solid var(--border);
  background: var(--bg);
}
#ws-database .panel:last-child { border-right: none; }

#ws-database .panel-head {
  padding: 10px 12px;
  background: var(--panel);
  border-bottom: 1px solid var(--border);
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  flex-shrink: 0;
}

#ws-database .panel-head h2 {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}

#ws-database .panel-head input[type="search"] {
  flex: 1;
  min-width: 100px;
}

#ws-database .scroll {
  overflow: auto;
  padding: 10px;
  flex: 1;
  min-height: 0;
}

/* Navigation */
#ws-database .nav-head h2 { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; }

#ws-database .nav-group-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  padding: 10px 10px 4px;
  margin: 0;
}

#ws-database .nav-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  text-align: left;
  padding: 8px 10px;
  border: none;
  background: transparent;
  color: var(--muted);
  border-radius: 6px;
  margin-bottom: 2px;
}
#ws-database .nav-item .nav-icon {
  width: 18px;
  text-align: center;
  opacity: 0.85;
  font-size: 12px;
}
#ws-database .nav-item.active {
  color: var(--text);
  background: var(--panel2);
  border: 1px solid var(--border);
}
#ws-database .nav-item:hover:not(.active) { color: var(--text); background: rgba(255, 255, 255, 0.04); }

/* List cards */
#ws-database .list-card {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  margin-bottom: 6px;
  background: var(--panel2);
  border: 2px solid transparent;
  border-radius: 8px;
  cursor: pointer;
  transition: border-color 0.12s, transform 0.08s;
}
#ws-database .list-card:hover { border-color: var(--border); }
#ws-database .list-card.active {
  border-color: var(--accent);
  background: #243048;
}

#ws-database .list-card-body {
  flex: 1;
  min-width: 0;
}
#ws-database .list-card-title {
  font-weight: 600;
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#ws-database .list-card-meta {
  font-size: 11px;
  color: var(--muted);
  margin-top: 2px;
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  align-items: center;
}

#ws-database .badge {
  display: inline-block;
  font-size: 10px;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--panel);
  color: var(--muted);
  border: 1px solid var(--border);
}
#ws-database .badge.dex { color: var(--accent); border-color: #3d5a80; background: #1a2840; }
#ws-database .badge.pocket-medicine { color: #8fd4a0; border-color: #3a5c48; }
#ws-database .badge.pocket-balls { color: #7eb8ff; border-color: #3a5080; }
#ws-database .badge.pocket-key { color: var(--warn); border-color: #5c4a30; }

#ws-database .state-badge {
  display: inline-flex;
  align-items: center;
  width: max-content;
  padding: 2px 7px;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
}
#ws-database .state-editable {
  color: #9ee6b1;
  border-color: #356747;
  background: #14291c;
}
#ws-database .state-readonly {
  color: #b7c0cf;
  border-color: #465063;
  background: #1a202b;
}
#ws-database .nav-lock {
  margin-left: auto;
  color: var(--muted);
  font-size: 9px;
  text-transform: uppercase;
}

#ws-database .type-chip {
  display: inline-block;
  font-size: 10px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 999px;
  color: #111;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

#ws-database .fx-thumb {
  flex-shrink: 0;
  image-rendering: pixelated;
  background-repeat: no-repeat;
  border: 1px solid var(--border);
  border-radius: 4px;
  background-color: #0c1220;
}
#ws-database .fx-preview-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 10px;
}
#ws-database .muted-label {
  font-size: 12px;
  color: var(--muted);
  margin: 8px 0 0;
  line-height: 1.4;
}

#ws-database .empty-state {
  color: var(--muted);
  font-size: 13px;
  padding: 16px 8px;
  text-align: center;
}

#ws-database .boot-error {
  max-width: 36rem;
  padding: 8px 4px;
}
#ws-database .boot-error h2 {
  margin: 0 0 8px;
  font-size: 15px;
  color: var(--danger);
}
#ws-database .boot-error p {
  margin: 0 0 8px;
  color: var(--text);
  line-height: 1.45;
}
#ws-database .boot-error-hint {
  color: var(--muted);
  font-size: 12px;
}

/* Detail */
#ws-database .detail-header {
  margin-bottom: 16px;
}
#ws-database .detail-header h2 {
  margin: 0;
  font-size: 20px;
  font-weight: 600;
}
#ws-database .detail-header .subtitle {
  color: var(--muted);
  font-size: 12px;
  margin-top: 4px;
}

#ws-database .detail-card {
  background: var(--panel2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 14px 16px;
  margin-bottom: 12px;
}
#ws-database .detail-card-title {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin: 0 0 12px;
  font-weight: 600;
}

.creature-detail-tabs {
  display: flex;
  gap: .35rem;
  margin: 0 0 12px;
  padding: 4px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--panel2);
}

.creature-detail-tabs button {
  flex: 1 1 0;
  min-height: 2.15rem;
  border-color: transparent;
  background: transparent;
  color: var(--muted);
}

.creature-detail-tabs button.active {
  color: var(--text);
  border-color: var(--border-strong, var(--border));
  background: var(--panel3);
  box-shadow: inset 0 -2px var(--accent);
}

.curve-samples {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
  gap: .45rem;
  margin-top: .75rem;
}

.curve-samples span {
  padding: .45rem .55rem;
  border: 1px solid var(--border);
  border-radius: 5px;
  color: var(--muted-strong, var(--text));
  background: var(--panel);
  font-variant-numeric: tabular-nums;
}

#ws-database .field { margin-bottom: 10px; }
#ws-database .field-editable > label::after {
  content: ' · edit';
  color: #75c990;
  font-size: 9px;
}
#ws-database .field-locked > label::after {
  content: ' · locked';
  color: #8c97aa;
  font-size: 9px;
}
#ws-database .field label {
  display: block;
  font-size: 11px;
  color: var(--muted);
  margin-bottom: 4px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.field input,
.field select,
#ws-database .field textarea {
  width: 100%;
  max-width: 100%;
}
#ws-database .field textarea { min-height: 4rem; resize: vertical; }
#ws-database .field-hint,
#ws-database .field-lock-reason {
  display: block;
  margin-top: 4px;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.35;
}
#ws-database .field-row {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}
#ws-database .field-row .field { flex: 1; min-width: 100px; }

#ws-database .stat-field {
  display: grid;
  grid-template-columns: 48px 1fr 64px;
  gap: 8px;
  align-items: center;
  margin-bottom: 8px;
}
#ws-database .stat-field label {
  font-size: 11px;
  color: var(--muted);
  text-transform: uppercase;
}
#ws-database .stat-bar-wrap {
  height: 8px;
  background: var(--panel);
  border-radius: 4px;
  overflow: hidden;
}
#ws-database .stat-bar {
  height: 100%;
  background: linear-gradient(90deg, #3d74c4, var(--accent));
  border-radius: 4px;
  transition: width 0.15s;
}
#ws-database .stat-field input[type="number"] {
  width: 100%;
  padding: 4px 6px;
}

#ws-database table.data-table {
  border-collapse: collapse;
  width: 100%;
  font-size: 13px;
}
table.data-table th,
#ws-database table.data-table td {
  border: 1px solid var(--border);
  padding: 6px 8px;
  text-align: left;
}
#ws-database table.data-table th {
  background: var(--panel);
  font-size: 10px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
table.data-table input,
#ws-database table.data-table select {
  width: 100%;
  border: none;
  background: transparent;
  padding: 4px;
}

#ws-database .matrix-wrap { overflow-x: auto; max-width: 100%; }
#ws-database .matrix th, #ws-database .matrix td { text-align: center; font-size: 11px; }
#ws-database .matrix td.match-x20 { background: rgba(111, 220, 140, 0.22); }
#ws-database .matrix td.match-x5 { background: rgba(255, 122, 107, 0.18); }
#ws-database .matrix td.match-x0 { background: rgba(255, 80, 60, 0.28); }
#ws-database .matrix select { font-size: 11px; min-width: 52px; }

#ws-database .type-matchup-focus {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}
#ws-database .type-matchup-table td:last-child,
#ws-database .type-matchup-table th:last-child { width: 8rem; text-align: center; }
#ws-database .type-matchup-table select { min-width: 6rem; text-align: center; }
#ws-database .type-matchup-full { margin-top: 14px; }
#ws-database .type-matchup-full > summary {
  width: max-content;
  cursor: pointer;
  color: var(--accent);
  font-size: 12px;
}
#ws-database .type-matchup-full[open] > summary { margin-bottom: 10px; }

@media (max-width: 900px) {
  #ws-database .type-matchup-focus { grid-template-columns: 1fr; }
}

#ws-database .curve-card .formula {
  font-family: ui-monospace, monospace;
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 10px;
}
#ws-database .curve-users {
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 12px;
}
#ws-database .curve-chart {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 80px;
  padding-top: 8px;
}
#ws-database .curve-bar-col {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  min-width: 0;
}
#ws-database .curve-bar {
  width: 100%;
  max-width: 36px;
  background: linear-gradient(180deg, var(--accent), #3d74c4);
  border-radius: 4px 4px 0 0;
  min-height: 4px;
}
#ws-database .curve-bar-label {
  font-size: 10px;
  color: var(--muted);
}
#ws-database .curve-bar-value {
  font-size: 9px;
  color: var(--muted);
}

#ws-database .row-actions button {
  margin-top: 4px;
  font-size: 12px;
}
#ws-database .table-row-controls { display: flex; gap: 4px; align-items: center; }
#ws-database .table-row-controls button { padding: 4px 7px; white-space: nowrap; }

#ws-database .readonly-note {
  color: var(--muted);
  font-size: 13px;
  margin-bottom: 12px;
  padding: 10px 12px;
  background: var(--panel);
  border-radius: 6px;
  border: 1px dashed var(--border);
}

#ws-database .animation-pack-line,
#ws-database .animation-player-controls,
#ws-database .animation-actions,
#ws-database .rom-sample-strip {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
#ws-database .animation-pack-line { margin-bottom: 12px; }
#ws-database .animation-pack-line .muted-label { margin: 0; }
#ws-database .animation-player {
  display: grid;
  grid-template-columns: 128px minmax(0, 1fr);
  gap: 12px;
  align-items: center;
  margin: 12px 0;
}
#ws-database .animation-stage {
  display: grid;
  place-items: center;
  width: 128px;
  height: 128px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background:
    linear-gradient(45deg, #101620 25%, transparent 25%) 0 0 / 16px 16px,
    linear-gradient(45deg, transparent 75%, #101620 75%) 0 0 / 16px 16px,
    linear-gradient(45deg, transparent 75%, #101620 75%) -8px 8px / 16px 16px,
    linear-gradient(45deg, #101620 25%, #192130 25%) -8px 8px / 16px 16px;
}
#ws-database .battle-anim-frame {
  flex: 0 0 auto;
  image-rendering: pixelated;
  background-repeat: no-repeat;
  background-color: #0d121b;
  border: 1px solid var(--border);
  border-radius: 5px;
}
#ws-database .animation-readout { color: var(--muted); font-size: 11px; }
#ws-database .animation-timeline,
#ws-database .animation-catalog-strip {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding: 10px 2px;
}
#ws-database .animation-frame-item {
  position: relative;
  flex: 0 0 auto;
  padding: 18px 6px 6px;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: #121824;
}
#ws-database .animation-frame-order {
  position: absolute;
  top: 3px;
  left: 6px;
  color: var(--muted);
  font-size: 9px;
}
#ws-database .animation-frame-controls { display: flex; gap: 3px; margin-top: 5px; }
#ws-database .animation-frame-controls button { padding: 2px 6px; font-size: 11px; }
#ws-database .animation-actions { margin: 2px 0 14px; }
#ws-database .rom-sample { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }
#ws-database .rom-sample .muted-label { display: block; margin: 0 0 7px; }

@media (max-width: 620px) {
  #ws-database .animation-player { grid-template-columns: 1fr; }
}

/* Toast */
#db-toast.toast {
  position: fixed;
  bottom: 16px;
  right: 16px;
  max-width: 420px;
  padding: 12px 16px;
  border-radius: 8px;
  background: var(--panel);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  z-index: 100;
  animation: toast-in 0.2s ease-out;
  font-size: 13px;
  line-height: 1.45;
}
#db-toast.toast.ok { border-color: var(--ok); }
#db-toast.toast.err { border-color: var(--danger); }
#db-toast.toast.hidden { display: none; }
#db-toast.toast ul {
  margin: 8px 0 0;
  padding-left: 18px;
}
#db-toast.toast li { margin-bottom: 4px; }

#ws-database .support-badge {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid var(--border);
  vertical-align: middle;
  white-space: nowrap;
}
#ws-database .support-snes {
  color: #0d3b24;
  background: #6fdc8c;
  border-color: #4caf6e;
}
#ws-database .support-web {
  color: #1a334d;
  background: #6eb5ff;
  border-color: #4a90d9;
}
#ws-database .support-none {
  color: #4a3a1a;
  background: #ffb060;
  border-color: #d99440;
}
#ws-database .support-row,
#ws-database .support-field-item {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  margin-top: 8px;
}
#ws-database .support-note {
  font-size: 12px;
  color: var(--muted);
  flex: 1;
  min-width: 12rem;
}
#ws-database .support-field-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
#ws-database .support-field-item code {
  font-size: 12px;
  min-width: 6.5rem;
}

@keyframes toast-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

#ws-database .event-steps {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
#ws-database .event-step {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--panel);
}
#ws-database .event-step-controls {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex-shrink: 0;
}
#ws-database .event-step-controls button {
  width: 2rem;
  padding: 2px 0;
  font-size: 14px;
  line-height: 1.2;
}
#ws-database .event-step-controls button.danger {
  color: var(--danger);
}
#ws-database .event-step-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
#ws-database .event-step-index {
  font-size: 11px;
  font-weight: 700;
  color: var(--muted);
  letter-spacing: 0.04em;
}
#ws-database .event-step-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}
#ws-database .event-step-operands {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 16px;
}
#ws-database .event-show-text-body {
  margin-top: 10px;
  width: 100%;
}
#ws-database .event-show-text-body textarea {
  width: 100%;
  min-height: 5rem;
}
#ws-database .event-step-text-actions {
  display: flex;
  gap: 8px;
  margin-top: 6px;
}
#ws-database .event-step-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
  margin-top: 12px;
}
/* Script / Steps: two views of the same instructions, so they sit together
   above the detail rather than looking like two different editors. */
#ws-database .event-view-tabs {
  display: flex;
  gap: 4px;
  margin: 8px 0 4px;
}
#ws-database .event-view-tab {
  padding: 4px 12px;
  background: var(--bg, #111);
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
}
#ws-database .event-view-tab.active {
  border-color: #7fd1ff;
  font-weight: 600;
}
/* Monospace and tall: this is the editing surface, not a form field. Tabs are
   never typed -- the form is indentation-insensitive -- so the default tab
   behaviour moving focus out of the box is the right one. */
#ws-database .event-script-text {
  width: 100%;
  min-height: 22rem;
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 0.85rem;
  line-height: 1.45;
  white-space: pre;
  overflow-wrap: normal;
  overflow-x: auto;
  tab-size: 4;
}
#ws-database .event-script-text:disabled {
  opacity: 0.75;
  cursor: default;
}
#ws-database .event-run-flags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  margin: 8px 0 12px;
}
#ws-database .event-run-flag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 0.9rem;
}
#ws-database .event-run-transcript {
  margin-top: 12px;
  padding: 10px;
  max-height: 240px;
  overflow: auto;
  background: var(--bg, #111);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.8rem;
  white-space: pre-wrap;
}
.npc-script-badge {
  margin: 8px 0 0;
  font-size: 0.85rem;
  opacity: 0.85;
}

/* ---------------------------------------------------------------------------
   Themes workspace — the tileset workbench.

   Three panes: the map as the theme draws it, the roles it draws, and the
   sheet those roles are cut from. The sheet is the one that needs care: it is
   an image with clickable boxes laid over it, so the overlay has to sit
   exactly on the image at any zoom, which is why both are sized in script
   rather than by CSS.
   --------------------------------------------------------------------------- */
/* Workspaces are switched by a body class, not by [hidden] alone: the
   stylesheet gives each one an explicit `display`, which outranks the UA rule
   that [hidden] relies on. Miss these and every workspace draws at once. */
body.app-themes #ws-themes { display: flex; flex-direction: column; }
body.app-themes #ws-maps,
body.app-themes #ws-database,
body.app-themes #maps-chrome,
body.app-themes #db-chrome,
body.app-themes #selection { display: none !important; }
body.app-maps #ws-themes,
body.app-database #ws-themes { display: none !important; }

.theme-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
.theme-bar label { display: flex; align-items: center; gap: 6px; }
.theme-bar-actions { margin-left: auto; display: flex; gap: 6px; }
#theme-status.bad { color: #ff9d9d; }

.theme-layout {
  display: grid;
  /* The roles list is a list of short labels; it does not need a quarter
     of the window. Narrower here gives the map and the sheet the room,
     which is where the work actually happens. */
  grid-template-columns: minmax(320px, 3fr) var(--theme-roles-track, minmax(220px, 1fr));
  grid-template-rows: minmax(240px, 1fr) minmax(200px, 1fr);
  gap: 10px;
  padding: 10px;
  height: calc(100vh - 150px);
}
.theme-preview { grid-column: 1; grid-row: 1; overflow: hidden; }
.theme-roles-panel { grid-column: 2; grid-row: 1 / span 2; overflow: hidden; }
.theme-sheet-panel { grid-column: 1; grid-row: 2; overflow: hidden; }
.theme-preview .scroll { height: 100%; overflow: auto; }
#theme-preview-img { display: block; image-rendering: pixelated; }

.theme-role {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: 5px 6px;
  /* The spec line carries names like PALLET_WALL_LEFT, which will not fit the
     narrower column on one line and must wrap rather than push the column
     back open. */
  min-width: 0;
  margin: 0 0 4px;
  text-align: left;
  background: var(--bg, #111);
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
}
.theme-role.active { border-color: #7fd1ff; }
/* An edited role is the one thing you must be able to see at a glance: it is
   what will be written if you press Save. */
.theme-role.edited { border-left: 3px solid #ffd166; }
.theme-role-text {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  min-width: 0; overflow-wrap: anywhere;
}
.theme-role-name { font-weight: 600; }
.theme-role-spec { font-size: 0.78rem; opacity: 0.75; }
.theme-role-cells { font-size: 0.72rem; opacity: 0.55; }
.theme-role:disabled { cursor: default; opacity: 1; }
/* The swatch is the fastest way to see what a role draws — including for
   Cartographer, which has no family to describe but does have art. */
.theme-swatch {
  width: 24px; height: 24px;
  image-rendering: pixelated;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: #222;
  flex: none;
}
.theme-hint { margin: 4px 10px 6px; font-size: 0.78rem; }
.theme-preview .panel-head { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
#theme-preview-img { cursor: crosshair; }

.theme-sheet-panel .panel-head { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.theme-sheet-scroll { height: 100%; overflow: auto; }
.theme-sheet-stack { position: relative; display: inline-block; }
#theme-sheet-img { display: block; image-rendering: pixelated; }
.theme-sheet-overlay { position: absolute; inset: 0; }
.theme-candidate {
  position: absolute;
  padding: 0;
  background: rgba(127, 209, 255, 0.14);
  border: 1px solid #7fd1ff;
  border-radius: 2px;
  cursor: pointer;
}
.theme-candidate:hover { background: rgba(255, 209, 102, 0.3); border-color: #ffd166; }

/* A block another theme already uses on this sheet. Worth telling apart from
   one the scan found: it is knowledge about the pack, not about the file. */
.theme-candidate.known {
  background: rgba(160, 255, 170, 0.14);
  border-color: #8fe39a;
  border-style: dashed;
}
.theme-candidate.known:hover { background: rgba(160, 255, 170, 0.32); }

/* Where a tile the map draws sits on Cartographer's sheet. Faint for all of
   them, lit for the selected role: the sheet is 533 rows deep and a map uses
   a scattered handful, so without a mark you are hunting. */
.theme-tile-mark {
  position: absolute;
  padding: 0;
  background: transparent;
  border: 1px solid rgba(127, 209, 255, 0.35);
  border-radius: 2px;
  cursor: pointer;
}
.theme-tile-mark:hover { border-color: #ffd166; background: rgba(255, 209, 102, 0.2); }
/* Active must beat .mapped — equal specificity used to leave selected role
   tiles looking only faintly green when they were already assigned.
 *
 * Blue, not amber, and quiet. This says "these tiles belong to the role you
 * clicked", which can be most of the sheet at once; amber is reserved for
 * .theme-pair-box, the handful you actually dragged a box around. Both being
 * amber -- and this one heavier, at 3px over a half-opaque fill -- made a role
 * click look like a selection and buried the real one underneath it. */
.theme-tile-mark.active,
.theme-tile-mark.active.mapped,
.theme-tile-mark.active.mapped.on-base {
  border-color: #7fd1ff;
  border-width: 2px;
  border-style: solid;
  background: rgba(127, 209, 255, 0.16);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18);
  z-index: 2;
}
#theme-used-wrap { display: flex; align-items: center; gap: 5px; }

/* Tiles mode: the original and the theme side by side, and a mapping between
   them. Two independent scrollers -- the sheets have nothing to do with each
   other's shape, and 533 rows next to 110 would make a shared one useless. */
/* `.panel` sets its own display, which outranks the UA rule [hidden] relies
   on -- so the pane being switched away from keeps drawing, on top of the one
   replacing it. Same trap as the workspaces, one level down. */
.theme-layout > .panel[hidden] { display: none !important; }

/* `min-height: 0` at every level, which is what actually makes these scroll.
   A flex or grid child defaults to min-content, so a 34,000px sheet makes the
   pane 34,000px tall and nothing scrolls -- the page grows instead, and the
   tiles sit a thousand pixels below the fold. */
.theme-pair-panel {
  grid-column: 1;
  grid-row: 2;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}
.theme-pair-panel .panel-head { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.theme-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  flex: 1;
  min-height: 0;
}
.theme-pair-side { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.theme-pair-side-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 2px 8px;
}
.theme-pair-side-head h3 { margin: 0; font-size: 0.78rem; opacity: 0.7; font-weight: 500; }
.theme-role-nav { display: flex; gap: 4px; }
.theme-role-nav[hidden] { display: none !important; }
.theme-role-nav button:disabled { opacity: 0.35; }
.theme-pair-side h3 { margin: 2px 8px; font-size: 0.78rem; opacity: 0.7; font-weight: 500; }
.theme-pair-scroll { flex: 1; min-height: 0; overflow: auto; }
.theme-pair-stack { position: relative; display: inline-block; }
.theme-pair-stack img { display: block; image-rendering: pixelated; }
.theme-pair-stack .theme-sheet-overlay { cursor: crosshair; }
.theme-pair-grid {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  image-rendering: pixelated;
}
#theme-pair-grid.active { outline: 1px solid var(--accent, #7fd1ff); }
/* A tile that has been mapped. */
.theme-tile-mark.mapped {
  border-color: #8fe39a;
  background: rgba(143, 227, 154, 0.22);
}
/* And one that is not, which used to be "whatever has no other class" -- fine
   on an exterior where a handful remain, useless on an interior where it is
   nearly every tile and the eye has nothing to catch. Dotted and dim: present
   enough to count, quiet enough to ignore while working. */
.theme-tile-mark.unmapped {
  border-color: rgba(190, 190, 200, 0.45);
  border-style: dotted;
}
/* Mapped and standing on the theme's base. A dashed edge rather than another
   colour: it is a second fact about a mapped tile, not a third kind of one. */
.theme-tile-mark.mapped.on-base {
  border-style: dashed;
  border-width: 2px;
}
.theme-pair-box {
  position: absolute;
  border: 2px solid #ffd166;
  background: rgba(255, 209, 102, 0.15);
  pointer-events: none;
  border-radius: 2px;
}
.character-animation-preview {
  display: grid;
  gap: .6rem;
  margin: .4rem 0 1rem;
}

.character-list-thumb {
  width: 42px;
  height: 42px;
  flex: 0 0 42px;
  object-fit: contain;
  image-rendering: pixelated;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: repeating-conic-gradient(#20252b 0 25%, #282e35 0 50%) 0 / 10px 10px;
}

.character-list-thumb.missing { opacity: .2; }

.list-section-label {
  margin: .8rem .25rem .3rem;
  color: var(--muted);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.list-section-label:first-child { margin-top: .15rem; }

.character-role-note {
  margin: 0 0 12px;
  padding: .7rem .8rem;
  border-left: 3px solid var(--accent);
  color: var(--muted-strong, var(--text));
  background: color-mix(in srgb, var(--accent) 8%, var(--panel2));
}

.character-usage-list { display: grid; gap: .4rem; }
.character-usage-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  padding: .5rem .6rem;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--panel2);
}

.character-usage-copy { display: grid; min-width: 0; gap: .1rem; }
.character-usage-copy small { color: var(--muted); }
.trainer-assignment {
  margin-top: .65rem;
  border-top: 1px solid var(--border);
  padding-top: .65rem;
}
.trainer-assignment summary {
  cursor: pointer;
  color: var(--accent);
  font-weight: 700;
}
.trainer-list-filters {
  display: flex;
  gap: .35rem;
  padding: .55rem .65rem .2rem;
}
.trainer-list-filters button {
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: .25rem .6rem;
  background: var(--surface-2, rgba(255, 255, 255, 0.045));
  color: var(--muted);
  cursor: pointer;
}
.trainer-list-filters button.active {
  border-color: var(--accent);
  color: var(--text);
  background: color-mix(in srgb, var(--accent) 18%, rgba(255, 255, 255, 0.045));
}
.trainer-placement-placed { color: var(--success, #74d99f); }
.trainer-placement-unplaced { color: var(--muted); }

.detail-header .event-return-button { margin-left: auto; }
.event-starter-controls { display: grid; gap: .65rem; }
.event-starter-settings { display: grid; gap: .55rem; }
.event-starter-settings .readonly-note { margin: 0; }
.trainer-assignment-control {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
  align-items: end;
  gap: .6rem;
  padding-top: .65rem;
}
.trainer-assignment-control .field-hint,
.trainer-assignment-control .readonly-note {
  grid-column: 1 / -1;
  margin: 0;
}
@media (max-width: 760px) {
  .trainer-assignment-control { grid-template-columns: 1fr; }
}
.character-manage-actions { display: flex; flex-wrap: wrap; gap: .5rem; }
.character-manage-actions .danger {
  color: var(--danger, #ff7a6b);
  border-color: color-mix(in srgb, var(--danger, #ff7a6b) 45%, var(--border));
}

.asset-missing-error {
  padding: .65rem;
  color: var(--danger, #ff7a6b);
  border: 1px solid color-mix(in srgb, var(--danger, #ff7a6b) 40%, transparent);
  border-radius: 5px;
}

.character-animation-stage {
  display: grid;
  width: 8rem;
  height: 7rem;
  place-items: center;
  overflow: hidden;
  border: 1px solid var(--border, #3b4149);
  border-radius: 6px;
  background: repeating-conic-gradient(#20252b 0 25%, #282e35 0 50%) 0 / 12px 12px;
}

.character-animation-sprite {
  image-rendering: pixelated;
  background-repeat: no-repeat;
}

.character-facing-controls {
  display: flex;
  flex-wrap: wrap;
  gap: .3rem;
}

.character-facing-controls button.active {
  border-color: var(--accent, #78a9ff);
  color: var(--accent, #78a9ff);
}
.visual-asset-trigger {
  width: 100%;
  min-height: 2.25rem;
  text-align: left;
}

.asset-picker-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: grid;
  place-items: center;
  padding: 2rem;
  background: rgb(6 9 13 / 78%);
}

.asset-picker-dialog {
  display: grid;
  grid-template-rows: auto auto auto minmax(0, 1fr);
  gap: .75rem;
  width: min(62rem, 100%);
  max-height: min(46rem, 92vh);
  padding: 1rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--panel, #171b21);
  box-shadow: 0 1.5rem 5rem rgb(0 0 0 / 45%);
}

.asset-picker-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.asset-picker-head h2 { margin: 0; }

.asset-picker-facing {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .35rem;
  color: var(--muted);
  font-size: .78rem;
}

.asset-picker-facing button { padding: .28rem .55rem; }
.asset-picker-facing button.active {
  color: var(--accent);
  border-color: var(--accent);
}

.asset-picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: .65rem;
  overflow: auto;
}

.asset-picker-card {
  display: grid;
  grid-template-rows: 7rem auto auto auto;
  gap: .25rem;
  min-width: 0;
  padding: .55rem;
  text-align: left;
}

.asset-picker-card.active { border-color: var(--accent); }
.asset-picker-character-stage {
  display: grid;
  width: 100%;
  height: 7rem;
  place-items: center;
  overflow: hidden;
  border-radius: 4px;
  background: repeating-conic-gradient(#20252b 0 25%, #282e35 0 50%) 0 / 12px 12px;
}

.asset-picker-character-sprite { flex: 0 0 auto; }
.asset-picker-card img {
  width: 100%;
  height: 7rem;
  object-fit: contain;
  image-rendering: pixelated;
  background: repeating-conic-gradient(#20252b 0 25%, #282e35 0 50%) 0 / 12px 12px;
}
.asset-picker-card span,
.asset-picker-card small {
  overflow: hidden;
  color: var(--muted);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.asset-picker-card .asset-picker-source { color: var(--muted-strong, #b6c0d0); }

.asset-provenance {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: .3rem .75rem;
  margin: .8rem 0 0;
  padding-top: .75rem;
  border-top: 1px solid var(--border);
  font-size: .82rem;
}

.asset-provenance dt { color: var(--muted); }
.asset-provenance dd { margin: 0; overflow-wrap: anywhere; }
