/* Shared chrome for Vellmoor Editor (maps + database). */

/* The header, in two rows.
 *
 * Row one says where you are and what the project is made of; row two says
 * what you can do here. The old header was one wrapping row holding all of
 * it -- brand, tabs, two labelled dropdowns, the ROM buttons, a status line
 * and *both* workspaces' action groups -- and its alignment was whatever the
 * wrap happened to produce at that window width.
 *
 * Sizes are in px rather than rem. This is a tool bar, not prose: the controls
 * want to be the same height as each other at every zoom, and 28px is that
 * height.
 */

.app-header {
  display: block;
  padding: 0;
  gap: 0;
}

.app-bar,
.work-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  min-width: 0;
}

.app-bar {
  border-bottom: 1px solid var(--border, #343c50);
  /* Slightly darker than the row below: the title bar reads as chrome, the
     action bar as something you use. */
  background: rgba(0, 0, 0, 0.18);
}

.work-bar { flex-wrap: wrap; }

.header-chrome {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

/* Only one workspace's actions at a time. `tools/data_editor/editor.css` has
   said so for a long time; it is served at /database/static/editor.css, and
   while that route 404'd both rendered at once. Saying it here too means the
   header does not depend on the Database workspace's stylesheet loading. */
body.app-database #maps-chrome,
body.app-maps #db-chrome,
body.app-themes #maps-chrome,
body.app-themes #db-chrome { display: none; }

/* The document header describes the open *map*, so it belongs to the World
   workspace. Left visible elsewhere it announced "World / Maps / City 3 / Lab"
   over the monster database. */
body.app-database #doc-breadcrumb,
body.app-database #doc-meta,
body.app-themes #doc-breadcrumb,
body.app-themes #doc-meta { display: none; }

body.app-database #status,
body.app-themes #status,
body.app-maps #db-status,
body.app-themes #db-status { display: none; }

/* Groups are separated by a rule, the way a tool bar's groups always have
   been -- cheaper to read than eight px of extra gap. */
.rom-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-left: 8px;
  border-left: 1px solid var(--border, #343c50);
}

.rom-download {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 0 10px;
  border: 1px solid var(--border, #343c50);
  border-radius: var(--radius-sm, 4px);
  color: var(--text);
  background: var(--panel2);
  text-decoration: none;
  font: inherit;
}
.rom-download:hover { border-color: var(--border-strong); background: var(--panel3); }
.rom-download.hidden { display: none; }

/* The web game is opened at the map you are looking at, so it is only an
   option where there is one. */
body:not(.app-maps) #btn-play { display: none; }

/* The status bar.
 *
 * One line along the bottom carrying everything that used to be a caption
 * somewhere: what is selected, what the last action did, what the ROM build
 * is saying. Fixed height and fixed to the bottom, so a message that grows
 * cannot reflow the canvas above it -- which is what the old strip under the
 * header did, mid-drag, shifting the map under the cursor.
 */
.status-bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 12px;
  height: 26px;
  padding: 0 12px;
  font-size: 12px;
  color: var(--muted, #8b95a8);
  background: var(--panel, #1c2230);
  border-top: 1px solid var(--border, #343c50);
  white-space: nowrap;
  overflow: hidden;
}

/* What is under the cursor or selected. Truncates rather than wraps: this bar
   is one line, and a second one would move the canvas. */
.status-context {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.status-spacer { flex: 1 1 auto; }

/* The log opens upward, over the workspace, rather than pushing the bar. */
.status-bar .rom-build-log-wrap {
  position: relative;
  flex: 0 0 auto;
  font-size: 11px;
}

.status-bar .rom-build-log-wrap > summary {
  cursor: pointer;
  list-style: none;
}

.status-bar .rom-build-log {
  font-family: var(--font-mono, ui-monospace, Consolas, monospace);
  position: absolute;
  right: 0;
  bottom: 1.6em;
  z-index: 60;
  width: 46rem;
  max-width: 80vw;
  max-height: 16rem;
  overflow: auto;
  margin: 0;
  padding: 8px 10px;
  background: var(--panel, #1c2230);
  border: 1px solid var(--border, #343c50);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.55);
  white-space: pre-wrap;
  word-break: break-word;
}

.app-header button,
.app-header select,
.app-header .project-source {
  height: 28px;
  padding: 0 10px;
  font-size: 12px;
  line-height: 1;
}

/* A dropdown with a bare word next to it reads as two things. Wrapped in a
   bordered field with the word inside it, it reads as one labelled control --
   which is what `art yana` and `monsters Yana` always were.

   Scoped to the header. Unscoped, this claimed every `.field` in the Data
   workspace as well -- a 28px inline-flex box with `overflow: hidden` around
   a label that expects to sit *above* its input -- which clipped ACCURACY,
   PRIORITY and CRIT STAGE on every record in the database. */
.app-header .field {
  display: inline-flex;
  align-items: center;
  height: 28px;
  border: 1px solid var(--border, #343c50);
  border-radius: 6px;
  background: var(--panel2, #252c3c);
  overflow: hidden;
}

.app-header .field-label {
  padding: 0 8px;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted, #8b95a8);
  border-right: 1px solid var(--border, #343c50);
  align-self: stretch;
  display: flex;
  align-items: center;
  white-space: nowrap;
}

.app-header .field select {
  border: 0;
  border-radius: 0;
  background: transparent;
  max-width: 11rem;
}

.app-bar-right {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  min-width: 0;
}

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

#db-status.status-line {
  font-size: 12px;
  color: var(--muted, #8b95a8);
  min-width: 0;
}
#db-status.status-line.ok { color: var(--ok, #6fdc8c); }
#db-status.status-line.warn { color: var(--warn, #ffb060); }
#db-status.status-line.err { color: var(--danger, #ff7a6b); }

#ws-maps.workspace {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.editor-shell-nav {
  display: flex;
  align-items: center;
  gap: 2px;
  min-width: 0;
}

.editor-shell-brand {
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.02em;
  color: inherit;
  text-decoration: none;
  margin-right: 10px;
  padding-right: 10px;
  border-right: 1px solid var(--border, #343c50);
  opacity: 0.92;
  white-space: nowrap;
}

.editor-shell-tab {
  display: inline-flex;
  align-items: center;
  height: 26px;
  padding: 0 12px;
  border-radius: 5px;
  font-size: 12px;
  color: inherit;
  text-decoration: none;
  opacity: 0.7;
  border: 1px solid transparent;
  white-space: nowrap;
}

.editor-shell-tab:hover {
  opacity: 1;
  border-color: rgba(255, 255, 255, 0.15);
}

.editor-shell-tab.active {
  opacity: 1;
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.2);
}

/* The document header: where you are, and what is open.
 *
 * This row used to repeat the workspace's own name -- "Maps", under a tab also
 * saying "Maps", above a panel heading saying "Maps" -- and never plainly said
 * which map you had open. The breadcrumb answers the first question and the
 * map's name is the strongest text on the row, which answers the second.
 */
.doc-breadcrumb {
  display: flex;
  align-items: center;
  gap: 5px;
  min-width: 0;
  font-size: 12px;
  color: var(--muted, #8b95a8);
  white-space: nowrap;
}

.doc-breadcrumb .crumb-sep { opacity: 0.5; }

.doc-breadcrumb .crumb-current {
  font-size: 13px;
  font-weight: 600;
  color: var(--text, #e8eaee);
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Everything else about the map: size, id, the sheet its tiles come from.
   Muted and compact, because it is reference rather than navigation. */
.doc-meta {
  font-size: 11px;
  color: var(--muted, #8b95a8);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.doc-actions { position: relative; display: inline-flex; }

/* The save state, said in words.
 *
 * A disabled Save button only means "nothing to write" to someone who already
 * knows that is what it means. Colour is never the only signal: each state
 * says itself. */
.save-state {
  font-size: 11px;
  padding: 0 8px;
  border-radius: 999px;
  line-height: 20px;
  white-space: nowrap;
  border: 1px solid transparent;
}

.save-state[data-state="clean"] { color: var(--muted, #8b95a8); }

.save-state[data-state="dirty"] {
  color: var(--warn, #ffb060);
  border-color: rgba(255, 176, 96, 0.35);
  background: rgba(255, 176, 96, 0.10);
}

.save-state[data-state="saving"] { color: var(--accent, #6eb5ff); }

.save-state[data-state="error"] {
  color: var(--danger, #ff7a6b);
  border-color: rgba(255, 122, 107, 0.45);
  background: rgba(255, 122, 107, 0.12);
}

.settings-group { position: relative; display: inline-flex; }

/* The project settings menu holds labelled fields rather than menu items, so
   it needs room the icon-sized rows do not. */
#settings-menu { min-width: 22rem; padding: 6px; gap: 6px; }
#settings-menu .field { width: 100%; }
#settings-menu .field select {
  flex: 1 1 auto;
  min-width: 0;
  max-width: none;
  color-scheme: dark;
  color: var(--text, #e7edf7);
  background: var(--panel2, #252c3c);
}

/* Chromium/Windows otherwise opens these native menus as white while
   inheriting the shell's near-white foreground, making every unselected row
   disappear. Both colours must be stated on the popup rows themselves. */
#settings-menu .field select option,
#settings-menu .field select optgroup {
  color: #e7edf7;
  background-color: #252c3c;
}

#settings-menu .field select option:disabled { color: #8792a5; }

/* The compact product mark. A placeholder box until the icon pack lands; the
   full illustrated logo never belongs in editing chrome. */
.smce-mark {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  border-radius: 4px;
  background: linear-gradient(140deg, var(--accent, #6eb5ff), #a98bff);
}

.editor-shell-context {
  font-size: 11px;
  font-weight: 400;
  opacity: 0.55;
  margin-left: 6px;
}

.rom-build-log-wrap.hidden {
  display: none;
}

.rom-build-log-wrap {
  flex-basis: 100%;
  margin: 0;
  font-size: 0.8rem;
}

.rom-build-log {
  max-height: 12rem;
  overflow: auto;
  margin: 0.35rem 0 0;
  padding: 0.5rem 0.65rem;
  background: rgba(0, 0, 0, 0.35);
  border-radius: 4px;
  white-space: pre-wrap;
  word-break: break-word;
}

/* NPC inspector on map workspace */
.npc-form {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  padding: 0.5rem 0.75rem 1rem;
}

.npc-form label {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  font-size: 0.8rem;
}

.npc-form-section {
  display: grid;
  gap: 0.55rem;
  padding: 0.65rem;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.025);
}

.npc-form-section h4 {
  margin: 0;
  color: #f2f5fa;
  font-size: 0.78rem;
  letter-spacing: 0.035em;
  text-transform: uppercase;
}

.npc-form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.55rem;
}

.npc-interaction-hint { margin: 0; line-height: 1.35; }

.npc-interaction-summary {
  display: grid;
  gap: 0.15rem;
  padding: 0.5rem 0.6rem;
  border-left: 3px solid #8fb8ff;
  border-radius: 4px;
  background: rgba(93, 145, 231, 0.1);
}

.npc-interaction-summary strong { color: #f2f5fa; font-size: 0.82rem; }
.npc-interaction-summary span { color: #b8c0ce; font-size: 0.76rem; }

.map-event-list { display: grid; gap: 0.55rem; }
.map-event-summary, .map-event-empty { margin: 0; }
.map-event-search { width: 100%; }
.map-event-items { display: grid; gap: 0.3rem; }
.map-event-row {
  position: relative;
  display: grid;
  grid-template-columns: 1.65rem minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.45rem 0.5rem;
  text-align: left;
  background: rgba(255, 255, 255, 0.025);
}
.map-event-row:hover { background: rgba(111, 164, 255, 0.1); }
.map-event-row--issue-error { border-color: rgba(255, 120, 110, 0.55); }
.map-event-row--issue-warning { border-color: rgba(240, 190, 85, 0.5); }
.map-event-issue-count {
  position: absolute;
  top: 0.2rem;
  right: 0.2rem;
  min-width: 1rem;
  height: 1rem;
  padding: 0 0.2rem;
  border-radius: 999px;
  color: #201014;
  background: #ff8a79;
  font-size: 0.62rem;
  font-weight: 800;
  line-height: 1rem;
  text-align: center;
}
.map-event-row--issue-warning .map-event-issue-count { background: #efc35e; }
.map-event-kind {
  display: grid;
  place-items: center;
  width: 1.55rem;
  height: 1.55rem;
  border-radius: 50%;
  color: #e9effa;
  background: #55647a;
  font-size: 0.7rem;
  font-weight: 800;
}
.map-event-row--trainer .map-event-kind { background: #9b5c5c; }
.map-event-row--pickup .map-event-kind { background: #89712e; }
.map-event-row--service .map-event-kind { background: #397b62; }
.map-event-row--script .map-event-kind { background: #68569b; }
.map-event-row--sign .map-event-kind { background: #6f624d; }
.map-event-row--warp .map-event-kind { background: #356c91; }
.map-event-row--start .map-event-kind { background: #37734d; }
.map-event-copy { display: grid; min-width: 0; gap: 0.1rem; }
.map-event-copy strong, .map-event-copy span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.map-event-copy strong { color: #edf2fa; font-size: 0.78rem; }
.map-event-copy span, .map-event-coords { color: #929eaf; font-size: 0.7rem; }
.map-event-coords { padding-right: 0.75rem; }
.map-event-legend { display: flex; flex-wrap: wrap; gap: 0.3rem 0.55rem; }
.map-event-legend-item { display: inline-flex; align-items: center; gap: 0.25rem; color: #9ba7b8; font-size: 0.66rem; }
.map-event-legend-item .map-event-kind { width: 1.1rem; height: 1.1rem; font-size: 0.55rem; }
.map-event-issues {
  margin: 0.65rem;
  padding: 0.6rem;
  border: 1px solid rgba(255, 120, 110, 0.5);
  border-radius: 5px;
  background: rgba(119, 39, 45, 0.16);
  color: #f3dadd;
  font-size: 0.75rem;
}
.map-event-issues ul { margin: 0.35rem 0 0; padding-left: 1.1rem; }
.map-event-issue--warning { color: #f0cb82; }

@media (max-width: 760px) {
  .npc-form-grid { grid-template-columns: 1fr; }
}

.npc-form input,
.npc-form select,
.npc-form textarea {
  font: inherit;
  padding: 0.35rem 0.45rem;
  border-radius: 4px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  background: rgba(0, 0, 0, 0.25);
  color: inherit;
}

/* Chromium on Windows can ignore an inherited dark canvas when it opens a
   native select, leaving the option text and popup almost the same colour. */
.npc-form select {
  color-scheme: dark;
  color: #edf1f7;
  background-color: #121824;
}

.npc-form select option,
.npc-form select optgroup {
  color: #edf1f7;
  background-color: #171e2a;
}

.npc-form select option:disabled { color: #8792a5; }

.npc-form textarea {
  min-height: 4.5rem;
  resize: vertical;
}

.npc-form-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-top: 0.25rem;
}

.npc-form-actions button {
  font: inherit;
  padding: 0.35rem 0.65rem;
  border-radius: 4px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  background: rgba(255, 255, 255, 0.06);
  color: inherit;
  cursor: pointer;
}

.npc-form-actions button:hover {
  background: rgba(255, 255, 255, 0.12);
}

.encounter-map-list {
  list-style: none;
  padding: 0;
  margin: 0.35rem 0 0;
}

.encounter-map-list a {
  color: inherit;
  text-decoration: none;
}

.encounter-map-list a:hover {
  text-decoration: underline;
}

/* Where the editor's data comes from: the Python server, or a folder opened in
   the browser. Styled like the build button because it sits beside it and does
   the same kind of thing -- it changes what the editor is working on. */
.project-source {
  font: inherit;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  background: rgba(255, 255, 255, 0.06);
  color: inherit;
  cursor: pointer;
  max-width: 12rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The project menu: which game the editor is working on, and the others it
   knows about. Same split-button shape as Play, one row up. */
.project-group { position: relative; display: inline-flex; }

.project-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 60;
  min-width: 15rem;
  max-width: 22rem;
  display: flex;
  flex-direction: column;
  padding: 4px;
  gap: 1px;
  background: var(--panel, #1c2230);
  border: 1px solid var(--border, #343c50);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}

.project-menu[hidden] { display: none; }

/* Open toolbar menus live in the viewport layer. This lets them escape a
   horizontally scrollable work bar instead of being cut off at its bottom. */
.project-menu.is-floating {
  position: fixed;
  right: auto;
  z-index: 1000;
}

.project-menu-label {
  padding: 5px 8px 3px;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted, #8b95a8);
}

.project-menu-sep {
  height: 1px;
  margin: 4px 0;
  background: var(--border, #343c50);
}

.project-row { display: flex; align-items: center; gap: 2px; }

.app-header .project-menu button {
  height: auto;
  padding: 7px 10px;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: inherit;
  font-size: 12px;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.app-header .project-menu .project-pick { flex: 1 1 auto; min-width: 0; }

/* Forgetting is not deleting, so it is quiet until you go looking for it. */
.app-header .project-menu .project-forget {
  flex: 0 0 auto;
  padding: 7px 8px;
  opacity: 0;
  color: var(--muted, #8b95a8);
}

.project-row:hover .project-forget { opacity: 1; }

.app-header .project-menu button:hover {
  background: rgba(255, 255, 255, 0.09);
}

.app-header .project-menu .project-forget:hover {
  background: rgba(255, 122, 107, 0.18);
  color: var(--danger, #ff7a6b);
}

.app-header .project-menu .is-open {
  color: var(--accent, #6eb5ff);
  font-weight: 600;
}

.project-source:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.12);
}

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

/* A folder is open, so reads and writes are not reaching the server. Worth
   showing at a glance: it changes what Save means. */
.project-source.is-local {
  border-color: rgba(120, 220, 160, 0.6);
  background: rgba(120, 220, 160, 0.12);
}

/* The cartridge, playing in the page.
 *
 * Pixel art at an integer scale and nothing else: `image-rendering` here is
 * not a preference, it is the difference between the art as drawn and a
 * blurred approximation of it.
 */
/* This stylesheet has no blanket `.hidden` rule -- every element that hides
   declares it, as .dirty-dot and .rom-build-log-wrap do above. Missing this
   was why Stop appeared to do nothing twice over: the loop really had stopped
   and the canvas really was cleared, and the panel sat there regardless. */
.emu-panel.hidden,
#btn-emu-play.hidden { display: none; }

.emu-panel {
  /* Placed by emulator.js -- centred on first show, then wherever it is
     dragged -- so no corner is nailed down here. */
  position: fixed;
  left: 50%;
  top: 50%;
  z-index: 40;
  background: #0b0d12;
  border: 1px solid #2a3142;
  border-radius: 6px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6);
}

.emu-bar {
  cursor: move;
  user-select: none;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.35rem 0.5rem;
  font-size: 11px;
  color: #9aa4b8;
}

.emu-keys { margin-left: auto; opacity: 0.7; }

#emu-screen {
  display: block;
  width: 512px;
  height: 448px;
  image-rendering: pixelated;
  background: #000;
  outline: none;
}

#emu-screen:focus { box-shadow: inset 0 0 0 2px #3b82f6; }

/* The splash and the welcome screen.
 *
 * Both sit over everything and both are built in JS, so what is here is only
 * what CSS is better at: the layering, the frame, and the one animation.
 *
 * Colours are literal, like the rest of this file. The palette is the dark
 * chrome the editor already uses (#0d1017 ground, #9aa4b8 secondary text),
 * with the brand's amber for the thing you are meant to press.
 */

.splash {
  position: fixed;
  inset: 0;
  z-index: 9000;
  display: grid;
  place-items: center;
  align-content: center;
  gap: 18px;
  background: #0d1017;
  transition: opacity 200ms ease;
}

.splash.is-leaving { opacity: 0; }

/* Text-free artwork, per the design system. It is a wide band, so it is
   covered and centred rather than stretched -- a 4.7:1 image scaled to fill a
   tall window would be unrecognisable. */
.splash-art {
  position: absolute;
  inset: 0;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  opacity: 0.35;
  filter: saturate(0.9);
}

.splash-crest {
  position: relative;
  width: min(420px, 60vw);
  height: auto;
  filter: drop-shadow(0 6px 24px rgba(0, 0, 0, 0.6));
}

.splash-minimal .splash-crest { width: min(260px, 40vw); }
.splash-minimal .splash-art { opacity: 0.18; }

.splash-info {
  position: relative;
  width: min(420px, 70vw);
  text-align: center;
  color: #9aa4b8;
  font-size: 12px;
}

.splash-stage { margin: 0 0 8px; }

.splash-bar {
  height: 6px;
  border-radius: 3px;
  background: #1b2130;
  overflow: hidden;
}

.splash-bar-fill {
  height: 100%;
  width: 0;
  border-radius: 3px;
  background: linear-gradient(90deg, #f0a92b, #f5c95a);
  transition: width 160ms ease;
}

/* No percentage to show: sweep instead of inventing one. */
.splash-bar.is-indeterminate .splash-bar-fill {
  width: 35%;
  animation: splash-sweep 1.1s ease-in-out infinite;
}

@keyframes splash-sweep {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(300%); }
}

/* Visible to a screen reader, not to the eye: the stage text above already
   says it, and showing it twice is clutter. */
.splash-live {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  .splash { transition: none; }
  .splash-bar.is-indeterminate .splash-bar-fill { animation: none; width: 100%; }
}

/* ---------------------------------------------------------------- welcome */

.welcome {
  position: fixed;
  inset: 0;
  z-index: 9100;
  display: grid;
  place-items: center;
  background: rgba(6, 8, 12, 0.82);
  backdrop-filter: blur(3px);
}

.welcome-panel {
  position: relative;
  width: min(560px, 92vw);
  max-height: 92vh;
  overflow: auto;
  padding: 28px 28px 22px;
  border: 1px solid #232a3a;
  border-radius: 12px;
  background: #11151f;
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.55);
  text-align: center;
}

.welcome-crest {
  width: min(300px, 62%);
  height: auto;
  margin: 0 auto 18px;
  display: block;
}

.welcome-actions {
  display: grid;
  gap: 8px;
  text-align: left;
}

.welcome-action {
  display: block;
  width: 100%;
  padding: 10px 12px;
  border: 1px solid #262f42;
  border-radius: 8px;
  background: #161c28;
  color: #e6eaf2;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.welcome-action:hover { border-color: #3a4560; background: #1a2130; }
.welcome-action:focus-visible { outline: 2px solid #f0a92b; outline-offset: 2px; }

.welcome-action-name { display: block; font-weight: 600; }

.welcome-action-hint {
  display: block;
  margin-top: 2px;
  color: #8d97ab;
  font-size: 11px;
}

.welcome-form {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: end;
  gap: 10px;
  margin: 12px 0 0;
  padding: 12px;
  border: 1px solid #262f42;
  border-radius: 8px;
  background: #0f1420;
  text-align: left;
}

.welcome-field { display: grid; gap: 4px; font-size: 11px; color: #8d97ab; }
.welcome-seed-row { display: flex; gap: 6px; }

.welcome-seed,
.welcome-cities {
  min-width: 0;
  padding: 6px 8px;
  border: 1px solid #2b3448;
  border-radius: 6px;
  background: #0b0f18;
  color: #e6eaf2;
  font: inherit;
}

.welcome-cities { width: 72px; }

.welcome-dice {
  padding: 6px 10px;
  border: 1px solid #2b3448;
  border-radius: 6px;
  background: #161c28;
  color: #e6eaf2;
  cursor: pointer;
}

.welcome-make {
  padding: 7px 16px;
  border: 0;
  border-radius: 6px;
  background: #f0a92b;
  color: #1a1206;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.welcome-recents { margin-top: 18px; text-align: left; }

.welcome-recents-label {
  margin: 0 0 6px;
  color: #8d97ab;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.welcome-recent {
  display: block;
  width: 100%;
  padding: 6px 10px;
  border: 0;
  border-radius: 6px;
  background: none;
  color: #cdd5e4;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.welcome-recent:hover { background: #1a2130; }

.welcome-tip {
  margin: 18px 0 0;
  color: #7f899d;
  font-size: 11px;
  line-height: 1.5;
  text-align: left;
}

.welcome-status { margin: 10px 0 0; min-height: 1em; color: #9aa4b8; font-size: 11px; }
.welcome-status.is-bad { color: #ef8b7a; }

.welcome.is-busy .welcome-actions,
.welcome.is-busy .welcome-form { opacity: 0.5; pointer-events: none; }

.welcome-dismiss {
  position: absolute;
  top: 8px;
  right: 10px;
  border: 0;
  background: none;
  color: #8d97ab;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

/* -------------------------------------------------------------------------
   Unified studio finish

   The three workspaces grew at different times. These final, shared rules are
   intentionally loaded last: they turn the existing controls into one visual
   language without changing the ids and DOM contracts their scripts use.
   ------------------------------------------------------------------------- */

:root {
  color-scheme: dark;
  --bg: #0d1119;
  --panel: #141a25;
  --panel2: #1b2331;
  --panel3: #222c3d;
  --canvas-void: #0a0e15;
  --text: #edf1f7;
  --muted: #98a5b9;
  --muted-strong: #b8c2d1;
  --accent: #73b7ff;
  --accent-strong: #3d8fe8;
  --accent-soft: rgba(69, 151, 239, 0.16);
  --warn: #f2b35d;
  --danger: #f17d75;
  --ok: #72d69a;
  --border: #2a3547;
  --border-strong: #3b4960;
  --radius-sm: 5px;
  --radius: 7px;
  --radius-lg: 10px;
  --shadow-menu: 0 14px 38px rgba(0, 0, 0, 0.48);
  --shadow-focus: 0 0 0 3px rgba(115, 183, 255, 0.2);
}

body {
  background:
    radial-gradient(circle at 50% -20%, rgba(59, 109, 172, 0.08), transparent 42%),
    var(--bg);
}

::selection { background: rgba(115, 183, 255, 0.3); color: var(--text); }
* { scrollbar-color: #39475d transparent; scrollbar-width: thin; }

button,
select,
input,
textarea { font-family: var(--font-ui); }

button,
select,
input[type="search"],
input[type="text"],
input[type="number"],
textarea {
  border-color: var(--border);
  border-radius: var(--radius-sm);
}

button { transition: color 120ms ease, background 120ms ease, border-color 120ms ease; }
button:hover:not(:disabled) { border-color: var(--border-strong); background-color: var(--panel3); }
button.primary {
  color: #fff;
  background: linear-gradient(180deg, #397fd0, #2868b2);
  border-color: #4b91de;
  box-shadow: inset 0 1px rgba(255, 255, 255, 0.12);
}
button.primary:hover:not(:disabled) { background: linear-gradient(180deg, #468fdc, #3275c3); }

:where(button, select, input, textarea, a):focus-visible {
  outline: 2px solid var(--accent) !important;
  outline-offset: 2px !important;
  box-shadow: var(--shadow-focus);
}

.app-bar {
  min-height: 42px;
  padding: 6px 12px;
  background: rgba(17, 23, 34, 0.96);
}

.work-bar {
  min-height: 40px;
  padding: 5px 12px;
  flex-wrap: nowrap;
  overflow-x: auto;
  background: rgba(22, 29, 42, 0.96);
}

.app-header button,
.app-header select,
.app-header .project-source { height: 30px; }

.smce-mark {
  width: 19px;
  height: 19px;
  border-radius: 5px;
  background:
    linear-gradient(135deg, rgba(255,255,255,.25), transparent 45%),
    linear-gradient(140deg, #69aff8, #9b82ef);
  box-shadow: 0 0 0 1px rgba(255,255,255,.08), 0 3px 12px rgba(61,143,232,.2);
}

.editor-shell-brand { color: var(--text); font-weight: 650; }
.editor-shell-tab { height: 29px; color: var(--muted-strong); opacity: 0.78; }
.editor-shell-tab.active {
  color: var(--text);
  background: var(--panel3);
  border-color: var(--border-strong);
  box-shadow: inset 0 -2px var(--accent);
}

.doc-breadcrumb { flex: 0 1 auto; }
.doc-meta { color: #8491a5; }
.header-chrome { flex: 0 0 auto; }
.header-chrome .toolbar { align-items: center; flex-wrap: nowrap; }
.rom-actions { margin-left: 2px; }

.save-state {
  padding: 0 9px;
  line-height: 22px;
  background: rgba(255,255,255,.025);
}

.project-menu {
  border-color: var(--border-strong);
  background: #171e2a;
  box-shadow: var(--shadow-menu);
}

.layout-switcher {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding-left: 9px;
  margin-left: 5px;
  border-left: 1px solid var(--border);
}

.layout-toggle {
  height: 28px !important;
  padding: 0 8px !important;
  color: var(--muted);
  background: transparent;
}

.layout-toggle[aria-pressed="true"] {
  color: var(--text);
  border-color: var(--border-strong);
  background: var(--panel3);
}

.status-bar {
  height: 27px;
  color: var(--muted);
  background: #111722;
  border-color: var(--border);
}

/* Panel visibility uses zero-width grid tracks. The panes are hidden instead
   of removed, preserving their current selections and scroll positions. */
body.layout-map-list-hidden #main { --list-track: 0px; }
body.layout-palette-hidden #main { --palette-track: 0px; }
body.layout-context-hidden #main { --context-track: 0px; }
body.layout-map-list-hidden #panel-maps-list,
body.layout-palette-hidden #panel-palette,
body.layout-context-hidden #panel-context { display: none !important; }

body.layout-db-nav-hidden .db-layout { --db-nav-track: 0px; }
body.layout-db-list-hidden .db-layout { --db-list-track: 0px; }
body.layout-db-nav-hidden #ws-database .nav-panel,
body.layout-db-list-hidden #ws-database .list-panel { display: none !important; }

body.layout-theme-roles-hidden .theme-layout { --theme-roles-track: 0px; }
body.layout-theme-roles-hidden .theme-roles-panel { display: none !important; }

/* World */
#ws-maps #main { background: var(--canvas-void); }
#ws-maps .panel {
  background: rgba(14, 19, 28, 0.9);
  border-color: var(--border);
}

#ws-maps .panel-head,
#ws-database .panel-head,
#ws-themes .panel-head {
  min-height: 39px;
  padding: 7px 11px;
  background: #171e2a;
  border-color: var(--border);
  flex-wrap: nowrap;
}

#ws-maps .panel-head h2,
#ws-database .panel-head h2,
#ws-themes .panel-head h2 {
  color: var(--muted-strong);
  font-size: 12px;
  letter-spacing: .015em;
}

#ws-maps .scroll { padding: 9px; }
#ws-maps .map-list .map-item {
  margin-bottom: 5px;
  padding: 8px 9px;
  border-width: 1px;
  border-color: transparent;
  background: #192130;
}
#ws-maps .map-list .map-item:hover { background: #1e2838; border-color: var(--border-strong); }
#ws-maps .map-list .map-item.selected {
  background: linear-gradient(90deg, rgba(61,143,232,.2), rgba(61,143,232,.08));
  border-color: var(--accent);
  box-shadow: inset 3px 0 var(--accent);
}

#ws-maps #paint-bar,
#ws-maps #view-bar {
  min-height: 42px;
  padding: 6px 12px;
  background: #151c28;
  border-color: var(--border);
  overflow-x: auto;
  flex-wrap: nowrap;
}

/* #view-bar owns a menu that must escape the toolbar and sit over the canvas. */
#ws-maps #view-bar { overflow: visible; }

#ws-maps #paint-bar .tool[aria-pressed="true"],
#ws-maps #view-bar .tool.active,
#ws-maps #paint-bar .tool.active {
  background: var(--accent-soft);
  border-color: var(--accent);
  box-shadow: inset 0 -2px var(--accent);
}

#ws-maps .map-canvas-wrap {
  padding: 20px;
  background:
    radial-gradient(circle at center, rgba(39, 51, 70, .28), transparent 62%),
    var(--canvas-void);
}
#map-canvas-host { box-shadow: 0 12px 36px rgba(0,0,0,.35); }

#palette-sub,
#palette-tabs,
#palette-recent { background: #121824; border-color: var(--border); }
#context-form-host { padding-bottom: 24px; }
#context-form-host > form,
#context-form-host > section,
#context-form-host > div { border-color: var(--border); }

/* Data */
#ws-database { font-family: var(--font-ui); font-size: 13px; }
#ws-database .db-layout { background: var(--canvas-void); }
#ws-database .panel { background: #101620; border-color: var(--border); }
#ws-database .nav-panel { grid-column: 1; }
#ws-database .list-panel { grid-column: 2; }
#ws-database .detail-panel { grid-column: 3; }
#ws-database .nav-panel { background: #111722; }
#ws-database .nav-group-label { color: #77869c; padding-top: 13px; }
#ws-database .nav-item { min-height: 34px; color: #a1aec1; }
#ws-database .nav-item.active {
  color: var(--text);
  background: var(--accent-soft);
  border-color: rgba(115,183,255,.32);
  box-shadow: inset 3px 0 var(--accent);
}

#ws-database .list-card {
  margin-bottom: 5px;
  border-width: 1px;
  border-color: transparent;
  background: #192130;
}
#ws-database .list-card:hover { background: #1e2838; border-color: var(--border-strong); }
#ws-database .list-card.active {
  background: linear-gradient(90deg, rgba(61,143,232,.22), rgba(61,143,232,.09));
  border-color: var(--accent);
  box-shadow: inset 3px 0 var(--accent);
}

#ws-database .detail-panel { background: var(--bg); }
#ws-database #db-detail { padding: 18px 20px 40px; }
#ws-database .detail-header { margin-bottom: 18px; }
#ws-database .detail-header h2 { font-size: 22px; letter-spacing: -.015em; }
#ws-database .detail-card {
  padding: 16px 18px;
  border-color: var(--border);
  border-radius: var(--radius-lg);
  background: #192130;
  box-shadow: 0 1px 0 rgba(255,255,255,.02);
}
#ws-database .detail-card-title { color: #91a8d4; }
#ws-database .field label { color: #93a1b6; }
#ws-database .matrix-wrap {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: #121824;
}
#ws-database .matrix { min-width: max-content; }
#ws-database .matrix th { position: sticky; top: 0; z-index: 2; }
#ws-database .matrix th:first-child,
#ws-database .matrix td:first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  background: #171e2a;
}
#ws-database .matrix th:first-child { z-index: 3; }

/* Themes */
#ws-themes { min-height: 0; background: var(--bg); }
.theme-bar {
  min-height: 49px;
  gap: 10px;
  padding: 7px 12px;
  background: #121824;
  border-color: var(--border);
  opacity: 1;
}
.theme-bar label,
#ws-themes .panel-head label {
  color: var(--muted);
  font-size: 11px;
}
.theme-bar-actions { padding-left: 10px; border-left: 1px solid var(--border); }
.theme-layout {
  flex: 1;
  min-height: 0;
  height: auto;
  gap: 8px;
  padding: 8px;
  grid-template-rows: minmax(220px, .72fr) minmax(280px, 1.28fr);
  background: var(--canvas-void);
}
#ws-themes .panel {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: #101620;
}
.theme-preview .scroll {
  padding: 12px;
  background: radial-gradient(circle at top left, rgba(49,65,89,.3), transparent 60%);
}
.theme-role {
  padding: 7px 8px;
  background: #171f2c;
  border-color: var(--border);
}
.theme-role:hover { background: #1e2838; border-color: var(--border-strong); }
.theme-role.active {
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: inset 3px 0 var(--accent);
}
.theme-pair { gap: 1px; background: var(--border); }
.theme-pair-side { background: #0e141e; }
.theme-pair-side h3,
.theme-pair-side-head { min-height: 28px; color: var(--muted-strong); }

/* Onboarding */
.welcome { background: rgba(5, 8, 13, .88); backdrop-filter: blur(8px); }
.welcome-panel {
  width: min(600px, 92vw);
  padding: 26px 30px 24px;
  border-color: var(--border-strong);
  background: linear-gradient(180deg, #151c28, #101620);
  box-shadow: 0 32px 90px rgba(0,0,0,.65);
  text-align: left;
}
.welcome-crest { width: min(250px, 52%); margin-bottom: 14px; }
.welcome-intro { text-align: center; margin-bottom: 20px; }
.welcome-kicker,
.welcome-section-label {
  color: #89a1cb;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.welcome-title { margin: 6px 0 5px; font-size: 22px; letter-spacing: -.02em; }
.welcome-lede { margin: 0; color: var(--muted); font-size: 12px; }
.welcome-section-label { margin: 0 0 7px; }
.welcome-actions { grid-template-columns: 1fr 1fr; }
.welcome-action {
  min-height: 68px;
  padding: 11px 12px;
  border-color: var(--border);
  background: #192130;
}
.welcome-action:hover { border-color: var(--accent); background: #1f2a3b; }
.welcome-action:first-child { background: linear-gradient(145deg, rgba(61,143,232,.2), #192130 68%); }
.welcome-action-hint { line-height: 1.35; }
.welcome-tip { padding-top: 13px; border-top: 1px solid var(--border); }

@media (max-width: 1180px) {
  .doc-meta { display: none; }
  .work-bar { gap: 6px; }
  .layout-toggle { font-size: 11px !important; padding-inline: 6px !important; }
  #ws-database #db-detail { padding: 14px 16px 32px; }
  .theme-layout { grid-template-columns: minmax(0, 1fr) var(--theme-roles-track, 240px); }
}

@media (max-width: 760px) {
  .editor-shell-brand { display: none; }
  .app-bar-right { margin-left: auto; }
  .welcome-actions { grid-template-columns: 1fr; }
  .welcome-form { grid-template-columns: 1fr auto; }
  .welcome-form .welcome-make { grid-column: 1 / -1; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { scroll-behavior: auto !important; transition-duration: .01ms !important; }
}
.project-menu-help {
  max-width: 22rem;
  margin: .5rem 0 0;
  color: var(--muted, #9aa3ad);
  font-size: .75rem;
  line-height: 1.35;
}

.appearance-source-card {
  max-width: 22rem;
  margin-top: .65rem;
  padding: .55rem .65rem;
  border: 1px solid var(--border, #3b4149);
  border-radius: 5px;
  color: var(--muted, #9aa3ad);
  font-size: .75rem;
  line-height: 1.45;
}

.appearance-summary-heading {
  display: block;
  padding: .15rem .25rem .45rem;
  color: var(--text, #e7edf7);
  font-size: .72rem;
  letter-spacing: .04em;
  text-transform: uppercase;
}

.app-header .project-menu .appearance-summary-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: .45rem;
  width: 100%;
  padding: .48rem .35rem;
  color: inherit;
  text-align: left;
}

.appearance-summary-copy,
.appearance-summary-title {
  display: flex;
  min-width: 0;
}

.appearance-summary-copy { flex-direction: column; gap: .1rem; }
.appearance-summary-title { justify-content: space-between; gap: .65rem; }
.appearance-summary-title strong { color: var(--text, #e7edf7); }
.appearance-summary-title > span,
.appearance-summary-copy small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.appearance-summary-state {
  padding: .08rem .3rem;
  border: 1px solid color-mix(in srgb, var(--ok, #72d29a) 45%, transparent);
  border-radius: 999px;
  color: var(--ok, #72d29a);
  font-size: .63rem;
  text-transform: uppercase;
}

.appearance-summary-state.is-bad {
  color: var(--danger, #ff7a6b);
  border-color: color-mix(in srgb, var(--danger, #ff7a6b) 45%, transparent);
}

.appearance-summary-arrow { color: var(--muted, #9aa3ad); font-size: 1rem; }

.npc-character-preview {
  display: block;
  max-width: 100%;
  max-height: 8rem;
  margin: .35rem 0 .75rem;
  object-fit: contain;
  object-position: left center;
  image-rendering: pixelated;
  border: 1px solid var(--border, #3b4149);
  border-radius: 4px;
  background: repeating-conic-gradient(#20252b 0 25%, #282e35 0 50%) 0 / 12px 12px;
}

.npc-script-badge--missing {
  color: var(--danger, #f28b82);
}
