.panel,
.card {
  background: var(--color-surface);
  border: var(--line-soft);
  border-radius: var(--radius-m);
  padding: var(--space-l);
  margin-bottom: var(--space-l);
}

.panel > h2,
.panel > .page-heading {
  margin-top: var(--space-xl);
}

.panel > h2:first-child,
.panel > .page-heading:first-child {
  margin-top: 0;
}

.table {
  width: 100%;
  border-collapse: collapse;
}

.table th,
.table td {
  text-align: left;
  padding: var(--space-s) var(--space-m);
  border-bottom: var(--line);
}

.muted {
  color: var(--color-muted);
}

.stack {
  display: grid;
  gap: var(--space-m);
}

input,
button,
select,
textarea {
  font: inherit;
}

label {
  display: grid;
  gap: var(--space-xs);
}

input,
select,
textarea {
  background: var(--color-surface);
  border: var(--line);
  border-radius: var(--radius-s);
  color: var(--color-text);
  padding: var(--space-s) var(--space-m);
}

textarea {
  font-family: var(--font-mono);
  font-size: 0.875rem;
  line-height: 1.5;
  resize: vertical;
  tab-size: 4;
}

input:focus,
select:focus,
textarea:focus,
button:focus-visible,
a:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
}

button,
a.button {
  background: var(--color-button-primary);
  border: none;
  border-radius: var(--radius-s);
  color: #fff;
  padding: var(--space-s) var(--space-l);
  cursor: pointer;
  display: inline-block;
  text-decoration: none;
}

button.danger,
a.button.danger {
  background: var(--color-button-danger);
}

button:disabled,
a.button[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
}

.link-button {
  background: none;
  border: none;
  color: var(--color-link);
  padding: 0;
  text-decoration: underline;
  cursor: pointer;
}

.inline-form {
  display: inline;
}

.auth-panel {
  max-width: 28rem;
}

dialog.modal,
div.modal {
  background: var(--color-surface);
  color: var(--color-text);
  border: var(--line);
  border-radius: var(--radius-m);
  padding: 0;
  width: min(32rem, 90vw);
  max-height: 90vh;
}

dialog.modal::backdrop {
  background: rgba(0, 0, 0, 0.45);
}

.modal-header,
.modal-body,
.modal-footer {
  padding: var(--space-l);
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: var(--line);
}

.modal-header h2 {
  margin: 0;
  font-size: 1.1rem;
}

.modal-body {
  display: grid;
  gap: var(--space-m);
  overflow-y: auto;
}

.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-m);
  border-top: var(--line);
}

.modal-close {
  background: none;
  color: var(--color-muted);
  padding: var(--space-xs) var(--space-s);
  font-size: 1.25rem;
  line-height: 1;
}

.button-secondary {
  background: var(--color-surface);
  color: var(--color-text);
  border: var(--line);
}

.field-hint {
  color: var(--color-muted);
  font-size: 0.875rem;
}

.page-heading {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-m);
  margin-bottom: var(--space-l);
}

.page-heading h1,
.page-heading h2 {
  margin: 0;
}

.button-row {
  display: flex;
  gap: var(--space-s);
  flex-wrap: wrap;
}

.detail-grid {
  display: grid;
  gap: var(--space-l);
}

.used-by-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--space-s);
}

.file-tree {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--space-xs);
  font-family: var(--font-mono);
  font-size: 0.875rem;
}

.file-tree .file-tree {
  padding-left: var(--space-l);
  margin-top: var(--space-xs);
}

.file-tree-row {
  display: flex;
  /* Row-gap 0 so the wrapped .file-tree-children div sits directly under
     the toggle button; vertical spacing is owned exclusively by the
     outer grid's gap and the nested ul's margin-top. */
  gap: 0 var(--space-s);
  align-items: baseline;
  flex-wrap: wrap;
}

.file-tree-toggle {
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
  padding: 0;
  font: inherit;
  text-align: left;
}

.file-tree-toggle .chevron {
  display: inline-block;
  width: 1ch;
  text-align: center;
  transition: transform 120ms ease;
  margin-right: var(--space-xs);
}

.file-tree-row-file {
  padding-left: calc(1ch + var(--space-xs));
}

.file-tree-name-button {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--color-link);
  cursor: pointer;
  text-align: left;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.file-tree-name-button:hover,
.file-tree-name-button:focus-visible {
  text-decoration-thickness: 2px;
}

.file-tree-toggle[aria-expanded="true"] .chevron {
  transform: rotate(90deg);
}

.file-tree-children {
  flex-basis: 100%;
}

.file-tree-children[hidden] {
  display: none;
}

.file-tree-badge {
  font-size: 0.75rem;
  padding: 0 0.4em;
  border-radius: var(--radius-s);
  background: var(--color-surface-muted);
  color: var(--color-muted);
  border: var(--line);
}

.file-tree-badge-warn {
  background: transparent;
  color: var(--color-danger);
  border-color: var(--color-danger);
}

.file-tree-row-truncated {
  font-style: italic;
}

.overlay-picker {
  display: grid;
  gap: var(--space-m);
}

.overlay-picker-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  min-height: 3rem;
}

.overlay-picker-row {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  padding: var(--space-s) var(--space-m);
  background: var(--color-surface-muted);
  border: var(--line);
  border-radius: var(--radius-s);
  cursor: grab;
  user-select: none;
}

.overlay-picker-row:active {
  cursor: grabbing;
}

.overlay-picker-row.is-dragging {
  opacity: 0.4;
}

.overlay-picker-row.drop-before {
  box-shadow: 0 2px 0 0 var(--color-focus) inset;
}

.overlay-picker-row.drop-after {
  box-shadow: 0 -2px 0 0 var(--color-focus) inset;
}

.overlay-picker-handle {
  color: var(--color-muted);
  font-family: var(--font-mono);
  letter-spacing: -0.1em;
}

.overlay-picker-name {
  flex: 1;
}

.overlay-picker-expose {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  color: var(--color-muted);
  white-space: nowrap;
  font-size: 0.9em;
}

.overlay-picker-expose code {
  font-size: inherit;
}

.overlay-picker-remove {
  background: none;
  color: var(--color-muted);
  padding: 0 var(--space-s);
  font-size: 1.1rem;
  line-height: 1;
}

.overlay-picker-remove:hover {
  color: var(--color-danger);
}

.overlay-picker-empty {
  margin: 0;
}

.overlay-picker-add {
  display: flex;
  align-items: center;
  gap: var(--space-s);
}

.overlay-picker-add select {
  flex: 1;
}

.section-title {
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--color-text);
  line-height: 1.3;
}

.stack > button {
  justify-self: end;
}

.page-footer-actions {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  gap: var(--space-s);
  margin-top: var(--space-l);
}

.form-actions-inline {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-s);
}

.danger-outline,
button.danger-outline {
  background: transparent;
  color: var(--color-button-danger);
  border: 1px solid var(--color-button-danger);
}

button.danger-outline:hover {
  background: color-mix(in srgb, var(--color-button-danger) 15%, transparent);
}

.inline-save {
  display: flex;
  gap: var(--space-s);
  align-items: stretch;
}

.inline-save > input {
  flex: 1;
}

.server-info {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: var(--space-l);
  row-gap: var(--space-xs);
  margin: var(--space-l) 0;
}

.server-info > div {
  display: contents;
}

.server-info dt {
  font-weight: 600;
}

.server-info dd {
  margin: 0;
}

.server-actions {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  flex-wrap: wrap;
}

.state-badge {
  padding: var(--space-xs) var(--space-s);
  border-radius: var(--radius-s);
  font-size: 0.85em;
}

.state-running {
  background: color-mix(in srgb, var(--color-success) 20%, transparent);
  color: var(--color-success);
}

.state-stopped {
  background: color-mix(in srgb, var(--color-muted) 20%, transparent);
  color: var(--color-muted);
}

.state-unknown {
  background: color-mix(in srgb, var(--color-muted) 15%, transparent);
  color: var(--color-muted);
}

.state-transient {
  background: color-mix(in srgb, var(--color-warning) 25%, transparent);
  color: var(--color-warning);
}

.state-drift {
  color: var(--color-warning);
  margin: var(--space-s) 0 0;
}

.last-job {
  color: var(--color-muted);
  margin: var(--space-xs) 0 0;
}

.config-shell {
  display: grid;
}

.config-preview {
  margin: 0;
  padding: var(--space-s) var(--space-m);
  background: var(--color-surface);
  color: var(--color-muted);
  border: var(--line);
  border-bottom: none;
  border-radius: var(--radius-s) var(--radius-s) 0 0;
  font-family: var(--font-mono);
  font-size: 0.875rem;
  line-height: 1.5;
  white-space: pre;
  overflow-x: auto;
}

.config-preview + textarea {
  border-top: none;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}

/* ============================================================
   Files-overlay editor: tree-row hover actions, drop targets,
   editor / new-folder / conflict / delete modals, and the
   floating Uploads panel.
   ============================================================ */

/* The display: flex / grid declarations on the elements below have the
   same specificity as the UA's `[hidden]{display:none}` rule and come
   later in the cascade, so without this they'd win and elements would
   stay visible after JS sets `el.hidden = true`. Targeted rather than
   a global `[hidden]!important` so we don't fight unknown UA defaults. */
.files-uploads[hidden],
.files-editor-binary[hidden],
.files-editor-text[hidden],
.files-editor-replace-idle[hidden],
.files-editor-replace-queued[hidden],
.files-editor-rename-hint[hidden],
.files-uploads-clear[hidden] {
  display: none !important;
}

.files-manager {
  display: grid;
  gap: var(--space-s);
}

.files-manager-hint {
  font-size: 0.85em;
  margin: 0;
}

.files-tree-root {
  border: var(--line-soft);
  border-radius: var(--radius-s);
  padding: var(--space-s);
  min-height: 3rem;
}

.files-tree-root .file-tree {
  margin: 0;
}

.files-tree-root.is-drop-target {
  outline: 2px solid var(--color-success);
  outline-offset: -2px;
  background: color-mix(in srgb, var(--color-success) 10%, transparent);
}

.files-row-root > .files-row-root-label {
  color: var(--color-muted);
  font-family: var(--font-mono);
}

.files-root-children {
  flex-basis: 100%;
  margin-top: var(--space-xs);
}

.files-empty {
  margin: var(--space-s) var(--space-xs);
}

/* Per-row action column. Lives inside a .file-tree-row. Hidden until row
   is hovered, except on touch devices where hover doesn't apply. */
.files-row {
  position: relative;
}

.files-row .files-row-actions {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding-left: var(--space-s);
  opacity: 0;
  pointer-events: none;
  transition: opacity 80ms ease;
  white-space: nowrap;
}

.files-row:hover > .files-row-actions,
.files-row:focus-within > .files-row-actions,
.files-row.is-drop-target > .files-row-actions,
.files-row.is-drag-source > .files-row-actions {
  opacity: 1;
  pointer-events: auto;
}

@media (hover: none) {
  .files-row .files-row-actions {
    opacity: 1;
    pointer-events: auto;
  }
}

.files-row-action {
  background: none;
  border: 1px solid transparent;
  color: var(--color-link);
  padding: 0 var(--space-xs);
  font-size: 0.85em;
  border-radius: var(--radius-s);
  cursor: pointer;
  text-decoration: none;
  line-height: 1.3;
}

.files-row-action:hover {
  background: var(--color-surface-muted);
  border-color: var(--color-link);
}

.files-row-danger {
  color: var(--color-danger);
}

.files-row-danger:hover {
  border-color: var(--color-danger);
}

.files-row.is-drag-source {
  opacity: 0.5;
}

.files-row.is-drop-target {
  outline: 2px solid var(--color-success);
  outline-offset: -2px;
  border-radius: var(--radius-s);
  background: color-mix(in srgb, var(--color-success) 10%, transparent);
}

/* Delete-confirm modal: scrollable preview list. The <details> wrapper
   collapses by default; when expanded, very large folders shouldn't
   push the modal off-screen. */
.files-delete-preview-list {
  max-height: 40vh;
  overflow-y: auto;
  margin: 0.5rem 0 0;
  padding-left: 1.25rem;
  font-family: var(--font-mono, monospace);
  font-size: 0.875rem;
}

.files-delete-preview-list li {
  list-style: square;
}

.files-delete-preview-summary {
  cursor: pointer;
}

/* Wider modal for the editor (textarea needs the breathing room). */
dialog.modal.modal-wide,
div.modal.modal-wide {
  width: min(48rem, 92vw);
}

.files-editor-field {
  display: grid;
  gap: 2px;
}

.files-editor-field input,
.files-editor-field textarea {
  font-family: var(--font-mono);
  font-size: 0.875rem;
}

.files-field-label {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-muted);
}

.files-editor-path {
  font-family: var(--font-mono);
  font-size: 0.95rem;
  margin: 0;
}

.files-editor-meta {
  display: flex;
  justify-content: space-between;
  font-size: 0.85em;
}

.files-editor-rename-hint {
  color: var(--color-success);
  font-size: 0.85em;
  margin: 0;
}

.files-editor-rename-hint code {
  font-family: var(--font-mono);
}

.files-editor-binary {
  background: var(--color-surface-muted);
  border: var(--line);
  border-radius: var(--radius-s);
  padding: var(--space-m);
  display: grid;
  gap: var(--space-s);
}

.files-editor-binary-note {
  color: var(--color-muted);
  font-size: 0.9em;
}

.files-editor-binary-replace-label {
  margin-top: var(--space-xs);
}

.files-editor-replace-zone {
  border: 1.5px dashed var(--color-success);
  border-radius: var(--radius-s);
  padding: var(--space-m);
  text-align: center;
  background: color-mix(in srgb, var(--color-success) 5%, transparent);
}

.files-editor-replace-zone.is-drop-target {
  background: color-mix(in srgb, var(--color-success) 22%, transparent);
}

.files-editor-replace-idle {
  color: var(--color-success);
  margin: 0;
  font-size: 0.9em;
}

.files-editor-replace-queued {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  margin: 0;
  font-size: 0.9em;
  color: var(--color-success);
}

.files-editor-footer {
  align-items: center;
}

.files-editor-footer-spacer {
  flex: 1;
}

.files-editor-delete {
  margin-right: auto;
}

.files-editor-save {
  background: var(--color-success);
}

.files-editor-save[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}

.files-new-folder-error {
  color: var(--color-danger);
  margin: 0;
  font-size: 0.9em;
}

.files-conflict-path {
  font-family: var(--font-mono);
}

/* Floating uploads panel — bottom-right of the page. */
.files-uploads {
  position: fixed;
  right: var(--space-l);
  bottom: var(--space-l);
  width: min(22rem, calc(100vw - 2 * var(--space-l)));
  background: var(--color-surface);
  border: var(--line);
  border-radius: var(--radius-m);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
  z-index: 50;
  max-height: 60vh;
  display: flex;
  flex-direction: column;
}

.files-uploads-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-s) var(--space-m);
  border-bottom: var(--line);
}

.files-uploads-list {
  list-style: none;
  margin: 0;
  padding: var(--space-s) var(--space-m);
  overflow-y: auto;
  display: grid;
  gap: var(--space-s);
}

.files-uploads-row {
  display: grid;
  gap: 2px;
  font-size: 0.85em;
}

.files-uploads-row-meta {
  display: flex;
  justify-content: space-between;
  gap: var(--space-s);
  align-items: baseline;
}

.files-uploads-row-name {
  font-family: var(--font-mono);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.files-uploads-row-target {
  font-size: 0.85em;
}

.files-uploads-row-progress {
  height: 3px;
  background: var(--color-surface-muted);
  border-radius: 2px;
  overflow: hidden;
}

.files-uploads-bar {
  width: 0;
  height: 100%;
  background: var(--color-link);
  transition: width 80ms linear;
}

.files-uploads-bar.is-done {
  background: var(--color-success);
}

.files-uploads-bar.is-error {
  background: var(--color-danger);
}

.files-uploads-bar.is-cancelled {
  background: var(--color-muted);
}

.files-uploads-row-status {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 0.8em;
  color: var(--color-muted);
}

/* ============================================================
   State cluster (top of server detail)
   ============================================================ */

.state-cluster {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
}

.state-cluster > * + * {
  border-top: 1px dashed var(--color-border-muted);
  padding-top: var(--space-m);
}

/* Config grid — auto-fit so it scales with field count */
.config-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-s) var(--space-m);
}
.config-field-label {
  font-size: 0.75em;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-muted);
  margin-bottom: 0.15em;
}
.config-field-value { font-size: 0.95em; }

/* ============================================================
   Live-state — compact player grids
   ============================================================ */

.player-grid {
  list-style: none;
  padding: 0;
  margin: var(--space-s) 0 0;
  display: grid;
  gap: var(--space-xs);
}
.player-grid.current { grid-template-columns: repeat(4, 1fr); }
.player-grid.recent  { grid-template-columns: repeat(5, 1fr); }

/* Player card layout — avatar on left spans full card height; name + meta
   stack on the right, both left-aligned. The avatar size is the height
   driver for the whole card. */
.player-card {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  column-gap: var(--space-s);
  align-items: center;
  padding: var(--space-xs);
}
.player-link {
  display: contents;
  color: inherit;
  text-decoration: none;
}
.player-link:hover .name { text-decoration: underline; }

.player-card .avatar {
  border-radius: var(--radius-s);
  object-fit: cover;
  grid-row: 1 / span 2;
}
.current-card .avatar { width: 36px; height: 36px; }
.recent-chip .avatar  { width: 28px; height: 28px; }

.player-card .name {
  grid-column: 2;
  grid-row: 1;
  font-size: 0.9em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.current-card .name { font-weight: 600; }
.recent-chip .name { font-weight: 500; }

.player-card .meta {
  grid-column: 2;
  grid-row: 2;
  color: var(--color-muted);
  font-size: 0.75em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.recent-chip .meta { font-size: 0.8em; }

.avatar.placeholder {
  display: inline-block;
  background: color-mix(in srgb, var(--color-muted) 30%, transparent);
}

.recent-header {
  margin: var(--space-m) 0 var(--space-xs);
  font-size: 0.75em;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-muted);
  font-weight: 600;
}
.recent-header-trigger {
  background: transparent;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--color-link);
  text-transform: inherit;
  letter-spacing: inherit;
  text-decoration: underline dotted;
  text-underline-offset: 2px;
  cursor: pointer;
}
.recent-header-trigger:hover { text-decoration-style: solid; }

.server-live-summary { font-size: 1.05em; }

/* Narrow viewports — collapse fixed grids so chips don't crush */
@media (max-width: 600px) {
  .player-grid.current,
  .player-grid.recent {
    grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  }
}

/* ============================================================
   Inspection strip — tabbed Log / Console / Files
   ============================================================ */

.inspection-strip {
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
}
.tab-bar {
  display: flex;
  align-items: center;
  border-bottom: 1px solid var(--color-border-muted);
  padding: 0 var(--space-s);
}
.tab-bar [role="tab"] {
  background: transparent;
  border: 0;
  padding: var(--space-s) calc(var(--space-m) * 1.5);
  color: var(--color-muted);
  cursor: pointer;
  font: inherit;
  font-size: 1.05em;
  border-bottom: 2px solid transparent;
}
.tab-bar [role="tab"][aria-selected="true"] {
  color: var(--color-text);
  border-bottom-color: var(--color-link);
}
.tab-bar .strip-expand {
  margin-left: auto;
  background: transparent;
  border: 0;
  padding: var(--space-s) var(--space-m);
  color: var(--color-muted);
  cursor: pointer;
}
.tab-bar .strip-expand:hover { color: var(--color-text); }

.tab-pane {
  padding: var(--space-s);
  /* Fixed height (not max-height) so the strip stays the same size
     regardless of how much content the active tab has. The console
     tab's flex layout reserves full height for the input pin; the
     log and files tabs use scrollable overflow. */
  height: 18rem;
  overflow: auto;
}
.tab-pane[hidden] { display: none; }
.tab-pane .log-stream { max-height: none; }  /* let pane handle scrolling */

/* Console tab pane — input pinned at bottom, transcript scrolls.
   :not([hidden]) keeps .tab-pane[hidden] { display: none } winning
   when the tab is inactive (otherwise these rules would tie on
   specificity and the later rule would defeat the hidden state). */
.tab-pane[data-tab="console"]:not([hidden]) {
  display: flex;
  flex-direction: column;
  /* inherits max-height: 12rem from .tab-pane */
  overflow: hidden; /* clip here; transcript scrolls internally */
}
.tab-pane[data-tab="console"] .console-transcript {
  flex: 1 1 auto;
  min-height: 0;       /* allow flex item to shrink below content size */
  max-height: none;    /* override the global 400px cap — parent caps the area */
  overflow: auto;
  margin-bottom: var(--space-s); /* tighter gap inside fixed-height pane */
}
.tab-pane[data-tab="console"] .console-input-form {
  flex: 0 0 auto;      /* never shrink the input row */
}

/* ============================================================
   RCON console panel — server detail page
   ============================================================ */

.console-transcript {
  max-height: 400px;
  overflow-y: auto;
  background: var(--color-log-bg);
  color: var(--color-log-text);
  border-radius: var(--radius-s);
  padding: var(--space-m);
  font-family: var(--font-mono);
  font-size: 0.875rem;
  line-height: 1.4;
  margin-bottom: var(--space-m);
}

.console-line {
  margin: var(--space-s) 0;
}

.console-line:first-child {
  margin-top: 0;
}

.console-prompt {
  font-weight: 600;
  color: var(--color-primary);
}

.console-reply {
  margin: 0;
  font-family: inherit;
  font-size: inherit;
  white-space: pre-wrap;
  color: var(--color-muted);
  border: none;
  background: none;
  padding: 0;
}

.console-error .console-prompt {
  color: var(--color-danger);
}

.console-error {
  border-left: 3px solid var(--color-danger);
  padding-left: var(--space-s);
}

.console-input-form {
  display: flex;
  align-items: center;
  gap: var(--space-s);
}

.console-prompt-glyph {
  font-family: var(--font-mono);
  font-weight: 600;
  color: var(--color-primary);
  flex-shrink: 0;
}

.console-input-form input[name="command"] {
  flex: 1;
  min-width: 0;
}

.console-spinner {
  display: none;
  color: var(--color-muted);
  font-family: var(--font-mono);
  flex-shrink: 0;
}

.console-input-form.htmx-request .console-spinner {
  display: inline;
}

.recent-modal-list {
  /* Force a single column inside the modal regardless of the 5-col
     default on .player-grid.recent. !important is acceptable here:
     the only way to override the more-specific class selector
     chain is via specificity or !important; modal-only override
     is local enough that long-term maintainability is fine. */
  grid-template-columns: 1fr !important;
  max-height: 60vh;
  overflow: auto;
}

/* Modal-specific overrides — the log/console modals are meant to give
   the user *more* room than the inline tab. The .tall modifier opts
   into that extra height when the same element is rendered inside a
   .modal. */
.modal .log-stream.tall,
.modal .console-transcript.tall {
  max-height: 60vh;
}

/* Console modal body — input pinned at bottom, transcript scrolls. */
#console-modal .modal-body {
  display: flex;
  flex-direction: column;
  max-height: 70vh;
}
#console-modal .modal-body .console-transcript {
  flex: 1 1 auto;
  min-height: 0;
  max-height: none;    /* override global 400px / .tall 60vh — modal-body caps it */
  overflow: auto;
}
#console-modal .modal-body .console-input-form {
  flex: 0 0 auto;
}

/* --- Form primitives (new vocabulary, 2026-05) -------------------------- */

.field {
  display: grid;
  gap: var(--space-xs);
}

.field-label {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--color-text);
}

/* .field-hint already defined earlier in this file. */

.radio-list {
  display: grid;
  gap: var(--space-xs);
}

.radio-row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-s);
  padding: var(--space-xs) 0;
  cursor: pointer;
}

.radio-row > input[type="radio"] {
  appearance: none;
  box-sizing: border-box;
  width: 1rem;
  height: 1rem;
  padding: 0;
  border-radius: 50%;
  border: 1.5px solid var(--color-border);
  background: var(--color-bg);
  flex: 0 0 auto;
  margin: 0.2rem 0 0 0;
  display: grid;
  place-items: center;
  cursor: pointer;
}

.radio-row > input[type="radio"]:checked {
  border-color: var(--color-primary);
}

.radio-row > input[type="radio"]:checked::after {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--color-primary);
}

.radio-row > input[type="radio"]:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
}

.radio-row-text {
  display: grid;
  gap: 0.0625rem;
}

.radio-row-text strong {
  font-weight: 600;
  font-size: 0.9375rem;
  color: var(--color-text);
}

.radio-row-text span {
  color: var(--color-muted);
  font-size: 0.8125rem;
}

.switch-row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-s);
  padding: var(--space-xs) 0;
  cursor: pointer;
}

.switch-row > input[type="checkbox"] {
  appearance: none;
  box-sizing: border-box;
  position: relative;
  width: 1.875rem;
  height: 1rem;
  padding: 0;
  border: 0;
  background: var(--color-border);
  border-radius: 999px;
  flex: 0 0 auto;
  margin: 0.225rem 0 0 0;
  cursor: pointer;
  transition: background 0.15s;
}

.switch-row > input[type="checkbox"]::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 0.75rem;
  height: 0.75rem;
  background: #fff;
  border-radius: 50%;
  transition: transform 0.15s;
}

.switch-row > input[type="checkbox"]:checked {
  background: var(--color-button-primary);
}

.switch-row > input[type="checkbox"]:checked::after {
  transform: translateX(0.875rem);
}

.switch-row > input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
}

.switch-row-text {
  display: grid;
  gap: 0.0625rem;
}

.switch-row-text strong {
  font-weight: 600;
  font-size: 0.9375rem;
  color: var(--color-text);
}

.switch-row-text span {
  color: var(--color-muted);
  font-size: 0.8125rem;
}

.table-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: var(--space-m);
}

.table-actions-end {
  display: flex;
  align-items: center;
  gap: var(--space-m);
}

.workshop-input {
  font-family: var(--font-mono);
  font-size: 0.875rem;
}
