/* Terrazed — dark, dense, tool-like. The terrain is the bright thing on
   screen; the chrome stays out of its way. */

:root {
  --bg: #0b0e13;
  --bg-panel: #11151c;
  --bg-raised: #171c25;
  --bg-input: #0d1117;
  --border: #232a35;
  --border-strong: #313a48;
  --text: #e6eaf0;
  --text-dim: #9aa4b2;
  --text-faint: #6b7583;
  --accent: #6ee7b7;
  --accent-dim: #34d399;
  --accent-ink: #05231a;
  --danger: #f87171;
  --warn: #fbbf24;
  --radius: 7px;
  --radius-sm: 5px;
  --font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

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

body {
  background: var(--bg);
  color: var(--text);
  font: 14px/1.5 var(--font);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

a { color: var(--accent); }
a:hover { color: var(--accent-dim); }

h2, h3 { margin: 0; font-weight: 600; }
hr { border: none; border-top: 1px solid var(--border); margin: 16px 0; }

.muted { color: var(--text-dim); }
.small { font-size: 12px; }
.mono { font-family: var(--mono); }
.warn { color: var(--warn); }
.spacer { flex: 1; }
.pad { padding: 8px 10px; }
.grow { flex: 1; }
.span-2 { grid-column: 1 / -1; }

/* ------------------------------------------------------------------ header */

.app-header {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 14px;
  height: 52px;
  background: var(--bg-panel);
  border-bottom: 1px solid var(--border);
  flex: 0 0 auto;
}

.brand {
  display: flex;
  align-items: center;
  gap: 9px;
  font-weight: 650;
  letter-spacing: -0.01em;
  color: var(--text);
}

.brand-mark {
  width: 24px;
  height: 24px;
  color: var(--accent);
}

.project-name {
  flex: 0 1 280px;
  background: var(--bg-input);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: 6px 10px;
  font-size: 13px;
}

.header-actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* ---------------------------------------------------------------- beta */

/* Always present next to the wordmark, so the beta status is stated even after
   the banner below has been dismissed. */
.beta-badge {
  font-family: var(--mono);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.14em;
  padding: 2px 6px 2px 7px;
  border-radius: 3px;
  color: var(--accent-ink);
  background: linear-gradient(135deg, var(--warn), #f59e0b);
  box-shadow: 0 0 0 1px rgba(251, 191, 36, 0.35), 0 0 12px rgba(251, 191, 36, 0.25);
  align-self: center;
  user-select: none;
}

.beta-banner {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 16px;
  flex: 0 0 auto;
  background:
    linear-gradient(90deg, rgba(251, 191, 36, 0.10), rgba(251, 191, 36, 0.02) 55%, transparent),
    var(--bg-panel);
  border-bottom: 1px solid var(--border);
  overflow: hidden;
}

/* A slow sheen travelling along the top edge — enough to read as "unfinished,
   in motion" without the blinking-marquee energy of a typical beta bar. */
.beta-banner::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--warn), transparent);
  animation: beta-sweep 5s ease-in-out infinite;
}

@keyframes beta-sweep {
  0%, 100% { transform: translateX(-60%); opacity: 0.35; }
  50% { transform: translateX(60%); opacity: 1; }
}

.beta-banner-tag {
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.16em;
  color: var(--warn);
  border: 1px solid rgba(251, 191, 36, 0.45);
  border-radius: 3px;
  padding: 3px 8px;
  flex: 0 0 auto;
}

.beta-banner-text {
  margin: 0;
  font-size: 12px;
  line-height: 1.45;
  color: var(--text-dim);
  flex: 1;
  min-width: 0;
}
.beta-banner-text strong { color: var(--text); font-weight: 600; }

.beta-banner[hidden] { display: none; }

/* -------------------------------------------------------------- app layout */

.app-body {
  flex: 1;
  display: grid;
  --left-width: 320px;
  --right-width: 340px;
  grid-template-columns: var(--left-width) minmax(0, 1fr) var(--right-width);
  min-height: 0;
}

/* Collapsing is just a width change, so the stage reflows into the space. */
.app-body.left-collapsed { --left-width: 0px; }
.app-body.right-collapsed { --right-width: 0px; }
.app-body.left-collapsed .panel-left,
.app-body.right-collapsed .panel-right { border: none; }

.panel {
  background: var(--bg-panel);
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

.panel-left { border-right: 1px solid var(--border); }
.panel-right { border-left: 1px solid var(--border); }

.panel-scroll {
  overflow-y: auto;
  overscroll-behavior: contain;
  flex: 1;
  min-height: 0;
}

.panel-section {
  padding: 14px;
  border-bottom: 1px solid var(--border);
}

.panel-heading {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-faint);
  margin-bottom: 10px;
}

.panel-footer {
  padding: 14px;
  color: var(--text-faint);
  font-size: 11px;
  line-height: 1.6;
}
.panel-footer p { margin: 0 0 6px; }

/* --------------------------------------------------------------- the stage */

.stage {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  background: var(--bg);
}

.stage-bar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 8px 14px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-panel);
  flex: 0 0 auto;
}

.tabs { display: flex; gap: 2px; background: var(--bg-input); padding: 3px; border-radius: var(--radius); }

.tabs button {
  background: none;
  border: none;
  color: var(--text-dim);
  padding: 5px 13px;
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}
.tabs button:hover { color: var(--text); }
.tabs button.active { background: var(--bg-raised); color: var(--text); }

.stage-body {
  flex: 1;
  position: relative;
  min-height: 0;
}

.stage-pane {
  position: absolute;
  inset: 0;
}

#preview2d, #preview3d {
  width: 100%;
  height: 100%;
  display: block;
}

#preview3d { cursor: grab; }
#preview3d:active { cursor: grabbing; }

#preview2d { cursor: crosshair; touch-action: none; }
#preview2d.grabbing { cursor: grabbing; }

#zoom-level {
  font-family: var(--mono);
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}

/* Sits on top of terrain that can be any colour — snow and sand both defeat
   faint text on no background. Opaque enough to always read, dark enough to
   stay out of the way, and the same chip treatment as the zoom buttons so it
   looks deliberate rather than pasted on. */
.stage-hint {
  position: absolute;
  left: 12px;
  bottom: 12px;
  margin: 0;
  max-width: calc(100% - 24px);
  padding: 5px 10px;
  font-size: 11px;
  line-height: 1.4;
  color: var(--text-dim);
  background: rgba(13, 17, 23, 0.88);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  backdrop-filter: blur(6px);
  pointer-events: none;
}

/* A labelled toggle among the round icon buttons, so it needs its own width. */
.map-controls .mode-toggle {
  width: auto;
  min-width: 44px;
  padding: 0 10px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.map-controls .mode-toggle[aria-pressed='true'] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--bg);
}

.map-canvas { position: absolute; inset: 0; }

.stat-row { display: flex; gap: 18px; flex-wrap: wrap; }

.stat { display: flex; flex-direction: column; gap: 1px; }
.stat-label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-faint); }
.stat strong { font-size: 13px; font-weight: 600; }

.stat-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-top: 12px;
}

.count-list { display: flex; flex-wrap: wrap; gap: 4px; }
.count-pill {
  font-size: 11px;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 8px;
  color: var(--text-dim);
}

/* -------------------------------------------------------------- progress */

.progress {
  position: absolute;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 10px;
  background: rgba(11, 14, 19, 0.92);
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  padding: 7px 14px;
  backdrop-filter: blur(6px);
}

.progress-track {
  width: 160px;
  height: 4px;
  background: var(--bg-raised);
  border-radius: 999px;
  overflow: hidden;
}

.progress-bar {
  height: 100%;
  width: 0;
  background: var(--accent);
  transition: width 0.12s linear;
}

.progress-label { font-size: 12px; color: var(--text-dim); white-space: nowrap; }

/* --------------------------------------------------------------- controls */

.group { border-bottom: 1px solid var(--border); }

.group > summary {
  padding: 11px 14px;
  cursor: pointer;
  font-weight: 550;
  font-size: 13px;
  list-style: none;
  display: flex;
  align-items: center;
  user-select: none;
}
.group > summary::-webkit-details-marker { display: none; }
.group > summary::before {
  content: "›";
  display: inline-block;
  margin-right: 8px;
  color: var(--text-faint);
  transition: transform 0.15s ease;
}
.group[open] > summary::before { transform: rotate(90deg); }
.group > summary:hover { background: var(--bg-raised); }

.group-body { padding: 4px 14px 14px; }
.group-help { margin: 0 0 12px; font-size: 12px; color: var(--text-dim); }

.field { margin-bottom: 14px; }
.field:last-child { margin-bottom: 0; }
.field-inline { margin-bottom: 10px; }

.field-label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--text-dim);
  margin-bottom: 5px;
}

.field-help {
  margin: 5px 0 0;
  font-size: 11px;
  line-height: 1.45;
  color: var(--text-faint);
}

.row { display: flex; gap: 8px; align-items: center; }
.row > input[type="text"], .row > input[type="search"] { flex: 1; }

.mini {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  color: var(--text-faint);
}
.mini input { width: 100%; }

input[type="text"],
input[type="number"],
input[type="search"],
input[type="email"],
input[type="password"],
select {
  background: var(--bg-input);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: 6px 8px;
  font: inherit;
  font-size: 13px;
  width: 100%;
}

input:focus, select:focus, button:focus-visible {
  outline: 2px solid var(--accent-dim);
  outline-offset: 1px;
}

input.num {
  width: 74px;
  text-align: right;
  font-family: var(--mono);
  font-size: 12px;
  padding: 3px 6px;
}

input[type="range"] {
  width: 100%;
  accent-color: var(--accent);
  height: 18px;
}

input[type="color"] {
  width: 30px;
  height: 22px;
  padding: 0;
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  background: none;
  cursor: pointer;
}

.checkbox {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  cursor: pointer;
}
.checkbox input { width: auto; accent-color: var(--accent); }

.check-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  margin-bottom: 12px;
}

/* ----------------------------------------------------------------- chips */

.chips { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 8px; }

.chip {
  background: var(--bg-input);
  border: 1px solid var(--border);
  color: var(--text-dim);
  border-radius: 999px;
  padding: 4px 11px;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.chip:hover { border-color: var(--border-strong); color: var(--text); }
.chip.active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
}

/* --------------------------------------------------------------- buttons */

.btn {
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: 7px 13px;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  white-space: nowrap;
}
.btn:hover:not(:disabled) { border-color: var(--text-faint); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }

.btn-sm { padding: 5px 10px; font-size: 12px; }
.btn-block { display: block; width: 100%; margin-bottom: 8px; }

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
}
.btn-primary:hover:not(:disabled) { background: var(--accent-dim); border-color: var(--accent-dim); }

.btn.danger, .icon-btn.danger { color: var(--danger); }

.icon-btn {
  background: none;
  border: 1px solid transparent;
  color: var(--text-dim);
  border-radius: var(--radius-sm);
  width: 26px;
  height: 26px;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.icon-btn:hover:not(:disabled) { background: var(--bg-raised); color: var(--text); }
.icon-btn:disabled { opacity: 0.3; cursor: not-allowed; }

/* ------------------------------------------------------------- segmented */

.segmented {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3px;
  background: var(--bg-input);
  padding: 3px;
  border-radius: var(--radius);
}

.segmented label { position: relative; }
.segmented input { position: absolute; opacity: 0; pointer-events: none; }

.segmented span {
  display: block;
  text-align: center;
  padding: 6px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  color: var(--text-dim);
  cursor: pointer;
}
.segmented input:checked + span { background: var(--bg-raised); color: var(--text); font-weight: 550; }
.segmented input:focus-visible + span { outline: 2px solid var(--accent-dim); }

/* ---------------------------------------------------------------- layers */

.layer-list { display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; }

.layer {
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.layer.disabled { opacity: 0.5; }
.layer > summary { list-style: none; cursor: pointer; padding: 7px 9px; }
.layer > summary::-webkit-details-marker { display: none; }

.layer-header { display: flex; align-items: center; gap: 8px; }
.layer-tag {
  font-size: 10px;
  color: var(--text-faint);
  font-family: var(--mono);
  text-transform: uppercase;
}

.layer-body { padding: 4px 10px 10px; }

/* ------------------------------------------------------------------- map */

.map-root {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: #0d1117;
  cursor: grab;
  touch-action: none;
}
.map-root.dragging { cursor: grabbing; }

.map-tiles { position: absolute; inset: 0; }

.map-tile {
  position: absolute;
  top: 0;
  left: 0;
  width: 256px;
  height: 256px;
  user-select: none;
  pointer-events: none;
  /* OSM tiles are bright; take the edge off so the selection reads clearly. */
  filter: saturate(0.8) brightness(0.82);
}
.map-tile.failed { visibility: hidden; }

.map-overlay { position: absolute; inset: 0; pointer-events: none; }

.map-controls {
  position: absolute;
  top: 12px;
  right: 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.map-controls button {
  width: 30px;
  height: 30px;
  background: rgba(17, 21, 28, 0.92);
  border: 1px solid var(--border-strong);
  color: var(--text);
  border-radius: var(--radius-sm);
  font-size: 15px;
  cursor: pointer;
}
.map-controls button:hover { background: var(--bg-raised); }

.map-attribution {
  position: absolute;
  right: 6px;
  bottom: 4px;
  font-size: 10px;
  color: var(--text-dim);
  background: rgba(11, 14, 19, 0.75);
  padding: 2px 6px;
  border-radius: 3px;
}

/* --------------------------------------------------------------- search */

.search-wrap { position: relative; }

.search-results {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  max-height: 240px;
  overflow-y: auto;
  z-index: 20;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}

.search-result {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  padding: 8px 10px;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.search-result:hover { background: var(--bg-input); }
.search-result:last-child { border-bottom: none; }

/* ------------------------------------------------------------- provider */

.provider-note { margin-top: 8px; }
.provider-note p { margin: 0 0 5px; }

/* Licence is the thing people skip and later regret, so give it colour. */
.license {
  border-left: 2px solid var(--border-strong);
  padding-left: 8px;
  color: var(--text-dim);
}
.license-public-domain { border-left-color: var(--accent); }
.license-cc-by-nc-sa { border-left-color: var(--warn); }
.license-restricted { border-left-color: var(--danger); }

/* ------------------------------------------------------------- swatches */

.swatch-grid { display: flex; flex-direction: column; gap: 3px; }

.swatch {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 3px 4px;
  border-radius: 4px;
}
.swatch:hover { background: var(--bg-input); }
.swatch input[type="checkbox"] { width: auto; accent-color: var(--accent); }
.swatch-label { flex: 1; font-size: 12px; }
.swatch-count { font-size: 10px; color: var(--text-faint); font-family: var(--mono); }

/* --------------------------------------------------------------- modals */

.modal {
  background: var(--bg-panel);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  padding: 0;
  width: 90vw;
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6);
}
.modal::backdrop { background: rgba(5, 7, 10, 0.7); }

.modal-header {
  display: flex;
  align-items: center;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
}
.modal-header h2 { font-size: 15px; flex: 1; }

.modal-body { padding: 16px; max-height: 70vh; overflow-y: auto; }
.modal-body h3 { font-size: 13px; margin: 18px 0 8px; }
.modal-body h3:first-child { margin-top: 0; }

.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 12px 16px;
  border-top: 1px solid var(--border);
}

.form { display: flex; flex-direction: column; gap: 12px; }
.form label { display: flex; flex-direction: column; gap: 5px; font-size: 12px; color: var(--text-dim); }
.form-error { color: var(--danger); font-size: 12px; margin: 0; }

.verify-notice {
  border: 1px solid rgba(251, 191, 36, 0.35);
  border-left-width: 3px;
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  background: rgba(251, 191, 36, 0.06);
}
.verify-notice p { margin: 0 0 10px; color: var(--text-dim); line-height: 1.5; }
.verify-notice strong { color: var(--warn); }

.verified-ok { color: var(--accent); margin: 0; }

/* Quiet dot on the account button when the address is unconfirmed. */
.needs-attention { position: relative; }
.needs-attention::after {
  content: "";
  position: absolute;
  top: 3px;
  right: 3px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--warn);
  box-shadow: 0 0 0 2px var(--bg-panel);
}

.key-list { display: flex; flex-direction: column; gap: 14px; }
.key-row { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px; }
.key-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; }
.key-row p { margin: 0 0 8px; }

.project-list { display: flex; flex-direction: column; gap: 8px; }

.project-card {
  display: flex;
  align-items: center;
  gap: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 8px;
}
.project-thumb {
  width: 56px;
  height: 56px;
  border-radius: 4px;
  object-fit: cover;
  background: var(--bg-input);
}
.project-thumb.empty { border: 1px dashed var(--border-strong); }
.project-meta { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.project-meta strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------------------------------------------------------- task status */

.task-status {
  margin: 4px 0 12px;
  padding: 9px 10px;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.task-bar {
  height: 4px;
  background: var(--bg-raised);
  border-radius: 999px;
  overflow: hidden;
  margin-bottom: 7px;
}

.task-bar-fill {
  height: 100%;
  width: 0;
  background: var(--accent);
  border-radius: 999px;
  transition: width 0.2s ease;
}

/* No byte counts yet (still waiting on the upstream service): sweep instead of
   implying a percentage we do not know. */
.task-bar.indeterminate .task-bar-fill {
  width: 35%;
  animation: task-sweep 1.4s ease-in-out infinite;
}

@keyframes task-sweep {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(320%); }
}

.task-line {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 12px;
}

.task-phase { color: var(--text); }

.task-elapsed {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

.task-hint {
  margin: 6px 0 0;
  font-size: 11px;
  line-height: 1.45;
  color: var(--text-faint);
}

.task-status.done .task-bar-fill { background: var(--accent); }
.task-status.done .task-phase { color: var(--accent); }
.task-status.failed .task-bar-fill { background: var(--danger); }
.task-status.failed .task-phase { color: var(--danger); }

/* --------------------------------------------------------------- toasts */

.toast-host {
  position: fixed;
  right: 16px;
  bottom: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 100;
  max-width: min(420px, calc(100vw - 32px));
}

.toast {
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  border-left: 3px solid var(--text-faint);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  font-size: 13px;
  line-height: 1.45;
  cursor: pointer;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
  animation: toast-in 0.18s ease;
}
.toast-success { border-left-color: var(--accent); }
.toast-error { border-left-color: var(--danger); }
.toast-info { border-left-color: #60a5fa; }
.toast.leaving { opacity: 0; transform: translateX(12px); transition: 0.2s ease; }

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

.noscript {
  padding: 24px;
  text-align: center;
  color: var(--warn);
}

/* -------------------------------------------------------------- responsive */

@media (max-width: 1200px) {
  .app-body { --left-width: 280px; --right-width: 300px; }
  .app-body.left-collapsed { --left-width: 0px; }
  .app-body.right-collapsed { --right-width: 0px; }
}

@media (max-width: 980px) {
  body { overflow: auto; }
  .app-body {
    grid-template-columns: 1fr;
    grid-template-rows: auto 60vh auto;
  }
  .panel { max-height: 60vh; border: none; border-top: 1px solid var(--border); }
  .panel-left { order: 2; }
  .stage { order: 1; min-height: 60vh; }
  .panel-right { order: 3; }
  .project-name { flex-basis: 140px; }
}

/* Tablets and large phones. The header is the first thing to break: five
   buttons, a text field and the brand do not fit on one 52 px line. */
@media (max-width: 760px) {
  .app-header {
    height: auto;
    flex-wrap: wrap;
    padding: 8px 10px;
    gap: 8px;
  }
  .project-name {
    order: 3;
    flex: 1 1 100%;
    min-width: 0;
  }
  .header-actions {
    margin-left: auto;
    flex-wrap: wrap;
    gap: 6px;
  }

  .app-body { grid-template-rows: auto 52vh auto; }
  .stage { min-height: 52vh; }
  .panel { max-height: none; }

  /* Two columns of numbers at 360 px wide is four characters each. */
  .stat-grid,
  .check-grid { grid-template-columns: 1fr; }

  .row { flex-wrap: wrap; }
  .btn-block { width: 100%; }

  /* iOS zooms the whole page when a focused field is under 16px. */
  input,
  select,
  textarea { font-size: 16px; }
}

/* Phones. */
@media (max-width: 480px) {
  .app-header { padding: 8px; }
  .brand span:not(.beta-badge) { display: none; }
  .header-actions .btn { padding: 5px 9px; font-size: 12px; }

  .panel-body,
  .group-body { padding-left: 10px; padding-right: 10px; }

  .app-body { grid-template-rows: auto 45vh auto; }
  .stage { min-height: 45vh; }

  .beta-banner { flex-direction: column; align-items: flex-start; gap: 4px; }

  /* Nothing should be able to push the page sideways. */
  body { overflow-x: hidden; }
  .panel-scroll { overscroll-behavior: contain; }
}

/* Touch input, at any width: fingers need a bigger target than a mouse. */
@media (pointer: coarse) {
  .btn,
  .icon-btn,
  select,
  input[type='text'],
  input[type='number'] { min-height: 40px; }
  .btn-sm { min-height: 34px; }
  .checkbox { padding: 4px 0; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* ----------------------------------------------------- small-screen notice */

.device-notice {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(6, 9, 13, 0.94);
  backdrop-filter: blur(3px);
}
.device-notice[hidden] { display: none; }

.device-notice-card {
  max-width: 380px;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 22px;
  text-align: left;
}
.device-notice-card h2 {
  margin: 0 0 8px;
  font-size: 17px;
  font-weight: 650;
}
.device-notice-card p {
  margin: 0 0 12px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-dim);
}
.device-notice-card ul {
  margin: 0 0 16px;
  padding-left: 18px;
  font-size: 13px;
  line-height: 1.7;
  color: var(--text-dim);
}
.device-notice-card .btn { width: 100%; }
.device-notice-mark {
  width: 30px;
  height: 30px;
  color: var(--accent);
  margin-bottom: 10px;
}

/* ------------------------------------------------------- activity log */

.stage-footer {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 14px;
  border-top: 1px solid var(--border);
  background: var(--bg-panel);
  flex: 0 0 auto;
  min-height: 34px;
}

.footer-hint { font-size: 11px; color: var(--text-faint); }

.log-badge {
  display: inline-block;
  min-width: 16px;
  padding: 0 4px;
  margin-left: 4px;
  border-radius: 999px;
  background: var(--bg-raised);
  color: var(--text-dim);
  font-family: var(--mono);
  font-size: 10px;
  text-align: center;
}

.log-panel {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: min(45%, 340px);
  display: flex;
  flex-direction: column;
  background: rgba(11, 14, 19, 0.97);
  border-top: 1px solid var(--border-strong);
  backdrop-filter: blur(8px);
  z-index: 10;
}
.log-panel[hidden] { display: none; }

.log-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
  flex: 0 0 auto;
  flex-wrap: wrap;
}
.log-head strong { font-size: 13px; }

.log-filters { display: flex; gap: 4px; margin: 0; }
.log-filters .chip { padding: 2px 9px; font-size: 11px; }

.log-list {
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
  font-size: 12px;
}

.log-row {
  display: grid;
  grid-template-columns: 72px 62px minmax(0, 1fr) minmax(0, 1.1fr);
  gap: 10px;
  padding: 5px 12px;
  border-bottom: 1px solid rgba(35, 42, 53, 0.5);
  align-items: baseline;
}
.log-row:hover { background: var(--bg-panel); }

.log-time {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

.log-kind {
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-faint);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 1px 5px;
  text-align: center;
}
.log-kind-alert { color: var(--warn); border-color: rgba(251, 191, 36, 0.4); }
.log-kind-action { color: var(--accent); border-color: rgba(110, 231, 183, 0.35); }
.log-kind-account { color: #60a5fa; border-color: rgba(96, 165, 250, 0.4); }

.log-label { color: var(--text); overflow: hidden; text-overflow: ellipsis; }
.log-count { color: var(--text-faint); font-size: 10px; margin-left: 5px; }
.log-detail {
  color: var(--text-dim);
  font-family: var(--mono);
  font-size: 11px;
  overflow: hidden;
  text-overflow: ellipsis;
}

@media (max-width: 720px) {
  .log-row { grid-template-columns: 60px minmax(0, 1fr); }
  .log-row .log-kind, .log-row .log-detail { display: none; }
}

.task-cancel { padding: 2px 9px; font-size: 11px; margin-left: 8px; }

/* --------------------------------------------------------- panel toggles */

.panel-toggle {
  flex: 0 0 auto;
  background: var(--bg-input);
  border: 1px solid var(--border);
  color: var(--text-dim);
  border-radius: var(--radius-sm);
  width: 24px;
  height: 26px;
  font-size: 11px;
  line-height: 1;
  cursor: pointer;
}
.panel-toggle:hover { color: var(--text); border-color: var(--border-strong); }
.toggle-right { margin-left: auto; }

/* The chevron points the way the panel will move. */
.app-body.left-collapsed #toggle-left,
.app-body.right-collapsed #toggle-right { transform: scaleX(-1); }

/* Right-hand groups share the left panel's disclosure styling. */
.panel-right .group:last-of-type { border-bottom: 1px solid var(--border); }
.panel-realworld > .group:first-child > summary { border-top: none; }

/* The file options group sits inside the Export disclosure, so it drops its own
   summary and border rather than nesting a second collapsible inside one. */
#export-format .group { border-bottom: none; }
#export-format .group > summary { display: none; }
#export-format .group-body { padding: 0 0 8px; }

.plan-list { margin: 4px 0 10px; padding-left: 18px; font-size: 12px; color: var(--text-dim); line-height: 1.7; }
.plan-list li::marker { color: var(--warn); }

/* Sub-label inside a grouped field, for the sky picker under the 3D toggles. */
.field-label-sub { margin-top: 10px; }

/* ------------------------------------------------------------ app footer */

/* Slim, always present. Legal links have to live somewhere permanent rather
   than inside a view the user can switch away from. */
.app-footer {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 6px 14px;
  background: var(--bg-panel);
  border-top: 1px solid var(--border);
  font-size: 11px;
  color: var(--text-faint);
  min-height: 30px;
}

.app-footer-links { display: flex; gap: 12px; flex-wrap: wrap; }
.app-footer-links a { color: var(--text-dim); text-decoration: none; }
.app-footer-links a:hover { color: var(--accent); text-decoration: underline; }

.app-footer-note {
  margin-left: auto;
  text-align: right;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 760px) {
  .app-footer { flex-wrap: wrap; gap: 8px; }
  /* The obligation is stated on the linked page; the strapline is the part
     that can go when there is no room for it. */
  .app-footer-note { display: none; }
}

/* ------------------------------------------------------- document pages */

.doc-body {
  display: block;
  overflow: auto;
  background: var(--bg);
}

.doc {
  max-width: 760px;
  margin: 0 auto;
  padding: 48px 20px 80px;
  line-height: 1.7;
}

.doc h1 { font-size: 28px; font-weight: 650; margin: 0 0 6px; letter-spacing: -0.01em; }
.doc h2 { font-size: 17px; margin: 34px 0 10px; }
.doc h3 { font-size: 15px; margin: 0 0 6px; }
.doc p { margin: 0 0 12px; color: var(--text-dim); }
.doc li { color: var(--text-dim); margin-bottom: 6px; }
.doc ul { padding-left: 20px; margin: 0 0 14px; }
.doc strong { color: var(--text); font-weight: 600; }

.doc-meta { font-size: 12px; color: var(--text-faint); margin-bottom: 26px; }
.doc-lead { font-size: 15px; }
.doc-back { font-size: 13px; margin-bottom: 26px; }

.doc-callout {
  border: 1px solid var(--border-strong);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  background: var(--bg-panel);
  padding: 14px 16px;
  margin: 0 0 26px;
  font-size: 13px;
  color: var(--text-dim);
}
.doc-callout-warn { border-left-color: var(--warn); }

.doc-sources { display: grid; gap: 14px; margin-bottom: 10px; }

.doc-source {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-panel);
  padding: 16px;
}
.doc-source p { margin: 0 0 8px; font-size: 13px; }
.doc-source p:last-child { margin-bottom: 0; }

.doc-license {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.doc-license-open { color: var(--accent); }
.doc-license-warn { color: var(--warn); }

.doc-attribution {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-faint);
  background: var(--bg-input);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
}

.doc-table { width: 100%; border-collapse: collapse; margin: 0 0 18px; font-size: 13px; }
.doc-table th, .doc-table td {
  text-align: left;
  padding: 9px 10px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
  color: var(--text-dim);
}
.doc-table th { color: var(--text); font-weight: 600; font-size: 12px; }

@media (max-width: 620px) {
  .doc { padding: 28px 16px 60px; }
  /* Three columns of prose does not fit a phone; stack into labelled rows. */
  .doc-table, .doc-table tbody, .doc-table tr, .doc-table td { display: block; width: 100%; }
  .doc-table thead { display: none; }
  .doc-table tr { border-bottom: 1px solid var(--border); padding: 8px 0; }
  .doc-table td { border: none; padding: 2px 0; }
  .doc-table td:first-child { color: var(--text); font-weight: 600; }
}

/* The wordmark in the app footer uses the drawn mark, not the rendered logo:
   at 16px the photoreal artwork turns to mush, the same reason the favicon is
   an SVG. The full logo appears on the document pages, where it has room. */
.app-footer-brand {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--text-faint);
  text-decoration: none;
  flex: 0 0 auto;
}
.app-footer-brand:hover { color: var(--text-dim); }
.app-footer-mark { width: 16px; height: 16px; color: var(--accent); flex: 0 0 auto; }

.doc-footer {
  margin-top: 56px;
  padding-top: 28px;
  border-top: 1px solid var(--border);
  text-align: center;
}
.doc-footer-logo {
  width: 72px;
  height: 72px;
  border-radius: 12px;
  margin-bottom: 10px;
}
.doc-footer-brand {
  margin: 0 0 12px;
  font-weight: 650;
  color: var(--text);
  letter-spacing: -0.01em;
}
.doc-footer-links {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 16px;
  margin-bottom: 14px;
  font-size: 13px;
}
.doc-footer-links a { color: var(--text-dim); text-decoration: none; }
.doc-footer-links a:hover { color: var(--accent); text-decoration: underline; }
.doc-footer-note { font-size: 12px; color: var(--text-faint); margin: 0; }

/* The document footer sits outside <main>, so it needs the same measure or it
   would run the full width of the window under centred prose. */
.doc-footer {
  max-width: 760px;
  margin: 0 auto 48px;
  padding: 28px 20px 0;
}

/* ------------------------------------------------------- deletion notice */

/* Deliberately louder than the beta banner: this one is a countdown on
   something irreversible, and the undo has to be one click from anywhere. */
.deletion-banner {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 16px;
  flex: 0 0 auto;
  background: linear-gradient(90deg, rgba(248, 113, 113, 0.14), rgba(248, 113, 113, 0.03) 60%, transparent), var(--bg-panel);
  border-bottom: 1px solid rgba(248, 113, 113, 0.35);
}
.deletion-banner[hidden] { display: none; }

.deletion-banner-tag {
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--danger);
  border: 1px solid rgba(248, 113, 113, 0.45);
  border-radius: 3px;
  padding: 3px 8px;
  flex: 0 0 auto;
}
.deletion-banner-text {
  margin: 0;
  font-size: 12px;
  line-height: 1.45;
  color: var(--text-dim);
  flex: 1;
  min-width: 0;
}

.danger-zone {
  margin-top: 22px;
  padding: 14px 16px;
  border: 1px solid rgba(248, 113, 113, 0.3);
  border-radius: var(--radius);
  background: rgba(248, 113, 113, 0.04);
}
.danger-zone-active {
  border-color: rgba(248, 113, 113, 0.55);
  background: rgba(248, 113, 113, 0.08);
}
.danger-title { color: var(--danger); margin-bottom: 8px; font-size: 14px; }
.danger-zone p { margin: 0 0 10px; }

@media (max-width: 760px) {
  .deletion-banner { flex-wrap: wrap; }
}

/* ------------------------------------------------------ movable sections */

/* The grip is quiet until the header is hovered: it is a power feature, and a
   row of handles down the panel would read as clutter to everyone else. */
.group-grip {
  display: inline-block;
  width: 14px;
  margin-right: 6px;
  color: var(--text-faint);
  opacity: 0;
  font-size: 12px;
  line-height: 1;
  transition: opacity 0.12s ease;
  touch-action: none;
}
.group > summary:hover .group-grip,
.group-dragging .group-grip { opacity: 1; }
.group-grip:active { cursor: grabbing; }

/* Purely decorative now: the whole header is the drag handle, so the grip is a
   cue rather than a target and must never intercept a click meant for the
   header itself. */
.group-grip { pointer-events: none; }

/* Say the header can be dragged, without losing that clicking it still opens
   the section. */
.group > summary { cursor: grab; }
.group > summary:active { cursor: grabbing; }

.group-dragging {
  opacity: 0.45;
  outline: 1px dashed var(--border-strong);
  border-radius: var(--radius-sm);
}

/* Keeps the pointer a grab cursor over the whole window mid-drag, and stops
   text selecting as the pointer crosses labels. */
body.layout-dragging { cursor: grabbing; user-select: none; }

.layout-drop-line {
  height: 2px;
  margin: 2px 0;
  background: var(--accent);
  border-radius: 2px;
  box-shadow: 0 0 8px rgba(110, 231, 183, 0.5);
}

/* A finger cannot hover, so the grip is always visible on touch. */
@media (pointer: coarse) {
  .group-grip { opacity: 0.6; }
}

/* ----------------------------------------------------- floating sections */

/* The layer takes no pointer events itself, so the canvas underneath stays
   fully usable; the windows on it re-enable them. */
#float-layer {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 40;
}

.group-floating {
  position: fixed;
  pointer-events: auto;
  /* Held inside the canvas by layout.js; the cap here is a second line of
     defence for the moment before the first measurement lands. */
  max-height: calc(100vh - 24px);
  background: var(--bg-panel);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.55);
  overflow: auto;
  overscroll-behavior: contain;
}

/* Docked sections are separated by rules; a floating one is its own object and
   should not carry a stray border from that. */
.group-floating,
#float-layer .group:last-of-type { border-bottom: 1px solid var(--border-strong); }

.group-floating > summary {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--bg-raised);
  border-radius: var(--radius) var(--radius) 0 0;
  cursor: grab;
}

/* Always visible while floating: the grip is the title bar. */
.group-floating .group-grip { opacity: 1; pointer-events: auto; }

.group-floating.group-dragging {
  opacity: 0.9;
  outline: none;
  box-shadow: 0 16px 44px rgba(0, 0, 0, 0.65);
}


/* ------------------------------------------------------------ admin panel */

.admin-panel { display: flex; flex-direction: column; gap: 0; }

.admin-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-bottom: 12px;
}

.admin-tabs {
  display: flex;
  gap: 2px;
  padding: 3px;
  background: var(--bg-input);
  border-radius: var(--radius);
}

.admin-tab {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: none;
  border: none;
  color: var(--text-dim);
  font: inherit;
  font-size: 13px;
  padding: 7px 12px;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.admin-tab:hover { color: var(--text); }
.admin-tab.active { background: var(--bg-raised); color: var(--text); }

/* A count only ever appears for switches that are off, so it is always a
   warning rather than a neutral tally. */
.admin-tab-count {
  font-size: 10px;
  font-weight: 700;
  min-width: 16px;
  padding: 1px 5px;
  border-radius: 8px;
  background: var(--danger);
  color: #fff;
}

.admin-tab-body { padding-top: 14px; }

/* --- overview --- */

.admin-banner {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  margin-bottom: 12px;
  font-size: 12px;
  color: var(--text-dim);
  background: rgba(248, 113, 113, 0.08);
  border: 1px solid rgba(248, 113, 113, 0.4);
  border-radius: var(--radius-sm);
}
.admin-banner strong { color: var(--danger); }

.admin-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(104px, 1fr));
  gap: 8px;
}

.admin-tile {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 11px 12px;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.admin-tile-value { font-size: 21px; font-weight: 650; font-variant-numeric: tabular-nums; line-height: 1.1; }
.admin-tile-label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.07em; color: var(--text-faint); }
.admin-tile.busy { border-color: var(--accent); }
.admin-tile.busy .admin-tile-value { color: var(--accent); }
.admin-tile.good .admin-tile-value { color: var(--accent); }
.admin-tile.warn { border-color: rgba(251, 191, 36, 0.45); }
.admin-tile.warn .admin-tile-value { color: var(--warn); }

.admin-health-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 6px;
  margin-top: 10px;
}
.admin-health { display: flex; align-items: center; gap: 8px; font-size: 12px; }
.admin-health-label { color: var(--text); }

.admin-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex: 0 0 auto;
  background: var(--text-faint);
}
.admin-dot.ok { background: var(--accent); box-shadow: 0 0 6px rgba(110, 231, 183, 0.6); }
.admin-dot.idle { background: var(--text-faint); }
.admin-dot.bad { background: var(--danger); box-shadow: 0 0 6px rgba(248, 113, 113, 0.55); }

.admin-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  font-size: 11px;
  color: var(--text-faint);
}

/* --- switches --- */

.admin-switches { display: grid; gap: 6px; margin-top: 10px; }

.admin-switch-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 13px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-input);
}
.admin-switch-text { flex: 1; min-width: 0; }
.admin-switch-text p { margin: 2px 0 0; }

/* Off has to be obvious at a glance: this tab is opened to find out what is
   off, usually while something is going wrong. */
.admin-switch-row.is-off {
  border-color: rgba(248, 113, 113, 0.5);
  background: rgba(248, 113, 113, 0.07);
}
.admin-switch-row.is-off strong { color: var(--danger); }

.admin-switch { flex: 0 0 auto; cursor: pointer; }
.admin-switch input { position: absolute; opacity: 0; pointer-events: none; }

.admin-switch-track {
  display: block;
  width: 38px;
  height: 22px;
  border-radius: 11px;
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  position: relative;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.admin-switch-track::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--text-faint);
  transition: transform 0.15s ease, background 0.15s ease;
}
.admin-switch input:checked + .admin-switch-track {
  background: rgba(110, 231, 183, 0.22);
  border-color: var(--accent);
}
.admin-switch input:checked + .admin-switch-track::after {
  transform: translateX(16px);
  background: var(--accent);
}
.admin-switch input:disabled + .admin-switch-track { opacity: 0.5; cursor: not-allowed; }
.admin-switch input:focus-visible + .admin-switch-track { outline: 2px solid var(--accent); outline-offset: 2px; }

/* --- accounts --- */

.admin-users { display: grid; gap: 6px; margin-top: 10px; max-height: 340px; overflow-y: auto; }

.admin-user {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-input);
}
.admin-user-main { display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 0; }
.admin-user-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.admin-user-head strong { overflow: hidden; text-overflow: ellipsis; }
.admin-user-actions { display: flex; gap: 6px; flex: 0 0 auto; flex-wrap: wrap; justify-content: flex-end; }

.admin-badges { display: flex; flex-wrap: wrap; gap: 4px; }
.admin-badge {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 2px 7px;
  border-radius: 3px;
  background: var(--bg-raised);
  color: var(--text-dim);
  border: 1px solid var(--border);
  white-space: nowrap;
}
.admin-badge.role-admin { color: var(--accent); border-color: var(--accent); }
.admin-badge.role-staff { color: var(--text); border-color: var(--border-strong); }
.admin-badge.good { color: var(--accent); border-color: rgba(110, 231, 183, 0.4); }
.admin-badge.warn { color: var(--warn); border-color: rgba(251, 191, 36, 0.45); }
.admin-badge.danger { color: var(--danger); border-color: rgba(248, 113, 113, 0.45); }

/* --- log --- */

.admin-log { max-height: 340px; overflow-y: auto; margin-top: 4px; }
.admin-log-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 2px;
  border-bottom: 1px solid var(--border);
  font-size: 12px;
}
.admin-log-row .admin-dot { margin-top: 6px; }
.admin-log-main { display: flex; flex-direction: column; gap: 1px; min-width: 0; }

@media (max-width: 720px) {
  .admin-tab { font-size: 12px; padding: 7px 8px; }
  .admin-user { flex-direction: column; align-items: stretch; }
  .admin-user-actions { justify-content: flex-start; }
}

/* Credits panel: quiet, but the licence warnings have to be readable. */
.attribution-title {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-faint);
  margin-bottom: 6px;
}
.attribution-warn {
  color: var(--warn);
  border-left: 2px solid rgba(251, 191, 36, 0.5);
  padding-left: 8px;
}


/* ------------------------------------------------------- site header ---
   Shared by the landing page, the roadmap, the issues pages and the legal
   pages. It lived in landing.css, which meant every page that used the header
   silently rendered it unstyled unless it also loaded a stylesheet named after
   a page it was not. */

.lp-nav {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 14px 28px;
  background: rgba(11, 14, 19, 0.82);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
}

.lp-brand {
  display: flex;
  align-items: center;
  gap: 9px;
  font-weight: 650;
  font-size: 16px;
  color: var(--text);
  text-decoration: none;
  letter-spacing: -0.01em;
}
.lp-mark { width: 22px; height: 22px; color: var(--accent); }

.lp-nav-links { display: flex; align-items: center; gap: 22px; margin-left: auto; }
.lp-nav-links a { color: var(--text-dim); text-decoration: none; font-size: 14px; }
.lp-nav-links a:hover { color: var(--text); }
.lp-nav-links a.btn { color: var(--accent-ink); }

.lp-menu-btn {
  display: none;
  margin-left: auto;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  width: 38px;
  height: 34px;
  padding: 0 8px;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.lp-menu-btn span {
  display: block;
  height: 2px;
  border-radius: 1px;
  background: var(--text-dim);
  transition: transform 0.18s ease, opacity 0.18s ease;
}
.lp-menu-btn[aria-expanded='true'] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.lp-menu-btn[aria-expanded='true'] span:nth-child(2) { opacity: 0; }
.lp-menu-btn[aria-expanded='true'] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* A wider measure for pages that hold a board or a grid rather than prose. */
.doc-wide { max-width: 1180px; }

@media (max-width: 760px) {
  .lp-nav { padding: 12px 16px; gap: 12px; flex-wrap: wrap; }
  .lp-menu-btn { display: flex; }

  .lp-nav-links {
    display: none;
    order: 3;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    width: 100%;
    margin: 0;
    padding-top: 10px;
    border-top: 1px solid var(--border);
  }
  .lp-nav-links.is-open { display: flex; }
  .lp-nav-links a { padding: 12px 4px; font-size: 15px; border-bottom: 1px solid var(--border); }
  .lp-nav-links a.btn { margin-top: 10px; border-bottom: none; text-align: center; text-decoration: none; }
}

/* Classes that were being applied with no rule anywhere. Each is a real hook
   used by the interface; leaving them undefined meant relying on an element
   selector happening to cover them, which is fragile and hard to notice. */

/* The search boxes: the place picker, the admin account search, the issue
   list. The element selector above already styles them; this is what makes
   them consistent when one is placed somewhere without that context. */
.search-input { width: 100%; }

/* The form inside a modal, which owns the dialog's own scrolling. */
.modal-inner { display: flex; flex-direction: column; min-height: 0; }

/* The admin panel's tab body, which scrolls independently of the tab bar. */
.admin-content { min-height: 0; }
