/* editor.css — the shell around the game (index.html): the top bar, the code
   editor on the left, the frame the game runs in on the right. The game's own
   look is in zot.css; the colors here match it. */

:root {
  --shell-bg: #0e0e16;
  --shell-panel: #181826;
  --shell-line: #2c2c40;
  --shell-text: #e6e6f0;
  --shell-dim: #8a8aa0;
  --shell-focus: #4a7dff;
  --shell-run: #7ee08a;
  --shell-font: "Menlo", "Consolas", "DejaVu Sans Mono", monospace;
}

html, body { height: 100%; margin: 0; }
body {
  background: var(--shell-bg);
  color: var(--shell-text);
  font-family: var(--shell-font);
  font-size: 14px;
}

/* The page is exactly one screen tall: the bar on top, the panes fill the rest */
#shell {
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh;
}

.bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  flex: none;
  min-height: 44px;
  padding: 6px 12px;
  box-sizing: border-box;
  background: var(--shell-panel);
  border-bottom: 1px solid var(--shell-line);
}
.brand { font-weight: bold; margin-right: 8px; letter-spacing: 0.04em; color: inherit; text-decoration: none; }
.brand:hover { text-decoration: underline; }  /* the GitHub repo, in a new tab */
.brand:focus-visible { outline: 2px solid var(--shell-focus); outline-offset: 2px; }
.spacer { flex: 1 1 0; }  /* pushes Save, Load, Download and Share to the right */
.bar select, .bar button {
  height: 28px;
  padding: 0 10px;
  box-sizing: border-box;
  border: 1px solid var(--shell-line);
  border-radius: 4px;
  background: var(--shell-bg);
  color: var(--shell-text);
  font: inherit;
  cursor: pointer;
}
/* "Edited" or "Unsaved changes" after the dropdown, with a dot in One Dark's yellow */
.edited { color: var(--shell-dim); font-size: 12px; white-space: nowrap; cursor: default; }
.edited::before { content: "\25cf"; margin-right: 5px; color: #e5c07b; }
.edited[hidden] { display: none; }
/* The seed box: dim while it shows the seed of the dungeon running, bright
   once a seed is typed in and every Run plays it */
.seed { display: flex; align-items: center; gap: 6px; color: var(--shell-dim); font-size: 12px; }
.seed input {
  width: 7em;
  height: 28px;
  padding: 0 8px;
  box-sizing: border-box;
  border: 1px solid var(--shell-line);
  border-radius: 4px;
  background: var(--shell-bg);
  color: var(--shell-dim);
  font: inherit;
  font-size: 13px;
}
.seed input.pinned { color: var(--shell-text); border-color: var(--shell-dim); }
.seed input:read-only { border-style: dashed; cursor: default; }
.seed input:hover { border-color: var(--shell-dim); }
.seed input:focus-visible { outline: 2px solid var(--shell-focus); outline-offset: 1px; }
.seed input::placeholder { color: var(--shell-dim); opacity: 0.6; }
.bar select:hover, .bar button:hover { border-color: var(--shell-dim); }
.bar select:focus-visible, .bar button:focus-visible { outline: 2px solid var(--shell-focus); outline-offset: 1px; }

/* Edit is a switch: a track with a knob that slides right and turns blue
   while the editor is shown */
.bar .toggle {
  position: relative;
  padding-left: 40px;
}
.bar .toggle::before, .bar .toggle::after {
  content: "";
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  border-radius: 999px;
  transition: left 0.15s, background 0.15s;
}
.bar .toggle::before { left: 8px; width: 24px; height: 12px; background: var(--shell-line); }  /* the track */
.bar .toggle::after { left: 10px; width: 8px; height: 8px; background: var(--shell-dim); }     /* the knob */
.bar .toggle[aria-pressed="true"]::before { background: var(--shell-focus); }
.bar .toggle[aria-pressed="true"]::after { left: 22px; background: var(--shell-text); }
/* The speaker button at the right end: dim while the game is muted */
.bar .sound { padding: 0 7px; font-size: 16px; line-height: 1; }
.bar .sound[aria-pressed="false"] { opacity: 0.5; }
.bar .sound[hidden] { display: none; }
.bar .primary, .notice .primary, dialog .primary { border-color: var(--shell-run); color: var(--shell-run); }
.bar .primary:hover, .notice .primary:hover, dialog .primary:hover { background: var(--shell-run); color: var(--shell-bg); }

/* The editor and the frame side by side. Each pane has a top edge that lights
   up when its side has the keyboard, so it is clear where keys go: WASD in the
   editor types, WASD in the frame moves the hero. */
.panes {
  flex: 1 1 auto;
  display: flex;
  min-height: 0;
}
#editor, #stage {
  border: 0;
  border-top: 2px solid transparent;
  box-sizing: border-box;
}
#editor {
  /* The width is the dragged one (--editor-width, set by the handle below and
     remembered between visits), or half the page up to 720px; either way the
     code keeps at least 240px and the game at least 320px */
  flex: 0 0 clamp(240px, var(--editor-width, min(50%, 720px)), 100% - 320px);
  display: flex;
  flex-direction: column;
  position: relative;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  border-right: 1px solid var(--shell-line);
  background: #282c34;  /* the One Dark background, so the pane matches the editor while it loads */
}
/* Edit slides the pane open and closed: the basis goes to nothing and the
   frame grows into the room. Closed, the pane is inert (editor.js), so Tab
   skips it. The slide only runs once the page is up (#shell.ready), so a
   page that opens with the editor shown doesn't start by sliding it out. */
#shell.ready #editor { transition: flex-basis 0.25s ease, border-width 0.25s ease; }
#editor.closed { flex-basis: 0; border-width: 0; }
@media (prefers-reduced-motion: reduce) {
  #shell.ready #editor { transition: none; }
}
/* The handle on the pane's right edge: drag it to set the width, double-click
   it to go back to the default, or focus it and use the arrow keys. It lights
   up while hovered or dragged. */
.gutter {
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  width: 6px;
  cursor: col-resize;
  z-index: 2;
}
.gutter:hover, .gutter:focus-visible, #shell.resizing .gutter { background: var(--shell-focus); opacity: 0.6; outline: none; }
#shell.resizing { cursor: col-resize; user-select: none; }
#shell.resizing #editor { transition: none; }
#shell.resizing #frame { pointer-events: none; }  /* so the drag isn't lost to the game's page */
#stage {
  flex: 1 1 auto;
  position: relative;
  min-width: 0;
  background: var(--shell-bg);
}
#frame {
  display: block;
  border: 0;
  width: 100%;
  height: 100%;
  background: var(--shell-bg);
}
#shell.editor-focused #editor { border-top-color: var(--shell-focus); }
#shell.frame-focused #stage { border-top-color: var(--shell-focus); }

/* The click-to-run notice sits over the (empty) frame */
.notice {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 24px;
  text-align: center;
  background: var(--shell-bg);
}
.notice[hidden] { display: none; }
.notice p { max-width: 36em; margin: 0; line-height: 1.5; }
.notice button {
  height: 36px;
  padding: 0 20px;
  border: 1px solid var(--shell-line);
  border-radius: 4px;
  background: var(--shell-bg);
  color: var(--shell-text);
  font: inherit;
  font-size: 15px;
  cursor: pointer;
}

/* The Save, Load and Share dialogs */
dialog {
  width: min(32em, calc(100vw - 32px));
  padding: 20px;
  border: 1px solid var(--shell-line);
  border-radius: 6px;
  background: var(--shell-panel);
  color: var(--shell-text);
  font: inherit;
  box-sizing: border-box;
}
dialog::backdrop { background: rgba(0, 0, 0, 0.6); }
dialog h2 { margin: 0 0 12px; font-size: 16px; }
dialog label { display: flex; align-items: center; gap: 8px; }
dialog input[type="text"], dialog textarea {
  flex: 1 1 auto;
  padding: 6px 8px;
  border: 1px solid var(--shell-line);
  border-radius: 4px;
  background: var(--shell-bg);
  color: var(--shell-text);
  font: inherit;
  font-size: 13px;
  box-sizing: border-box;
}
dialog textarea { width: 100%; resize: none; word-break: break-all; }
dialog input:focus-visible, dialog textarea:focus-visible, dialog button:focus-visible { outline: 2px solid var(--shell-focus); outline-offset: 1px; }
dialog .hint { margin: 10px 0 0; color: var(--shell-dim); font-size: 12px; line-height: 1.5; }
dialog menu {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin: 16px 0 0;
  padding: 0;
}
dialog menu button, #save-list button {
  height: 28px;
  padding: 0 10px;
  border: 1px solid var(--shell-line);
  border-radius: 4px;
  background: var(--shell-bg);
  color: var(--shell-text);
  font: inherit;
  cursor: pointer;
}
dialog menu button:hover, #save-list button:hover { border-color: var(--shell-dim); }

/* One row per saved game: its name and date, then Load and Delete */
#save-list {
  max-height: 50vh;
  margin: 0;
  padding: 0;
  overflow: auto;
  list-style: none;
}
#save-list li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 0;
  border-bottom: 1px solid var(--shell-line);
}
#save-list .name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#save-list .when { flex: none; color: var(--shell-dim); font-size: 12px; }
#save-list .delete { color: var(--shell-dim); }
#save-list .delete:hover { border-color: #e06c75; color: #e06c75; }

/* CodeMirror fills what the bar leaves of its pane and scrolls inside it */
#editor .cm-editor { flex: 1 1 auto; min-height: 0; font-size: 13px; }
#editor .cm-editor.cm-focused { outline: none; }
#editor .cm-scroller { overflow: auto; font-family: var(--shell-font); }

/* Dark scrollbars on the editor, like the log's in zot.css: Chrome and Safari
   take the ::-webkit-scrollbar rules, Firefox scrollbar-color */
#editor .cm-scroller::-webkit-scrollbar { width: 10px; height: 10px; }
#editor .cm-scroller::-webkit-scrollbar-track, #editor .cm-scroller::-webkit-scrollbar-corner { background: #282c34; }
#editor .cm-scroller::-webkit-scrollbar-thumb { background: #3e4451; border-radius: 5px; border: 2px solid #282c34; }
#editor .cm-scroller::-webkit-scrollbar-thumb:hover { background: var(--shell-dim); }
@supports not selector(::-webkit-scrollbar) {
  #editor .cm-scroller { scrollbar-color: #3e4451 #282c34; }
}

/* The mistake bar over the editor, and the line it points at: a tinted
   background and a dot by the number. The red is One Dark's. */
.problem {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex: none;
  padding: 6px 10px;
  background: #3a1f24;
  color: #f0c4c9;
  border-bottom: 1px solid #e06c75;
  font-size: 12px;
  line-height: 1.5;
}
.problem[hidden] { display: none; }
.problem .text { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.problem .where, .problem .close {
  flex: none;
  padding: 0 6px;
  border: 1px solid #e06c75;
  border-radius: 4px;
  background: transparent;
  color: #e06c75;
  font: inherit;
  cursor: pointer;
}
.problem .where:hover, .problem .close:hover { background: #e06c75; color: var(--shell-bg); }
.problem .where[hidden] { display: none; }
.problem .close { border-color: transparent; font-size: 14px; }
.cm-problem-line { background: rgba(224, 108, 117, 0.18); }
.cm-problem-number { color: #e06c75; }
.cm-problem-dot { margin-right: 4px; }

/* A square of the sheet after tile: [12, 4], and a swatch after color: "lime".
   The sheet is white shapes, so the square is a mask over the color. See swatches.js */
.cm-tile, .cm-swatch {
  display: inline-block;
  width: 16px;
  height: 16px;
  margin-left: 6px;
  vertical-align: -3px;
  cursor: pointer;
}
.cm-tile {
  mask-image: url("tiles/tiles.png");
  -webkit-mask-image: url("tiles/tiles.png");
  mask-size: auto;
  -webkit-mask-size: auto;
  image-rendering: pixelated;
}
.cm-swatch { border-radius: 3px; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.25); }
.cm-tile:hover, .cm-swatch:hover { outline: 1px solid var(--shell-focus); outline-offset: 1px; }

/* The tile picker: the whole sheet at twice its size, in light gray, that scrolls.
   The current square is white with a steady frame; the square under the mouse has a bright one.
   As wide as the whole sheet when the window has room, so it only scrolls on small screens */
.tile-picker { width: fit-content; max-width: calc(100vw - 32px); }
.tile-scroll {
  max-height: calc(100vh - 220px);
  overflow: auto;
  padding: 8px;
  background: var(--shell-bg);
  border: 1px solid var(--shell-line);
  border-radius: 4px;
}
.tile-scroll::-webkit-scrollbar { width: 10px; height: 10px; }
.tile-scroll::-webkit-scrollbar-track, .tile-scroll::-webkit-scrollbar-corner { background: var(--shell-bg); }
.tile-scroll::-webkit-scrollbar-thumb { background: #3e3e58; border-radius: 5px; border: 2px solid var(--shell-bg); }
.tile-scroll::-webkit-scrollbar-thumb:hover { background: var(--shell-dim); }
@supports not selector(::-webkit-scrollbar) {
  .tile-scroll { scrollbar-color: #3e3e58 var(--shell-bg); }
}
.tile-sheet { position: relative; image-rendering: pixelated; cursor: crosshair; }
.tile-image { background: #9a9aa6; }
.tile-active, .tile-current, .tile-cursor {
  position: absolute;
  box-sizing: border-box;
  pointer-events: none;
}
.tile-active { background: #ffffff; }
.tile-current { border: 2px solid var(--shell-run); }
.tile-cursor { border: 2px solid var(--shell-focus); }
.tile-active[hidden], .tile-current[hidden], .tile-cursor[hidden] { display: none; }
.tile-hint { display: flex; align-items: center; gap: 12px; min-height: 48px; }
.tile-preview { flex: none; image-rendering: pixelated; }

/* The browser's color picker opens from an input that sits under the swatch, unseen */
.color-picker {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

/* On a phone the panes stack: the editor above, the game below */
@media (max-width: 720px) {
  .panes { flex-direction: column; }
  #stage { min-height: 0; }
  #editor {
    flex: 0 0 50%;
    border-right: 0;
    border-bottom: 1px solid var(--shell-line);
  }
  .gutter { display: none; }
}
