/* The standalone playground uses the same palette as docs/public/nupp.css.
   In particular, editor surfaces use the normal code-block background and
   borders use the normal code-block border instead of a playground-only
   approximation. */
:root {
  color-scheme: light;
  --pg-accent: #768d93;
  --pg-accent-hover: color-mix(in srgb, #768d93 80%, black);
  --pg-accent-soft: #f1e1df;
  --pg-button: #768d93;
  --pg-button-hover: color-mix(in srgb, #768d93 80%, black);
  --pg-button-text: #ffffff;
  --pg-background: #fcfbfb;
  --pg-background-alt: #f0ebe7;
  --pg-border: color-mix(in srgb, #50676c 70%, white);
  --pg-code-block-radius: 4px;
  --pg-code-background: #e6eaec;
  --pg-text: #2e2f2a;
  --pg-muted: #594a4f;
  --pg-faint: color-mix(in srgb, var(--pg-muted) 90%, transparent);
  --pg-error: #cf222e;
  --pg-warning: #836620;
  --pg-info: #768d93;
  --pg-syntax-keyword: #9a1600;
  --pg-syntax-boolean: #836620;
  --pg-syntax-string: #364c31;
  --pg-syntax-comment: #474c44;
  --pg-syntax-number: #836620;
  --pg-syntax-function: #376076;
  --pg-syntax-meta: #2e595c;
  --pg-syntax-type: #2e595c;
  --pg-syntax-operator: #2e595c;
  --pg-syntax-property: var(--pg-syntax-variable);
  --pg-syntax-punctuation: #3c5156;
  --pg-syntax-variable: #6e5032;
  --pg-font: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --pg-font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --pg-accent: #d64a3b;
    --pg-accent-hover: color-mix(in srgb, #d64a3b 85%, white);
    --pg-accent-soft: #161214;
    --pg-button: #d64a3b;
    --pg-button-hover: color-mix(in srgb, #d64a3b 85%, white);
    --pg-button-text: #000000;
    --pg-background: #1c1917;
    --pg-background-alt: #1b2626;
    --pg-border: #38312d;
    --pg-code-background: #1f1c1b;
    --pg-text: #d4c2b6;
    --pg-muted: #ad9277;
    --pg-faint: color-mix(in srgb, var(--pg-muted) 45%, transparent);
    --pg-error: #ff7b72;
    --pg-warning: #f9cd5f;
    --pg-info: #d64a3b;
    --pg-syntax-keyword: #fa745c;
    --pg-syntax-boolean: #f9cd5f;
    --pg-syntax-string: #9eb798;
    --pg-syntax-comment: #747673;
    --pg-syntax-number: #f9cd5f;
    --pg-syntax-function: #93aab7;
    --pg-syntax-meta: #718e90;
    --pg-syntax-type: #718e90;
    --pg-syntax-operator: #718e90;
    --pg-syntax-property: var(--pg-syntax-variable);
    --pg-syntax-punctuation: #84a2aa;
    --pg-syntax-variable: #d3a87c;
  }
}

* { box-sizing: border-box; }

html, body {
  height: 100%;
  margin: 0;
}

body {
  display: flex;
  flex-direction: column;
  color: var(--pg-text);
  background: var(--pg-background);
  font-family: var(--pg-font);
}

.header {
  /* The options menu hangs off this. */
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 52px;
  padding: 0 1rem;
  border-bottom: 1px solid var(--pg-border);
  background: var(--pg-background);
  flex: none;
}

.brand {
  display: flex;
  align-items: center;
  gap: .5rem;
  color: var(--pg-text);
  font-weight: 700;
  text-decoration: none;
}

.brand-mark { display: block; }

.header-actions {
  display: flex;
  align-items: center;
  gap: .9rem;
}

.example-picker,
.dialect-picker {
  display: flex;
  align-items: center;
  gap: .45rem;
  color: var(--pg-muted);
  font-size: .8rem;
}
/* A class rule setting `display` outranks the user agent's own [hidden] rule,
   so hiding this from script needs saying here. */
.example-picker[hidden] { display: none; }

/* `appearance: none` would take the disclosure arrow with it, and nothing
   here wants to redraw one — this keeps the platform control and only
   restates the colors and metrics, so it stays a native menu on every
   platform. `color-scheme` on :root is what keeps the popup itself dark. */
.select {
  padding: .35rem 1.6rem .35rem .5rem;
  color: var(--pg-text);
  border: 1px solid var(--pg-border);
  border-radius: 7px;
  background: var(--pg-background-alt);
  font: inherit;
  font-size: .82rem;
  cursor: pointer;
}
.select:hover { border-color: var(--pg-accent); }
.select:focus-visible { outline: 2px solid var(--pg-accent); outline-offset: 1px; }

.is-busy .select { opacity: .55; pointer-events: none; }

.status {
  color: var(--pg-muted);
  font-size: .8rem;
  font-family: var(--pg-font-mono);
}

.status-error { color: var(--pg-error); }

.button {
  padding: .4rem .9rem;
  color: var(--pg-button-text);
  border: 1px solid color-mix(in srgb, var(--pg-button) 60%, white 15%);
  border-radius: 7px;
  background: var(--pg-button);
  font: inherit;
  font-weight: 600;
  font-size: .82rem;
  cursor: pointer;
}
.button:hover { background: var(--pg-button-hover); }

.is-busy .button { opacity: .55; pointer-events: none; }

/* index.html only: the editor on the left, the output panel down the right
   side. The panel is made of the same pieces as the embed's drawer further
   down this file; what this page changes is the direction each one runs,
   which is why its rules hang off `.shell` — an element only this page has —
   rather than off a modifier class the embed would have to know not to set. */
.shell {
  display: flex;
  flex-direction: row;
  flex: 1;
  min-height: 0;
}

.panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
}

.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 34px;
  padding: 0 .9rem;
  color: var(--pg-muted);
  border-bottom: 1px solid var(--pg-border);
  background: var(--pg-background-alt);
  font-family: var(--pg-font-mono);
  font-size: .74rem;
  flex: none;
}
.panel-head-note { margin-left: auto; }

.editor-host {
  flex: 1;
  min-height: 0;
  overflow: auto;
}

.editor-host .cm-editor { height: 100%; }
.editor-host .cm-scroller { font-family: var(--pg-font-mono); font-size: 13.5px; }

.diagnostics {
  margin: 0;
  padding: 0;
  list-style: none;
  overflow: auto;
}

.diagnostic {
  display: grid;
  grid-template-columns: auto auto 1fr;
  gap: .5rem;
  padding: .55rem .9rem;
  border-bottom: 1px solid var(--pg-border);
  font-size: .8rem;
  cursor: pointer;
}
.diagnostic:hover { background: var(--pg-background-alt); }

.diagnostic-loc {
  color: var(--pg-muted);
  font-family: var(--pg-font-mono);
  font-size: .74rem;
}

.diagnostic-code {
  color: var(--pg-muted);
  font-family: var(--pg-font-mono);
  font-size: .74rem;
}

.diagnostic-error .diagnostic-code { color: var(--pg-error); }
.diagnostic-warning .diagnostic-code { color: var(--pg-warning); }

.diagnostic-msg { grid-column: 1 / -1; }
.diagnostic-error .diagnostic-msg,
.diagnostic-warning .diagnostic-code + .diagnostic-msg { grid-column: 3; }

.diagnostic-help {
  grid-column: 1 / -1;
  margin-top: .2rem;
  color: var(--pg-muted);
  font-size: .76rem;
}

.diagnostic-empty {
  padding: 1.5rem;
  color: var(--pg-muted);
  text-align: center;
  font-size: .82rem;
}

.footer {
  padding: .5rem 1rem;
  color: var(--pg-muted);
  border-top: 1px solid var(--pg-border);
  background: var(--pg-background-alt);
  font-size: .72rem;
  flex: none;
}
.footer a { color: var(--pg-accent); }

/* embed.html: the editor between a head bar and an output drawer, meant to sit
   inside an <iframe> — no side panel or footer. A plain flex column, since the
   drawer changes height and the editor takes what is left. */
.is-embed {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.is-embed .editor-host .cm-scroller { font-size: 13px; }
.is-embed .editor-host .cm-content { padding: .5rem 0; }
.is-embed #source-editor {
  overflow: hidden;
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-code-block-radius);
}

.head-bar {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: .6rem;
  height: 2rem;
  padding: 0 0 .2rem;
  border: 0;
  background: transparent;
  flex: none;
}
.head-bar .example-picker { font-size: .72rem; }
.head-bar .select {
  padding: .18rem 1.4rem .18rem .4rem;
  font-size: .74rem;
}

.head-actions {
  display: flex;
  align-items: center;
  gap: .1rem;
  margin-left: auto;
}

/* One shape for every icon control on both pages. The glyphs are inline SVG
   drawn on a 16-unit grid and stroked rather than filled, except the play
   triangle, which has no outline to speak of. */
.icon-button {
  display: grid;
  width: 26px;
  height: 26px;
  padding: 0;
  place-items: center;
  color: var(--pg-muted);
  border: 0;
  border-radius: 6px;
  background: transparent;
  cursor: pointer;
}
.icon-button:hover { color: var(--pg-text); background: var(--pg-code-background); }
.icon-button.is-active { color: var(--pg-accent); background: var(--pg-code-background); }
.icon-button:focus-visible { outline: 2px solid var(--pg-accent); outline-offset: -2px; }
.icon-button svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.icon-button svg path[d^="M4.5"] { fill: currentColor; stroke: none; }

.is-busy .icon-button { opacity: .55; pointer-events: none; }
/* The first Run gesture also starts an embed's deferred worker. Keep that
   gesture alive when startWorker marks the page busy; compileNow disables the
   button itself until the request finishes. */
.is-embed.is-busy #compile-button:not(:disabled) { opacity: 1; pointer-events: auto; }
.icon-button:disabled { opacity: .55; pointer-events: none; cursor: default; }

/* Anchored under the button that opens it. Absolute rather than in flow so
   opening it does not move the editor down. */
.options-panel {
  position: absolute;
  z-index: 20;
  top: calc(100% + .3rem);
  right: .35rem;
  display: flex;
  width: 17rem;
  flex-direction: column;
  gap: .55rem;
  padding: .65rem .7rem;
  border: 1px solid var(--pg-border);
  border-radius: 8px;
  background: var(--pg-background);
  box-shadow: 0 6px 20px rgb(0 0 0 / .18);
}
.options-panel[hidden] { display: none; }

.options-row {
  display: flex;
  align-items: flex-start;
  gap: .5rem;
  cursor: pointer;
}
.options-row input { margin: .15rem 0 0; accent-color: var(--pg-accent); }
.options-text { display: flex; flex-direction: column; gap: .1rem; }
.options-name { color: var(--pg-text); font-size: .78rem; font-weight: 600; }
.options-hint { color: var(--pg-muted); font-size: .7rem; line-height: 1.35; }

/* Run reveals the output drawer. Collapsed after that, it is one bar saying
   what the compiler said; expanded it is that answer in full, with the
   diagnostics list beside it — a clean compile can still carry warnings. */
.output {
  display: flex;
  flex-direction: column;
  min-height: 0;
  border-top: 1px solid var(--pg-border);
  background: var(--pg-background-alt);
  flex: none;
}
.output[hidden] { display: none; }
/* 40% until someone drags it; see app.js, which then sets an inline size. */
.output.is-open { flex: 0 1 40%; }

/* The grab strip, just before the pane it sizes. It carries no line of its
   own: that pane's existing 1px border stays the divider, so collapsing the
   pane — which takes this strip away — does not take the divider with it. Six
   pixels, because a one-pixel target is a target you miss. */
.output-resizer {
  height: 6px;
  background: transparent;
  cursor: ns-resize;
  flex: none;
  /* Or a touch drag scrolls the page instead of moving the pane. */
  touch-action: none;
}
.output-resizer[hidden] { display: none; }
.output-resizer:hover,
.output-resizer.is-dragging { background: var(--pg-accent-soft); }
.output-resizer:focus-visible { outline: 2px solid var(--pg-accent); outline-offset: -2px; }

.output-head {
  display: flex;
  width: 100%;
  align-items: center;
  gap: .45rem;
  height: 1.9rem;
  padding: 0 .6rem;
  color: var(--pg-muted);
  border: 0;
  background: transparent;
  font: inherit;
  font-size: .74rem;
  text-align: left;
  /* Collapsed, index.html's panel is only as wide as this bar, so the bar
     must not answer that by wrapping itself narrower still. */
  white-space: nowrap;
  cursor: pointer;
  flex: none;
}
.output-head:hover { color: var(--pg-text); }
.output-caret { display: inline-block; font-size: .62rem; transition: transform 120ms ease; }
.output.is-open .output-caret { transform: rotate(90deg); }
.output-title { font-weight: 600; }
.output-summary {
  margin-left: auto;
  color: var(--pg-muted);
  font-family: var(--pg-font-mono);
  font-size: .7rem;
}
.output-summary.is-error { color: var(--pg-error); }

.output-body {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  min-height: 0;
  border-top: 1px solid var(--pg-border);
  background: var(--pg-code-background);
  flex: 1;
}
.output-body[hidden] { display: none; }

.output-main {
  overflow: auto;
  min-height: 0;
  margin: 0;
  padding: .55rem .7rem;
  color: var(--pg-text);
  font-family: var(--pg-font-mono);
  font-size: .74rem;
  line-height: 1.5;
  /* Diagnostics wrap; generated code overrides this to preserve Lua lines. */
  white-space: pre-wrap;
}
/* Generated Lua reads as code; a diagnostic run reads as a report. */
.output-main:not(.is-code) { color: var(--pg-muted); }
.output-main.is-code {
  padding-inline: 0;
  white-space: pre;
}
.output-main .lua-line {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
}
.output-main .lua-line-number {
  min-width: 2.75rem;
  padding: 0 .65rem;
  color: var(--pg-faint);
  text-align: right;
  user-select: none;
}
.output-main .lua-line-code {
  min-width: 0;
  padding-right: .7rem;
}
.output-main .lua-keyword { color: var(--pg-syntax-keyword); }
.output-main .lua-boolean { color: var(--pg-syntax-boolean); }
.output-main .lua-string { color: var(--pg-syntax-string); }
.output-main .lua-comment { color: var(--pg-syntax-comment); font-style: italic; }
.output-main .lua-number { color: var(--pg-syntax-number); }
.output-main .lua-type { color: var(--pg-syntax-type); }
.output-main .lua-operator { color: var(--pg-syntax-operator); }
.output-main .lua-property { color: var(--pg-syntax-property); }
.output-main .lua-punctuation { color: var(--pg-syntax-punctuation); }
.output-main .lua-variable { color: var(--pg-syntax-variable); }
.output-main .lua-builtin { color: var(--pg-syntax-function); }
.output-main .lua-meta { color: var(--pg-syntax-meta); }

.output-side {
  border-left: 1px solid var(--pg-border);
  background: var(--pg-background-alt);
}

@media (max-width: 620px) {
  .output-body { grid-template-columns: minmax(0, 1fr); }
  .output-side { border-left: 0; border-top: 1px solid var(--pg-border); }
}

/* index.html's arrangement of all of the above: the drawer stood up as a
   column beside the editor rather than under it, and its two panes stacked
   rather than side by side. Only the axes change — the collapse, the grab
   strips and their behaviour are the drawer's, unmodified. */

/* The editor is whatever the output panel leaves. Saying so is not optional
   in a row: a flex item left to itself is as wide as its content wants to be,
   and an editor's content is however long its longest line is — which would
   let a wide program take the panel's share away from it. */
.shell > .panel-source { flex: 1; }

.shell > .output {
  min-width: 0;
  border-top: 0;
  border-left: 1px solid var(--pg-border);
}
.shell > .output.is-open { flex: 0 1 38%; }
/* Collapsed, it is a strip naming what the compiler said: the width it was
   dragged to belongs to a panel that is showing something. app.js clears the
   dragged size to let this through, and puts it back on expand. */
.shell > .output:not(.is-open) { flex: none; }
.shell > .output-resizer {
  width: 6px;
  height: auto;
  cursor: ew-resize;
}

.shell .output-body {
  display: flex;
  flex-direction: column;
}
/* Restated because the rule above and the base `[hidden]` one are the same
   weight, and this file's order would otherwise hand it to the wrong one. */
.shell .output-body[hidden] { display: none; }
.shell .output-body > .editor-host { flex: 1; }
.shell .output-side {
  min-height: 0;
  border-left: 0;
  border-top: 1px solid var(--pg-border);
  flex: 0 1 40%;
}

/* Two columns need a window wide enough for both to be worth having; under
   that, the panel goes back to being the drawer it is made of. Its own two
   panes stay stacked, which is what fits when there is little width to give
   either. */
@media (max-width: 720px) {
  .shell { flex-direction: column; }
  .shell > .output {
    border-left: 0;
    border-top: 1px solid var(--pg-border);
  }
  .shell > .output.is-open { flex: 0 1 45%; }
  .shell > .output-resizer {
    width: auto;
    height: 6px;
    cursor: ns-resize;
  }
}

/* The editor's own colors (background, gutters, selection, syntax) are set
   properly via CodeMirror's theme API in src/cm-theme.js — an
   EditorView.theme extension, not loose CSS here — because loose overrides
   of .cm-* classes lose the specificity fight against the stylesheet
   basicSetup's default HighlightStyle injects. */

.cm-nupp-hover pre {
  margin: 0;
  padding: .2rem .75rem;
  color: var(--pg-text);
  font-family: var(--pg-font-mono);
  font-size: .72rem;
  line-height: 1.35;
  white-space: pre-wrap;
}
