/* Application layer on top of nocturne.css (the design system).
   Only app-specific pieces live here: the app shell, controls the design system
   does not ship, the highlight.js theme, and JSONEditor overrides. */

html, body { height: 100%; }
body { overflow: hidden; }

/* ── app shell ───────────────────────────────────────────────────────── */
.app {
  width: 100%; height: 100vh; display: flex; flex-direction: column;
  background: var(--color-bg); color: var(--color-text);
  font-family: var(--font-body, Inter, sans-serif);
}
.app-nav { flex: none; border-bottom: 1px solid var(--color-divider); }
.app-body { display: flex; flex: 1; min-height: 0; }

.app-side {
  width: 320px; flex: none; padding: var(--space-4); overflow-y: auto;
  display: flex; flex-direction: column; gap: var(--space-4);
}
.app-main {
  flex: 1; min-width: 0; display: flex; flex-direction: column;
  background: #ffffff;
  margin: var(--space-4) var(--space-4) var(--space-4) 0;
  border-radius: var(--radius-md); box-shadow: var(--shadow-sm); overflow: hidden;
}
.app-main-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-3) var(--space-6) 0;
  border-bottom: 1px solid var(--color-divider);
}
.app-main-body { flex: 1; overflow: auto; }

/* Stack on narrow screens rather than squeezing the 320px rail. */
@media (max-width: 860px) {
  body { overflow: auto; }
  .app { height: auto; }
  .app-body { flex-direction: column; }
  .app-side { width: auto; }
  .app-main { margin: 0 var(--space-4) var(--space-4); min-height: 60vh; }
}

/* ── language chips ──────────────────────────────────────────────────── */
/* Real radios so the form posts without JavaScript; the input is visually
   hidden and the label carries the appearance. */
.lang-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.lang-chip { position: relative; display: block; cursor: pointer; }
.lang-chip input {
  position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none;
}
.lang-chip span {
  display: flex; align-items: center; justify-content: center;
  padding: 7px 0; font-size: 11px; letter-spacing: 0.02em;
  border-radius: calc(var(--radius-md) * 0.75);
  border: 1px solid var(--color-accent); color: var(--color-accent);
}
.lang-chip:hover span { background: color-mix(in srgb, var(--color-accent) 10%, transparent); }
.lang-chip input:checked + span {
  background: var(--color-accent-800); border-color: var(--color-accent-800);
  color: var(--color-accent-100);
}
.lang-chip input:focus-visible + span { outline: 2px solid var(--color-accent); outline-offset: 2px; }

/* The less-used languages sit behind a native disclosure, so the whole control
   works with JavaScript off.
   <summary> must come first in the DOM, but the toggle reads better pinned
   below the chips it reveals, so the two are swapped visually with flex order
   rather than by scripting. */
.lang-more { display: flex; flex-direction: column; }
.lang-more > .lang-grid { order: 1; }
.lang-more > summary { order: 2; }
/* Belt and braces: some older engines render a details' content regardless of
   [open] once it is given a non-block display. Redundant where they do not. */
.lang-more:not([open]) > .lang-grid { display: none; }

.lang-more > summary {
  list-style: none; cursor: pointer; user-select: none;
  margin-top: var(--space-2); font-size: 12px;
  color: var(--color-accent);
}
.lang-more > summary::-webkit-details-marker { display: none; }
.lang-more > summary:hover { text-decoration: underline; text-underline-offset: 3px; }
.lang-more > summary:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.lang-more > .lang-grid { margin-top: var(--space-2); }
.lang-more .lang-more-hide { display: none; }
.lang-more[open] .lang-more-show { display: none; }
.lang-more[open] .lang-more-hide { display: inline; }

/* ── toggle switches ─────────────────────────────────────────────────── */
.switch {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 12.5px; cursor: pointer; gap: var(--space-3);
}
.switch input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.switch .track {
  width: 32px; height: 18px; border-radius: 9px; position: relative;
  display: inline-block; flex: none; background: var(--color-neutral-700);
  transition: background 120ms ease;
}
.switch .knob {
  width: 14px; height: 14px; border-radius: 50%; background: #ffffff;
  position: absolute; top: 2px; left: 2px; transition: left 120ms ease;
}
.switch input:checked + .track { background: var(--color-accent); }
.switch input:checked + .track .knob { left: 16px; }
.switch input:focus-visible + .track { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.switch.is-disabled { opacity: 0.4; cursor: not-allowed; }

/* ── attribute radios ────────────────────────────────────────────────── */
/* Drawn as the design's square boxes, but single-select: these options are
   mutually exclusive, and "None" is a real choice that changes generator
   behaviour, so a checkbox group would misrepresent them. */
.attr-list { display: flex; flex-direction: column; gap: 8px; }
.attr {
  display: flex; align-items: center; gap: 8px;
  font-size: 12.5px; color: var(--color-text); cursor: pointer;
}
.attr input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.attr .box {
  width: 15px; height: 15px; border-radius: 4px; flex: none;
  border: 1.5px solid var(--color-neutral-500);
  display: flex; align-items: center; justify-content: center;
}
.attr .box svg { display: none; width: 9px; height: 9px; color: #ffffff; }
.attr input:checked + .box { background: var(--color-accent); border-color: var(--color-accent); }
.attr input:checked + .box svg { display: block; }
.attr input:focus-visible + .box { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.attr-list.is-disabled { opacity: 0.4; }
.attr-list.is-disabled .attr { cursor: not-allowed; }

/* Disabled inputs across the rail read consistently. */
.input:disabled { opacity: 0.4; cursor: not-allowed; }

/* ── tabs ────────────────────────────────────────────────────────────── */
.tab {
  padding: 10px 16px; font-size: 13px; cursor: pointer; background: none;
  border: 0; border-bottom: 2px solid transparent; font-family: inherit;
  color: color-mix(in srgb, var(--color-text) 60%, transparent);
}
.tab:hover { color: var(--color-text); }
.tab.active { color: var(--color-text); border-bottom-color: var(--color-accent); }
.tab-panel { display: none; height: 100%; }
.tab-panel.active { display: block; }

/* ── generated code ──────────────────────────────────────────────────── */
.code-pane { padding: var(--space-8) var(--space-6); }
.code-pane pre { margin: 0; }
.code-pane code {
  font-family: ui-monospace, "JetBrains Mono", "Cascadia Mono", Consolas, monospace;
  font-size: 14px; line-height: 1.7; background: none; padding: 0;
}

/* highlight.js theme, tuned to the design's accent rather than a stock theme. */
.hljs { background: transparent; color: var(--color-neutral-900); }
.hljs-keyword, .hljs-built_in, .hljs-literal, .hljs-type {
  color: var(--color-accent-700); font-weight: 500;
}
.hljs-title, .hljs-title.class_, .hljs-title.function_, .hljs-meta {
  color: var(--color-neutral-900); font-weight: 500;
}
.hljs-string, .hljs-number { color: #8a6d3b; }
.hljs-comment { color: var(--color-neutral-500); font-style: italic; }
.hljs-attr, .hljs-attribute, .hljs-property, .hljs-variable { color: var(--color-neutral-800); }
.hljs-punctuation, .hljs-operator { color: var(--color-neutral-700); }

/* ── alerts ──────────────────────────────────────────────────────────── */
.alert {
  display: flex; align-items: flex-start; gap: var(--space-3);
  padding: var(--space-3) var(--space-4); margin-bottom: var(--space-4);
  border-radius: var(--radius-md); font-size: 13px;
  background: color-mix(in srgb, #d9534f 12%, var(--color-surface));
  border: 1px solid color-mix(in srgb, #d9534f 45%, transparent);
  color: var(--color-text);
}
.alert svg { flex: none; margin-top: 2px; color: #d9534f; }

/* ── copy button feedback ────────────────────────────────────────────── */
.copy-ok { color: #4a9d5f !important; }

/* ── JSONEditor: light surface, design typography ────────────────────── */
.jsoneditor { border: none !important; height: 100%; }
.jsoneditor-menu {
  background: var(--color-neutral-200) !important;
  border-bottom: 1px solid var(--color-neutral-300) !important;
}
.jsoneditor-menu button { color: var(--color-neutral-900); }
.jsoneditor-outer, .jsoneditor-tree, .jsoneditor-text {
  font-family: ui-monospace, "JetBrains Mono", Consolas, monospace !important;
  font-size: 13px !important;
}
.jsoneditor-frame, .jsoneditor-search input { background: #ffffff; }
.editor-host { height: 100%; min-height: 320px; }

/* ── static pages ────────────────────────────────────────────────────── */
.page {
  max-width: 760px; margin: 0 auto; padding: var(--space-8) var(--space-6);
  overflow-y: auto;
}
.page h1 { font-size: 28px; margin-bottom: var(--space-4); }
.page p { color: color-mix(in srgb, var(--color-text) 75%, transparent); }
