* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

:root {
  /* Cyberpunk palette — deep blue-black with cyan accent + orange highlight,
     inspired by the kipina.studio landing-page treatment. The whole UI
     theme switches by editing these seven values; downstream rules use the
     variables almost exclusively. */
  --bg-base:     #050b14;
  --bg-surface:  #0a1424;
  --bg-elevated: #101e33;
  --bg-glass:    rgba(10, 20, 36, 0.65);
  --text:        #e2f1fe;
  --text-muted:  #708fae;
  --accent:      #22d3ee;      /* cyan — primary action / focus / brand */
  --accent-hot:  #fb923c;      /* orange — callouts, warnings, hot states */
  --border:      rgba(34, 211, 238, 0.1);
  --border-solid:#1c3553;

  /* Soft cyan glow used on focus + active buttons for the "hud" feel.
     Kept tame (alpha 0.35) so it doesn't bleed across the IDE chrome. */
  --glow-accent: 0 0 0 1px rgba(34, 211, 238, 0.45),
                 0 0 14px rgba(34, 211, 238, 0.25);
  --glow-hot:    0 0 0 1px rgba(251, 146, 60, 0.4),
                 0 0 16px rgba(251, 146, 60, 0.25);
  --glass-shadow: 0 10px 30px rgba(0, 0, 0, 0.45),
                  0 0 1px rgba(34, 211, 238, 0.15) inset;
}

html, body {
  height: 100%;
}

body {
  font-family: 'Inter', -apple-system, system-ui, sans-serif;
  /* Subtle radial brighten at the top-left to suggest a light source
     (matches the screenshot's "machine sparks" composition without
     committing to an actual image). */
  background:
    radial-gradient(1200px 600px at 0% 0%, rgba(34, 211, 238, 0.06), transparent 60%),
    radial-gradient(1000px 500px at 100% 100%, rgba(251, 146, 60, 0.04), transparent 60%),
    var(--bg-base);
  color: var(--text);
  font-size: 14px;
  line-height: 1.5;
}

.shell {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

/* .workspace holds the original row layout (activity bar / sidebar /
   panes). The shell wraps it in a column so the .appbar can sit
   full-width below without competing for vertical space. */
.workspace {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
}

/* ── Full-width bottom status bar ── */
.appbar {
  flex: 0 0 24px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 12px;
  background:
    linear-gradient(180deg, rgba(34, 211, 238, 0.04), transparent),
    var(--bg-surface);
  border-top: 1px solid var(--border);
  font-size: 11px;
  color: var(--text-muted);
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
  letter-spacing: 0.4px;
}

.appbar-brand {
  /* Forgejo-orange brand wordmark — keeps "KIPINÄ" tied to the same
     palette as the org's git server. Body accent stays cyan. */
  color: var(--accent-hot);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  text-shadow: 0 0 8px rgba(251, 146, 60, 0.4);
  text-decoration: none;
  transition: filter 0.15s, text-shadow 0.15s;
}
.appbar-brand:hover {
  filter: brightness(1.15);
  text-shadow: 0 0 12px rgba(251, 146, 60, 0.6);
}

.appbar-brand-sub {
  color: var(--text-muted);
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0.3px;
  text-shadow: none;
}

.appbar-spacer {
  flex: 1;
}

.appbar-meta {
  color: var(--text-muted);
}

.appbar-nodes {
  color: var(--text-muted);
  font-size: 11px;
  white-space: nowrap;
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.appbar-nodes-status {
  cursor: help;
}
.appbar-nodes[data-state="online"] .appbar-nodes-status {
  color: var(--text-strong, inherit);
}
.appbar-nodes[data-state="offline"] .appbar-nodes-status,
.appbar-nodes[data-state="empty"] .appbar-nodes-status {
  opacity: 0.7;
}

.appbar-nodes-info {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  padding: 0;
  font: inherit;
  font-size: 10px;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid rgba(148, 163, 184, 0.4);
  border-radius: 50%;
  cursor: pointer;
  line-height: 1;
}
.appbar-nodes-info:hover {
  color: var(--text-strong, inherit);
  border-color: rgba(148, 163, 184, 0.8);
}

.appbar-nodes-popover {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  min-width: 380px;
  max-width: min(720px, 90vw);
  padding: 10px 12px;
  background: var(--bg-panel, #0f172a);
  color: var(--text-strong, #e2e8f0);
  border: 1px solid rgba(148, 163, 184, 0.3);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  font-size: 11px;
  white-space: normal;
}
.appbar-nodes-empty {
  margin: 0;
  color: var(--text-muted);
}
.appbar-nodes-table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}
.appbar-nodes-table th,
.appbar-nodes-table td {
  text-align: left;
  padding: 4px 8px;
  border-bottom: 1px solid rgba(148, 163, 184, 0.15);
}
.appbar-nodes-table thead th {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
}
.appbar-nodes-table tfoot td {
  font-weight: 600;
  border-bottom: none;
  border-top: 1px solid rgba(148, 163, 184, 0.3);
}
.appbar-nodes-table tr.offline {
  opacity: 0.55;
}

.appbar-nodes-users {
  color: var(--text-muted);
  cursor: help;
}
.appbar-nodes-section + .appbar-nodes-section {
  margin-top: 12px;
}
.appbar-nodes-h {
  margin: 0 0 4px 0;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
}
.appbar-nodes-users-table {
  font-size: 11px;
}

.appbar-toggle {
  background: transparent;
  border: 1px solid rgba(148, 163, 184, 0.3);
  color: var(--text-muted);
  font: inherit;
  font-size: 10px;
  padding: 2px 8px;
  border-radius: 3px;
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.appbar-toggle:hover {
  color: var(--text-strong, inherit);
  border-color: rgba(148, 163, 184, 0.6);
}
.appbar-toggle[aria-pressed="false"] {
  opacity: 0.5;
}

.appbar-auth {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.appbar-login {
  color: var(--accent);
  text-decoration: none;
  padding: 1px 8px;
  border: 1px solid rgba(34, 211, 238, 0.4);
  border-radius: 3px;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 1px;
}
.appbar-login:hover {
  background: rgba(34, 211, 238, 0.1);
  text-shadow: 0 0 6px rgba(34, 211, 238, 0.4);
}

.appbar-user {
  color: var(--text);
  padding: 1px 8px;
  border: 1px solid var(--border);
  border-radius: 3px;
  background: rgba(34, 211, 238, 0.06);
}

.appbar-logout {
  background: none;
  border: 1px solid var(--border);
  border-radius: 3px;
  color: var(--text-muted);
  font: inherit;
  cursor: pointer;
  padding: 0 6px;
  line-height: 18px;
}
.appbar-logout:hover { color: var(--accent-hot); border-color: var(--accent-hot); }

/* ─── Login page ────────────────────────────────────────────────────
   Fullscreen sign-in shown to unauthenticated visitors at /. Same
   palette as the IDE; the card sits over the body's radial gradient
   so the cyberpunk "sparks" composition reads through. */
.login-body {
  /* Body bg already has the radial gradients defined globally; we
     just need a centred flex container. */
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

.login-card {
  width: 100%;
  max-width: 460px;
  padding: 40px 36px 32px;
  background: linear-gradient(180deg, rgba(34, 211, 238, 0.04), transparent),
              var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow:
    0 0 0 1px rgba(34, 211, 238, 0.06) inset,
    0 30px 70px rgba(0, 0, 0, 0.55),
    0 0 60px rgba(34, 211, 238, 0.08);
  text-align: center;
  position: relative;
  overflow: hidden;
}

/* Thin animated scan-line across the top edge — subtle, doesn't loop
   fast enough to distract. */
.login-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  opacity: 0.7;
}

.login-brand {
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: 2.2px;
  margin-bottom: 28px;
}
.login-brand-name {
  color: var(--accent-hot);
  text-shadow: 0 0 12px rgba(251, 146, 60, 0.45);
}
.login-brand-slash {
  color: var(--text-muted);
  margin: 0 8px;
  font-weight: 400;
}
.login-brand-sub {
  color: var(--text);
  font-weight: 400;
  text-transform: lowercase;
  letter-spacing: 1px;
}

.login-lede {
  color: var(--text-muted);
  font-size: 14px;
  line-height: 1.6;
  margin-bottom: 28px;
}

.login-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  padding: 14px 20px;
  background: var(--accent);
  color: #061018;
  text-decoration: none;
  font-weight: 700;
  letter-spacing: 0.6px;
  border-radius: 8px;
  font-size: 14px;
  box-shadow: 0 0 20px rgba(34, 211, 238, 0.35);
  transition: filter 0.15s, box-shadow 0.15s, transform 0.05s;
}
.login-cta:hover { filter: brightness(1.08); box-shadow: 0 0 28px rgba(34, 211, 238, 0.55); }
.login-cta:active { transform: translateY(1px); }

.login-cta-icon {
  font-size: 18px;
  line-height: 1;
}

.login-foot {
  margin-top: 24px;
  font-size: 12px;
  color: var(--text-muted);
}
.login-foot a {
  color: var(--accent);
  text-decoration: none;
}
.login-foot a:hover { text-decoration: underline; }

/* ─── Admin dashboard ─── */
.admin-body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.admin-top {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-surface);
}

.admin-back {
  color: var(--text-muted);
  text-decoration: none;
  font-size: 13px;
}
.admin-back:hover { color: var(--accent); }

.admin-title {
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--accent-hot);
  text-shadow: 0 0 10px rgba(251, 146, 60, 0.35);
}

.admin-spacer { flex: 1; }

.admin-logout {
  color: var(--text-muted);
  text-decoration: none;
  font-size: 12px;
  border: 1px solid var(--border);
  padding: 4px 10px;
  border-radius: 4px;
}
.admin-logout:hover { color: var(--accent-hot); border-color: var(--accent-hot); }

.admin-main {
  flex: 1;
  padding: 24px 20px;
  max-width: 1400px;
  width: 100%;
  margin: 0 auto;
}

.admin-section {
  margin-bottom: 36px;
}

.admin-section-head {
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin-bottom: 14px;
}

.admin-section-head h2 {
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--accent);
  text-shadow: 0 0 6px rgba(34, 211, 238, 0.3);
}

.admin-count {
  color: var(--text-muted);
  font-weight: 400;
  font-size: 11px;
  margin-left: 4px;
}

.admin-btn {
  background: var(--accent);
  color: #061018;
  border: none;
  padding: 6px 14px;
  border-radius: 4px;
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.5px;
  cursor: pointer;
  margin-left: auto;
  box-shadow: 0 0 12px rgba(34, 211, 238, 0.25);
}
.admin-btn:hover { filter: brightness(1.1); box-shadow: 0 0 18px rgba(34, 211, 238, 0.45); }

.admin-btn-revoke {
  background: transparent;
  color: var(--accent-hot);
  border: 1px solid var(--accent-hot);
  margin-left: 0;
  box-shadow: none;
}
.admin-btn-revoke:hover {
  background: rgba(251, 146, 60, 0.15);
  box-shadow: 0 0 10px rgba(251, 146, 60, 0.3);
}

.admin-empty {
  color: var(--text-muted);
  font-size: 13px;
  padding: 14px;
  background: var(--bg-surface);
  border: 1px dashed var(--border);
  border-radius: 6px;
}

.admin-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  font-size: 13px;
}
.admin-table th {
  text-align: left;
  padding: 10px 12px;
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--text-muted);
  background: rgba(34, 211, 238, 0.04);
  border-bottom: 1px solid var(--border);
}
.admin-table td {
  padding: 10px 12px;
  border-bottom: 1px solid rgba(28, 53, 83, 0.5);
}
.admin-table tbody tr:last-child td { border-bottom: none; }
.admin-table tbody tr:hover { background: rgba(34, 211, 238, 0.04); }

.admin-mono {
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
  font-size: 12px;
}

.admin-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 3px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
}
.admin-pill-online {
  background: rgba(34, 211, 238, 0.15);
  color: var(--accent);
  border: 1px solid rgba(34, 211, 238, 0.4);
}
.admin-pill-offline {
  background: rgba(108, 112, 134, 0.15);
  color: var(--text-muted);
  border: 1px solid var(--border);
}
.admin-pill-revoked {
  background: rgba(251, 146, 60, 0.12);
  color: var(--accent-hot);
  border: 1px solid rgba(251, 146, 60, 0.4);
}

/* Token dialog */
.admin-dialog {
  background: var(--bg-surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 24px;
  min-width: 380px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}
.admin-dialog::backdrop { background: rgba(0, 0, 0, 0.6); backdrop-filter: blur(3px); }
.admin-dialog h3 {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 14px;
  letter-spacing: 1.2px;
  color: var(--accent);
  text-transform: uppercase;
  margin-bottom: 18px;
}
.admin-dialog label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 11px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  margin-bottom: 12px;
}
.admin-dialog input {
  background: var(--bg-base);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 8px 10px;
  font: inherit;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 13px;
  text-transform: none;
}
.admin-dialog input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--glow-accent);
}
.admin-dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 16px;
}
.admin-dialog-actions button {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
  padding: 6px 14px;
  border-radius: 4px;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.admin-dialog-actions button.admin-btn {
  background: var(--accent);
  border-color: var(--accent);
  color: #061018;
  font-weight: 700;
}
.admin-token-cmd {
  background: var(--bg-base);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 10px 12px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 12px;
  white-space: pre-wrap;
  word-break: break-all;
  color: var(--accent);
  margin: 12px 0;
}
.admin-token-hint {
  color: var(--text-muted);
  font-size: 12px;
  margin-top: 12px;
}
.hidden { display: none !important; }

/* Appbar admin link (next to user pill) */
.appbar-admin {
  color: var(--accent-hot);
  text-decoration: none;
  padding: 1px 8px;
  border: 1px solid rgba(251, 146, 60, 0.4);
  border-radius: 3px;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 1px;
}
.appbar-admin:hover {
  background: rgba(251, 146, 60, 0.12);
  text-shadow: 0 0 6px rgba(251, 146, 60, 0.4);
}

/* ─── Activity-bar admin button — orange to match the brand wordmark. */
.ab-btn-admin {
  color: var(--accent-hot);
}
.ab-btn-admin.active {
  color: var(--accent-hot);
  text-shadow: 0 0 8px rgba(251, 146, 60, 0.45);
}

/* ─── Compute nodes panel (sidebar) ─── */
.panel-nodes .nodes-list {
  flex: 1;
  overflow-y: auto;
  padding: 6px 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.nodes-loading, .nodes-empty, .nodes-error {
  font-size: 12px;
  color: var(--text-muted);
  padding: 10px;
  text-align: center;
}
.nodes-error { color: var(--accent-hot); }

.node-row {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-left: 3px solid var(--text-muted);
  border-radius: 6px;
  padding: 8px 10px;
  font-size: 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.node-row.node-online    { border-left-color: var(--accent); }
.node-row.node-offline   { border-left-color: var(--text-muted); opacity: 0.7; }
.node-row.node-revoked   { border-left-color: var(--accent-hot); opacity: 0.6; }

.node-row-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}
.node-name {
  font-weight: 700;
  color: var(--text);
}
.node-state {
  font-size: 9px;
  letter-spacing: 1px;
  padding: 1px 6px;
  border-radius: 2px;
}
.node-online    .node-state { color: var(--accent);     background: rgba(34, 211, 238, 0.12); }
.node-offline   .node-state { color: var(--text-muted); background: rgba(108, 112, 134, 0.15); }
.node-revoked   .node-state { color: var(--accent-hot); background: rgba(251, 146, 60, 0.12); }

.node-row-meta {
  display: flex;
  gap: 10px;
  font-size: 11px;
  color: var(--text-muted);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}

.node-row-loaded {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 10px;
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
}
.loaded-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 6px;
  border-radius: 3px;
  background: rgba(108, 112, 134, 0.18);
  color: var(--text-muted);
  border: 1px solid var(--border);
}
.loaded-chip em {
  font-style: normal;
  font-size: 9px;
  opacity: 0.8;
}
.loaded-chip.loaded-gpu {
  background: rgba(34, 211, 238, 0.12);
  color: var(--accent);
  border-color: rgba(34, 211, 238, 0.4);
}
.loaded-chip.loaded-mixed {
  background: rgba(251, 146, 60, 0.10);
  color: var(--accent-hot);
  border-color: rgba(251, 146, 60, 0.4);
}
.loaded-chip.loaded-cpu {
  background: rgba(243, 139, 168, 0.10);
  color: #f38ba8;
  border-color: rgba(243, 139, 168, 0.4);
}
.loaded-empty {
  color: var(--text-muted);
  font-size: 10px;
  opacity: 0.6;
}

/* VRAM gauge — thin bar with fill colored by current usage. */
.node-vram {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 10px;
  color: var(--text-muted);
}
.node-vram-label {
  font-size: 9px;
  letter-spacing: 0.5px;
  width: 30px;
}
.node-vram-bar {
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background: var(--bg-base);
  overflow: hidden;
}
.node-vram-fill {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--accent-hot));
  transition: width 0.6s ease;
}
.node-vram-text {
  font-variant-numeric: tabular-nums;
  min-width: 90px;
  text-align: right;
}

/* ─── Splash pane: shown in the editor area when no file is open. ─── */
.splash-pane {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 32px;
  padding: 40px 24px;
  overflow-y: auto;
  background-image: 
    linear-gradient(rgba(34, 211, 238, 0.02) 1px, transparent 1px),
    linear-gradient(90deg, rgba(34, 211, 238, 0.02) 1px, transparent 1px);
  background-size: 20px 20px;
  background-position: center;
}
.splash-pane.hidden { display: none; }

.splash-head { text-align: center; }

@keyframes float {
  0% { transform: translateY(0px) rotate(0deg); }
  50% { transform: translateY(-8px) rotate(2deg); }
  100% { transform: translateY(0px) rotate(0deg); }
}

.splash-rocket {
  font-size: 56px;
  line-height: 1;
  margin-bottom: 16px;
  animation: float 4s ease-in-out infinite;
  display: inline-block;
  filter: drop-shadow(0 0 12px rgba(34, 211, 238, 0.35));
}
.splash-title {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 22px;
  font-weight: 400;
  letter-spacing: 1.2px;
  color: var(--text);
  margin-bottom: 6px;
}
.splash-title-accent {
  color: var(--accent-hot);
  font-weight: 700;
  text-shadow: 0 0 10px rgba(251, 146, 60, 0.35);
}
.splash-sub {
  color: var(--text-muted);
  font-size: 14px;
}

.splash-grid {
  /* 8 personas → 4×2 on wide screens, 2×4 on medium, 1×8 on narrow.
     Fixed 4-column layout when there's room keeps the bottom row
     balanced (4+4) instead of stranded (5+3). */
  display: grid;
  grid-template-columns: repeat(4, minmax(180px, 1fr));
  gap: 16px;
  width: 100%;
  max-width: 920px;
}
@media (max-width: 880px) {
  .splash-grid { grid-template-columns: repeat(2, minmax(180px, 1fr)); }
}
@media (max-width: 440px) {
  .splash-grid { grid-template-columns: 1fr; }
}

.splash-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 12px;
  padding: 24px 16px 20px;
  background: rgba(12, 26, 44, 0.65);
  border: 1px solid rgba(34, 211, 238, 0.08);
  border-radius: 12px;
  color: var(--text);
  font: inherit;
  cursor: pointer;
  backdrop-filter: blur(8px);
  position: relative;
  overflow: hidden;
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), 
              box-shadow 0.25s cubic-bezier(0.4, 0, 0.2, 1), 
              border-color 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.splash-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0; height: 3px;
  background: var(--persona-color, var(--accent));
  opacity: 0;
  transition: opacity 0.25s ease;
}

.splash-card:hover::before {
  opacity: 0.85;
}

.splash-card:hover {
  transform: translateY(-5px);
  border-color: var(--persona-color, var(--accent));
  box-shadow: 
    0 10px 20px rgba(0, 0, 0, 0.4),
    0 0 15px color-mix(in srgb, var(--persona-color, var(--accent)) 25%, transparent);
}
.splash-card.active {
  border-color: var(--persona-color, var(--accent));
  box-shadow: 
    0 0 15px color-mix(in srgb, var(--persona-color, var(--accent)) 30%, transparent),
    inset 0 0 10px color-mix(in srgb, var(--persona-color, var(--accent)) 10%, transparent);
  background: rgba(12, 26, 44, 0.85);
}
.splash-card.active::before {
  opacity: 1;
}

.splash-card-icon {
  font-size: 32px;
  line-height: 1;
  background: rgba(255, 255, 255, 0.03);
  width: 56px;
  height: 56px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(255, 255, 255, 0.06);
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), 
              border-color 0.25s cubic-bezier(0.4, 0, 0.2, 1), 
              background-color 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
.splash-card:hover .splash-card-icon {
  transform: scale(1.1);
  border-color: var(--persona-color, var(--accent));
  background: color-mix(in srgb, var(--persona-color, var(--accent)) 8%, transparent);
}

.splash-card-name {
  font-weight: 700;
  font-size: 15px;
  color: var(--persona-color, var(--text));
  letter-spacing: 0.3px;
}
.splash-card-tagline {
  font-size: 11px;
  color: var(--text-muted);
  line-height: 1.45;
}

/* Pikanäppäin-rozet — pieni teksti kortin oikeassa yläkulmassa,
   näkyy hover:lla kirkkaampana. */
.splash-card-key {
  position: absolute;
  top: 8px;
  right: 8px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: 0.5px;
  color: var(--text-muted);
  opacity: 0.5;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 4px;
  padding: 1px 4px;
  transition: opacity 0.15s, color 0.15s, border-color 0.15s;
}
.splash-card:hover .splash-card-key {
  opacity: 1;
  color: var(--persona-color, var(--accent));
  border-color: var(--persona-color, var(--accent));
}

.splash-hint {
  color: var(--text-muted);
  font-size: 12px;
  margin-top: 6px;
}

.node-row-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 10px;
  color: var(--text-muted);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  gap: 8px;
}
.node-pubkey {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.node-revoke {
  background: transparent;
  color: var(--accent-hot);
  border: 1px solid var(--accent-hot);
  border-radius: 3px;
  padding: 1px 8px;
  font: inherit;
  font-size: 10px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  cursor: pointer;
}
.node-revoke:hover {
  background: rgba(251, 146, 60, 0.15);
  box-shadow: 0 0 8px rgba(251, 146, 60, 0.3);
}

.nodes-actions {
  padding: 8px 10px;
  border-top: 1px solid var(--border);
}
.nodes-new-token {
  width: 100%;
  background: var(--accent);
  color: #061018;
  border: none;
  border-radius: 4px;
  padding: 8px 12px;
  font: inherit;
  font-weight: 700;
  letter-spacing: 0.5px;
  font-size: 11px;
  cursor: pointer;
  text-transform: uppercase;
  box-shadow: 0 0 10px rgba(34, 211, 238, 0.25);
}
.nodes-new-token:hover {
  filter: brightness(1.1);
  box-shadow: 0 0 16px rgba(34, 211, 238, 0.45);
}

/* Token dialog — small, matches sidebar look. */
.nodes-dialog {
  background: var(--bg-surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 20px 22px;
  min-width: 340px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}
.nodes-dialog::backdrop { background: rgba(0, 0, 0, 0.55); backdrop-filter: blur(3px); }
.nodes-dialog h3 {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 12px;
  letter-spacing: 1.4px;
  color: var(--accent);
  text-transform: uppercase;
  margin-bottom: 14px;
}
.nodes-dialog label {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 10px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  margin-bottom: 10px;
}
.nodes-dialog input {
  background: var(--bg-base);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 6px 8px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 12px;
  text-transform: none;
}
.nodes-dialog input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--glow-accent);
}
.nodes-dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 6px;
  margin-top: 12px;
}
.nodes-dialog-actions button {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
  padding: 5px 12px;
  border-radius: 4px;
  font-size: 11px;
  cursor: pointer;
}
.nodes-dialog-actions .nodes-btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #061018;
  font-weight: 700;
}
.nodes-token-cmd {
  background: var(--bg-base);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 8px 10px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  white-space: pre-wrap;
  word-break: break-all;
  color: var(--accent);
  margin: 8px 0;
}
.nodes-token-hint {
  color: var(--text-muted);
  font-size: 11px;
}

/* ─── Activity bar ─── */
.activity-bar {
  width: 48px;
  flex-shrink: 0;
  background: var(--bg-glass);
  backdrop-filter: blur(12px);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 8px 0;
  gap: 6px;
}

.ab-btn {
  width: 38px;
  height: 38px;
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 18px;
  cursor: pointer;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  position: relative;
  transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.ab-btn::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%) scaleY(0);
  width: 3px;
  height: 14px;
  background: var(--accent);
  border-radius: 0 4px 4px 0;
  transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1), height 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

.ab-btn:hover::before {
  transform: translateY(-50%) scaleY(0.6);
}

.ab-btn:hover {
  background: rgba(255, 255, 255, 0.04);
  color: var(--text);
  transform: scale(1.05);
}

.ab-btn.active {
  color: var(--accent);
  background: rgba(34, 211, 238, 0.08);
  box-shadow: inset 0 0 10px rgba(34, 211, 238, 0.08);
  border: 1px solid rgba(34, 211, 238, 0.15);
}

.ab-btn.active::before {
  transform: translateY(-50%) scaleY(1);
  height: 20px;
}

.ab-btn-bottom {
  margin-top: auto;
}

/* ─── Sidebar ─── */
.sidebar {
  width: 240px;
  flex-shrink: 0;
  background: var(--bg-surface);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
}

.sidebar.hidden {
  display: none;
}

.panel {
  display: none;
  flex-direction: column;
  height: 100%;
}

.panel.active {
  display: flex;
}

.panel-header {
  padding: 14px 16px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
}

.panel-content {
  flex: 1;
  overflow-y: auto;
  padding: 12px 16px;
}

.panel-empty {
  color: var(--text-muted);
  font-size: 13px;
  line-height: 1.6;
}


.persona-list {
  flex: 1;
  overflow-y: auto;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* ─── Files panel ─── */
.files-toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  font-size: 12px;
  color: var(--text-muted);
}

.files-path {
  flex: 1;
  font-family: ui-monospace, SFMono-Regular, monospace;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.files-refresh {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 14px;
  padding: 0 4px;
}
.files-refresh:hover { color: var(--text); }

.files-list {
  flex: 1;
  overflow-y: auto;
  padding: 4px;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.file-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 8px;
  background: none;
  border: none;
  border-radius: 4px;
  color: var(--text);
  font: inherit;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
  width: 100%;
}

.file-item:hover {
  background: var(--bg-elevated);
}

.file-icon { flex-shrink: 0; font-size: 14px; }
.file-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-meta { color: var(--text-muted); font-size: 11px; font-family: ui-monospace, SFMono-Regular, monospace; }

.file-dir .file-name { color: var(--text); }

/* Active-directory indicator. Double-click a folder to make it the
   "working dir" — the New-folder button creates the new entry under
   it, and the toolbar's files-path label echoes its path. */
.file-dir-active {
  background: rgba(34, 211, 238, 0.12);
  border-left: 2px solid var(--accent);
}
.file-dir-active .file-name { font-weight: 600; }

/* Bilingual labels — the document's lang attribute (set by chat-stream.js
   based on the uiLang localStorage value) toggles which copy shows. */
html[lang="en"] .lang-fi { display: none; }
html:not([lang="en"]) .lang-en { display: none; }

/* Workflows panel — markdown files under .aide/workflows/. Each row
   is a click-to-run shortcut that loads the workflow into chat for
   Architect to execute step-by-step. */
.panel-workflows .panel-hint {
  padding: 0 12px 8px;
  margin: 0;
  font-size: 0.8rem;
  color: var(--text-dim, #94a3b8);
  line-height: 1.35;
}
.workflows-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 0 8px 8px;
  overflow-y: auto;
}
.workflows-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 6px 10px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  cursor: pointer;
  color: var(--text);
  font: inherit;
  text-align: left;
}
.workflows-item:hover {
  border-color: var(--accent);
  background: rgba(34, 211, 238, 0.06);
}
.workflows-item-name { font-weight: 500; }
.workflows-item-desc { font-size: 0.8rem; color: var(--text-dim, #94a3b8); }
.workflows-empty {
  padding: 12px;
  color: var(--text-dim, #94a3b8);
  font-size: 0.85rem;
  line-height: 1.4;
}
.workflows-empty code {
  background: rgba(255,255,255,0.05);
  padding: 1px 4px;
  border-radius: 3px;
  font-size: 0.9em;
}

/* Help sidebar — TOC of headings parsed from help.md. Long-form
   content lives in the editor pane via openHelpInEditor(). */
.help-toc {
  display: flex;
  flex-direction: column;
  padding: 6px 8px 12px;
  overflow-y: auto;
  font-size: 0.85rem;
  line-height: 1.4;
}
.help-toc a {
  color: var(--text);
  text-decoration: none;
  padding: 4px 8px;
  border-radius: 4px;
  cursor: pointer;
}
.help-toc a:hover {
  background: rgba(34, 211, 238, 0.08);
  color: var(--accent);
}
.help-toc-h1 { font-weight: 700; margin-top: 8px; }
.help-toc-h2 { padding-left: 16px !important; font-weight: 500; }
.help-toc-h3 { padding-left: 28px !important; color: var(--text-dim, #94a3b8); font-size: 0.8rem; }

/* Mermaid diagrams in the editor/course pane. */
#course-host .mermaid {
  background: rgba(255, 255, 255, 0.02);
  padding: 16px;
  border-radius: 6px;
  margin: 16px 0;
  text-align: center;
  overflow-x: auto;
}
#course-host .mermaid svg {
  max-width: 100%;
  height: auto;
}

/* Help content in editor pane — mermaid + tables get proper styling. */
#course-host[data-content-type="help"] .mermaid {
  background: rgba(255, 255, 255, 0.02);
  padding: 12px;
  border-radius: 6px;
  margin: 16px 0;
  text-align: center;
}
#course-host[data-content-type="help"] table {
  border-collapse: collapse;
  margin: 12px 0;
}
#course-host[data-content-type="help"] th,
#course-host[data-content-type="help"] td {
  border: 1px solid var(--border, #334155);
  padding: 6px 12px;
}

/* @-mention popup — autocompletes file paths under the chat input.
   Anchored to .chat-input-wrap (position:relative) so it floats above
   the textarea without pushing the page layout. */
.chat-input-wrap {
  position: relative;
  flex: 1;
  display: flex;
}
.chat-input-wrap textarea { flex: 1; }
.chat-mention-popup {
  position: absolute;
  bottom: 100%;
  left: 0;
  right: 0;
  margin-bottom: 4px;
  max-height: 200px;
  overflow-y: auto;
  background: var(--panel, #1f2937);
  border: 1px solid var(--accent);
  border-radius: 6px;
  z-index: 30;
  box-shadow: 0 4px 12px rgba(0,0,0,0.4);
}
.chat-mention-item {
  padding: 6px 10px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.85rem;
  color: var(--text);
  cursor: pointer;
}
.chat-mention-item:hover, .chat-mention-item.selected {
  background: rgba(34, 211, 238, 0.15);
}

/* Drag-and-drop upload visuals. The panel gets a glowing cyan border
   on hover; an individual folder row brightens when it's the drop
   target so the user can see where the files will land. */
.panel-tiedostot.drag-over {
  outline: 2px dashed var(--accent);
  outline-offset: -3px;
  background: rgba(34, 211, 238, 0.04);
}
.file-dir.drop-target {
  background: rgba(34, 211, 238, 0.15);
  outline: 1px solid var(--accent);
}

/* Hover-revealed delete button on each file row. Stays invisible
   until the row is hovered so the listing stays clean; the click
   handler stopPropagation's so we don't also open the file. */
.file-item .file-del {
  opacity: 0;
  margin-left: 6px;
  color: var(--text-muted);
  font-size: 13px;
  width: 16px;
  height: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 3px;
  flex-shrink: 0;
  transition: opacity 0.1s, color 0.1s, background 0.1s;
}
.file-item:hover .file-del { opacity: 0.6; }
.file-item .file-del:hover {
  opacity: 1;
  color: var(--accent-hot);
  background: rgba(251, 146, 60, 0.15);
}

/* Drag-source row dims while dragging to make the source/destination
   relationship obvious. */
.file-item.dragging {
  opacity: 0.4;
}
.file-chevron {
  width: 12px;
  flex-shrink: 0;
  color: var(--text-muted);
  font-size: 10px;
  text-align: center;
}
.file-file .file-chevron { visibility: hidden; }

.panel-subhint {
  padding: 8px 16px;
  font-size: 11px;
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
}

.skill-list {
  flex: 1;
  overflow-y: auto;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.skill-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  background: none;
  border: none;
  border-radius: 6px;
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  width: 100%;
  border-left: 3px solid transparent;
}

.skill-item:hover {
  background: var(--bg-elevated);
}

.skill-item[aria-pressed="true"] {
  background: color-mix(in srgb, var(--skill-color, #a6e3a1) 18%, transparent);
  border-left-color: var(--skill-color, #a6e3a1);
  color: var(--text);
}

.skill-item[aria-pressed="true"]:hover {
  background: color-mix(in srgb, var(--skill-color, #a6e3a1) 28%, transparent);
}

.skill-item[aria-pressed="true"] .skill-name {
  color: var(--text);
  font-weight: 500;
}

.skill-icon {
  font-size: 18px;
  flex-shrink: 0;
}

.skill-name {
  flex: 1;
  font-size: 13px;
}

.skill-toggle {
  width: 28px;
  height: 16px;
  border-radius: 8px;
  background: var(--bg-base);
  border: 1px solid var(--border);
  position: relative;
  flex-shrink: 0;
  transition: background 0.15s, border-color 0.15s;
}

.skill-toggle::after {
  content: '';
  position: absolute;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--text-muted);
  top: 2px;
  left: 2px;
  transition: left 0.15s, background 0.15s;
}

.skill-info {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 14px;
  padding: 0 4px;
  line-height: 1;
  opacity: 0.6;
  transition: opacity 0.15s, color 0.15s;
}
.skill-item:hover .skill-info,
.skill-info:focus-visible { opacity: 1; }
.skill-info:hover { color: var(--accent); }

/* Skill spec modal */
.skill-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10001;
  backdrop-filter: blur(4px);
}

.skill-modal-card {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-left: 4px solid var(--skill-color, var(--accent));
  border-radius: 10px;
  max-width: 640px;
  max-height: 80vh;
  width: calc(100% - 32px);
  overflow-y: auto;
  padding: 20px 24px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}

.skill-modal-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}

.skill-modal-icon { font-size: 22px; }
.skill-modal-name {
  flex: 1;
  font-size: 18px;
  font-weight: 600;
}

.skill-modal-close {
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  padding: 0 6px;
}
.skill-modal-close:hover { color: var(--text); }

.skill-modal-desc {
  color: var(--text-muted);
  font-size: 13px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--border);
  padding-bottom: 12px;
}

.skill-modal-tools {
  font-size: 12px;
  color: var(--text-muted);
  margin-bottom: 14px;
}
.skill-modal-tools code {
  background: rgba(255, 255, 255, 0.06);
  padding: 1px 6px;
  border-radius: 3px;
  font-family: ui-monospace, SFMono-Regular, monospace;
  color: var(--text);
  margin-right: 4px;
}

.skill-modal-body { font-size: 13px; }

.skill-item[aria-pressed="true"] .skill-toggle {
  background: var(--skill-color, #a6e3a1);
  border-color: var(--skill-color, #a6e3a1);
}

.skill-item[aria-pressed="true"] .skill-toggle::after {
  left: 14px;
  background: #fff;
}

/* Persona "card" tiles in the Roolit sidebar — match the splash grid's
   identity (icon + colored name + tagline) so switching between the
   splash and the sidebar feels like the same control surface. The
   ::before slab on the left signals the persona color even when the
   tile isn't active; the active state intensifies it. */
.persona-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: 7px;
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  width: 100%;
  position: relative;
  overflow: hidden;
  transition: border-color 0.15s, box-shadow 0.15s, transform 0.05s;
}
.persona-item .persona-text { flex: 1; min-width: 0; }
.persona-item .persona-icon,
.persona-item .persona-info,
.persona-item .persona-edit { flex-shrink: 0; }
.persona-item::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--persona-color, var(--text-muted));
  opacity: 0.55;
  transition: opacity 0.15s;
}
.persona-item:hover {
  border-color: var(--persona-color, var(--accent));
  box-shadow: 0 0 12px color-mix(in srgb, var(--persona-color, var(--accent)) 20%, transparent);
}
.persona-item:hover::before { opacity: 1; }
.persona-item.active {
  border-color: var(--persona-color, var(--accent));
  box-shadow: 0 0 14px color-mix(in srgb, var(--persona-color, var(--accent)) 30%, transparent);
}
.persona-item.active::before { opacity: 1; width: 4px; }

.persona-icon {
  font-size: 20px;
  line-height: 1;
  flex-shrink: 0;
  filter: drop-shadow(0 0 4px color-mix(in srgb, var(--persona-color, var(--accent)) 50%, transparent));
}

.persona-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.persona-name {
  font-size: 13px;
  font-weight: 700;
  color: var(--persona-color, var(--text));
}

.persona-tagline {
  font-size: 10.5px;
  color: var(--text-muted);
  line-height: 1.35;
  white-space: normal;
}

/* ─── Editor pane (center) + Chat pane (right) ─── */
.editor-pane {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  /* min-height: 0 lets the flex children (cm-host, md-preview-host)
     shrink past their content height so they scroll INSIDE the pane
     instead of pushing it taller than the viewport. Without this,
     tall rendered markdown bled past the bottom of the page,
     dragging the appbar with it. */
  min-height: 0;
  background: #282c34; /* one-dark base */
}

/* Rendered markdown preview pane (lazily created from JS). Only
   applies the flex sizing WHEN visible — using :not(.hidden) so
   the generic .hidden { display: none !important } rule still wins
   when the source-mode editor is active. Otherwise both cm-host
   and md-preview-host would stack visible. */
.md-preview-host:not(.hidden) {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 24px 32px;
}

.chat-pane {
  /* Sized to fit the header in one line: persona icon + name + model
     selector + 🧠 + Classic/Zen toggle + 📋 + 💡 + 🗑. Below ~480px
     the persona name was clipping to a bare icon. The resizer still
     lets the operator drag wider for prose-heavy sessions. */
  width: 500px;
  min-width: 500px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  border-left: 1px solid var(--border);
  position: relative;
}
/* On narrow viewports (phones, side-by-side panes), let the chat pane
   collapse to the available width rather than forcing horizontal
   scroll. The header will compact via the persona-name ellipsis. */
@media (max-width: 900px) {
  .chat-pane {
    width: 100%;
    min-width: 0;
  }
}

.chat-pane.hidden { display: none; }

.pane-header {
  display: flex;
  align-items: center;
  gap: 12px;
  height: 44px;
  padding: 0 16px;
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border);
  font-size: 13px;
  /* zen-scope is a position:absolute overlay (z-index 5) covering the
     whole .chat-pane. Without an explicit stacking context the header —
     and the Classic/Zen mode toggle inside it — ends up underneath, so
     a fresh-login user can't click Classic until they've dismissed Zen
     some other way (ESC). Lift the header above the overlay. */
  position: relative;
  z-index: 6;
}

.pane-title {
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
  font-weight: 700;
  color: var(--accent);
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: 1.2px;
  /* Subtle text-shadow gives the "lit LED" feel without making text fuzzy. */
  text-shadow: 0 0 8px rgba(34, 211, 238, 0.35);
}

.chat-pane-persona {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  /* min-width 0 so the inner items can shrink/truncate instead of
     pushing the row taller. Without this the persona name wrapped
     to two lines on narrow chat panes. */
  min-width: 0;
  flex-shrink: 1;
}

.chat-pane-persona #active-persona-icon {
  font-size: 16px;
  flex-shrink: 0;
}

.chat-pane-persona #active-persona-name {
  font-weight: 600;
  /* Ellipsis instead of wrap when the chat pane is narrow. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  flex-shrink: 1;
}

.chat-pane-model {
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 12px;
  color: var(--text-muted);
}

.chat-pane-model-select {
  background: var(--bg-base);
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 2px 6px;
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 12px;
  max-width: 200px;
}

.chat-pane-model-select:hover {
  color: var(--text);
  border-color: var(--accent);
}

.chat-pane-model-select:focus {
  outline: none;
  border-color: var(--accent);
}

.chat-clear-btn {
  background: transparent;
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 2px 8px;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  transition: color 120ms, border-color 120ms;
}

.chat-clear-btn:hover {
  color: var(--persona-warn, #f59e0b);
  border-color: var(--persona-warn, #f59e0b);
}

.zen-btn {
  background: transparent;
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 2px 8px;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  transition: color 120ms, border-color 120ms;
}
.zen-btn:hover,
.shell.zen-mode .zen-btn {
  color: var(--accent);
  border-color: var(--accent);
}

.chat-header-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}

/* ── Mode toggle (Classic / Zen) ────────────────────────────── */
.mode-toggle {
  display: flex;
  background: rgba(12, 26, 44, 0.65);
  border: 1px solid var(--border);
  border-radius: 20px;
  overflow: hidden;
  flex-shrink: 0;
  padding: 2px;
  backdrop-filter: blur(8px);
}
.mode-btn {
  background: transparent;
  color: var(--text-muted);
  border: none;
  padding: 3px 12px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  cursor: pointer;
  letter-spacing: .08em;
  border-radius: 18px;
  transition: background-color 0.25s cubic-bezier(0.4, 0, 0.2, 1), 
              color 0.25s cubic-bezier(0.4, 0, 0.2, 1),
              box-shadow 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
.mode-btn.active {
  background: var(--active-persona-color, var(--accent));
  color: #050b14;
  box-shadow: 0 2px 8px color-mix(in srgb, var(--active-persona-color, var(--accent)) 40%, transparent);
}
.mode-btn:not(.active):hover {
  color: var(--text);
  background: rgba(255, 255, 255, 0.04);
}

/* ── Suggestion chips ────────────────────────────────────────── */
.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}
.chip-btn {
  background: transparent;
  border: 1px solid var(--active-persona-color, var(--accent));
  color: var(--active-persona-color, var(--accent));
  border-radius: 999px;
  padding: 4px 12px;
  font-size: 12px;
  cursor: pointer;
  transition: background 120ms, color 120ms;
  white-space: nowrap;
}
.chip-btn:hover {
  background: var(--active-persona-color, var(--accent));
  color: #07101e;
}
.chip-btn--used {
  opacity: 0.4;
  cursor: default;
  pointer-events: none;
}

/* ── Voice input ─────────────────────────────────────────────────────── */
.mic-btn {
  background: transparent;
  border: none;
  font-size: 18px;
  line-height: 1;
  padding: 0 4px;
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 120ms;
  flex-shrink: 0;
}
.mic-btn:hover { opacity: 1; }
.mic-btn--recording {
  opacity: 1;
  animation: mic-pulse 900ms ease-in-out infinite;
}
@keyframes mic-pulse {
  0%, 100% { filter: drop-shadow(0 0 0px #ef4444); }
  50%       { filter: drop-shadow(0 0 6px #ef4444); }
}
.mic-hint {
  display: none;
  position: absolute;
  bottom: calc(100% + 6px);
  right: 0;
  background: #1e293b;
  color: #94a3b8;
  font-size: 11px;
  padding: 6px 10px;
  border-radius: 6px;
  border: 1px solid #334155;
  max-width: 320px;
  white-space: normal;
  z-index: 20;
  pointer-events: none;
}
.mic-hint--visible { display: block; }

/* ─── Terminal panel (between editor body and statusbar) ─── */
@font-face {
  font-family: 'Symbols Nerd Font Mono';
  src: url('https://cdn.jsdelivr.net/gh/ryanoasis/nerd-fonts@v3.2.1/patched-fonts/NerdFontsSymbolsOnly/SymbolsNerdFontMono-Regular.ttf') format('truetype');
  font-display: swap;
}


.terminal-panel {
  height: 280px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  background: #1e1e2e;
  border-top: 1px solid var(--border);
}

.terminal-panel.hidden { display: none; }

.terminal-header {
  display: flex;
  align-items: center;
  gap: 12px;
  height: 28px;
  padding: 0 12px;
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
  flex-shrink: 0;
}

.terminal-title { font-weight: 600; }

/* Chat-pane project focus bar. Each pin shows as a separate pill —
   user can have multiple folders/files in focus simultaneously,
   click × on any pill to unpin just that one. */
.chat-project-focus {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 6px 10px;
  margin: 0 8px 6px;
}
.chat-project-focus.hidden { display: none; }
.chat-project-focus-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 6px 2px 8px;
  border-radius: 12px;
  background: rgba(99, 102, 241, 0.12);
  border: 1px solid rgba(99, 102, 241, 0.35);
  font-size: 11px;
  color: var(--text);
  max-width: 220px;
}
.chat-project-focus-icon { font-size: 12px; }
.chat-project-focus-path {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.chat-project-focus-clear {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 0 2px;
  line-height: 1;
  font-size: 14px;
}
.chat-project-focus-clear:hover { color: var(--text); }

/* Inline 📌 button on each file/folder row. Sits between the size
   meta and the delete ×. Hidden by default; revealed on hover.
   When the row is pinned, stays visible + highlighted. */
.file-pin {
  opacity: 0;
  margin: 0 4px;
  font-size: 12px;
  cursor: pointer;
  transition: opacity 0.1s;
}
.file-item:hover .file-pin { opacity: 0.7; }
.file-pin:hover { opacity: 1 !important; }
.file-pin.active {
  opacity: 1 !important;
  /* Use color filter so the emoji has a tinted look without
     needing an SVG. */
  filter: drop-shadow(0 0 2px rgba(99, 102, 241, 0.8));
}
.file-item.file-pinned > .file-name {
  color: var(--text);
  font-weight: 500;
}
.file-item.file-pinned {
  background: rgba(99, 102, 241, 0.05);
}


.terminal-status {
  margin-left: auto;
  text-transform: none;
  letter-spacing: 0;
  font-size: 12px;
  padding: 1px 8px;
  border-radius: 10px;
  background: rgba(148, 163, 184, 0.15);
  color: var(--text-muted);
}
.terminal-status[data-kind="ok"] {
  background: rgba(16, 185, 129, 0.18);
  color: #34d399; /* emerald-400 */
}
.terminal-status[data-kind="busy"] {
  background: rgba(245, 158, 11, 0.18);
  color: #fbbf24; /* amber-400 */
}
.terminal-status[data-kind="error"] {
  background: rgba(239, 68, 68, 0.20);
  color: #f87171; /* red-400 */
}

.terminal-close {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 16px;
  padding: 0 6px;
  line-height: 1;
}

.terminal-close:hover { color: var(--text); }

.terminal-body {
  flex: 1;
  min-height: 0;
  padding: 6px 8px;
}

.terminal-body .xterm,
.terminal-body .xterm-viewport,
.terminal-body .xterm-screen {
  height: 100% !important;
}

/* ─── Editor statusbar (bottom of editor pane) ─── */
.editor-statusbar {
  display: flex;
  align-items: center;
  gap: 14px;
  height: 28px;
  padding: 0 12px;
  background: var(--bg-surface);
  border-top: 1px solid var(--border);
  font-size: 12px;
  color: var(--text-muted);
  flex-shrink: 0;
}

.editor-statusbar.hidden { display: none; }

.editor-statusbar .status-item {
  display: flex;
  align-items: center;
  gap: 6px;
}

.editor-statusbar label {
  color: var(--text-muted);
}

.editor-statusbar select {
  background: var(--bg-base);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 1px 6px;
  font: inherit;
  font-size: 11px;
}

.status-stats {
  font-variant-numeric: tabular-nums;
}


/* ─── Keyboard shortcut cheatsheet (hold Cmd/Ctrl to reveal) ─── */
#shortcut-cheatsheet {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: rgba(30, 30, 46, 0.95);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 24px 28px;
  z-index: 10000;
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.5);
  opacity: 0;
  transition: opacity 0.15s;
  pointer-events: none;
  min-width: 320px;
}

#shortcut-cheatsheet.visible { opacity: 1; }

#shortcut-cheatsheet .cheatsheet-title {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-bottom: 14px;
}

#shortcut-cheatsheet table {
  font-size: 13px;
  border-spacing: 0;
  width: 100%;
}

#shortcut-cheatsheet td.key {
  padding: 6px 24px 6px 0;
  font-family: ui-monospace, SFMono-Regular, monospace;
  color: #a6e3a1;
  white-space: nowrap;
  font-size: 12px;
}

#shortcut-cheatsheet td.desc {
  padding: 6px 0;
  color: var(--text);
}

.cm-host {
  flex: 1;
  overflow: hidden;
}

/* ─── Editor tabs (between pane-header and CodeMirror) ─── */
.editor-tabs {
  display: flex;
  align-items: stretch;
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  flex-shrink: 0;
}

.editor-tabs.empty { display: none; }
.editor-tabs.hidden { display: none; }

/* Markdown source/preview toggle — small button at the right end of
   the tab row, only shown when the active file is .md. Without
   explicit styling the browser rendered it with the default white
   <button> background, which clashed with the dark tab row. */
.editor-md-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px 8px;
  margin-left: auto;
  background: transparent;
  border: none;
  border-left: 1px solid var(--border);
  color: var(--text-muted);
  cursor: pointer;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 13px;
  line-height: 1;
}
.editor-md-toggle:hover {
  background: var(--bg-elev);
  color: var(--text);
}

.editor-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 6px 6px 12px;
  background: transparent;
  border: none;
  border-right: 1px solid var(--border);
  color: var(--text-muted);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
  white-space: nowrap;
  user-select: none;
}

.editor-tab:hover { color: var(--text); }

.editor-tab.active {
  background: #282c34;
  color: var(--text);
}

.editor-tab.stale {
  opacity: 0.55;
}

.editor-tab.stale .editor-tab-name {
  text-decoration: line-through;
  text-decoration-color: rgba(243, 139, 168, 0.7);
}

.editor-tab-warn {
  color: #f9e2af;
  font-size: 11px;
  margin-right: 2px;
}

.editor-tab.active .editor-tab-name { font-weight: 500; }

.editor-tab-name { padding-right: 2px; }

.editor-tab-close {
  display: inline-flex;
  width: 18px;
  height: 18px;
  align-items: center;
  justify-content: center;
  border-radius: 3px;
  border: none;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 0;
}

.editor-tab-close:hover {
  background: rgba(255, 255, 255, 0.10);
  color: var(--text);
}

.cm-host.hidden, .course-host.hidden, .editor-toolbar.hidden, .course-toolbar.hidden {
  display: none !important;
}

/* ─── Course reader ─── */
.course-toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
  font-size: 12px;
  color: var(--text-muted);
}

#course-breadcrumb {
  font-size: 13px;
  color: var(--text);
  font-weight: 500;
  max-width: 380px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.course-lang-btn, .pane-close {
  background: var(--bg-base);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 4px 10px;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}

.course-lang-btn:hover, .pane-close:hover {
  background: var(--bg-elevated);
}

.pane-close {
  padding: 0;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  line-height: 1;
}

.course-host {
  flex: 1;
  overflow-y: auto;
  padding: 32px 48px;
  background: var(--bg-base);
  color: var(--text);
}

.course-loading {
  color: var(--text-muted);
  font-size: 13px;
}

/* ─── Course list (sidebar) ─── */
.course-list {
  flex: 1;
  overflow-y: auto;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* Sidebar category headings — one row per distinct course.category
   ("Kurssit", "Projektit"). Separates groups without taking too much
   vertical space; first heading gets no top margin. */
.course-category-heading {
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim, #94a3b8);
  padding: 6px 8px 4px;
  margin-top: 10px;
  border-top: 1px solid rgba(148, 163, 184, 0.12);
}
.course-list > .course-category-heading:first-child {
  margin-top: 0;
  border-top: none;
}

.course-item {
  background: var(--bg-elevated);
  border-radius: 6px;
  overflow: hidden;
}

.course-summary {
  padding: 8px 10px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  list-style: none;
}

.course-summary::-webkit-details-marker { display: none; }
.course-summary::before {
  content: '▸';
  display: inline-block;
  margin-right: 6px;
  color: var(--text-muted);
  transition: transform 0.15s;
}
.course-item[open] .course-summary::before {
  transform: rotate(90deg);
}

.course-toc {
  padding: 4px 6px 8px;
}

.course-section-title {
  padding: 6px 8px 4px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
}

.course-page-btn {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  border-radius: 4px;
  color: var(--text);
  padding: 5px 8px;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}

.course-page-btn:hover {
  background: var(--bg-surface);
}

.course-page-btn.active {
  background: var(--accent);
  color: white;
}

/* ─── Rendered markdown (chat messages + course pages) ─── */
.markdown-body { line-height: 1.7; }

/* Cap rendered markdown to a readable column when shown inside the
   editor pane (md preview tab or course reader). Chat-bubble markdown
   keeps the bubble's natural width — only the editor-pane variant
   needs the cap because on wide monitors the pane stretches to
   thousands of pixels and the prose looks like a billboard. */
.editor-pane .markdown-body > *,
#md-preview-host.markdown-body > *,
.course-host.markdown-body > * {
  max-width: 1100px;
  margin-left: auto;
  margin-right: auto;
}

/* Images / video / SVG / iframe in rendered markdown must not overflow
   the container. Native dimensions on a wide floor plan, screenshot,
   etc. would otherwise force horizontal scroll across the whole
   editor pane. `height: auto` preserves aspect ratio. */
.markdown-body img,
.markdown-body video,
.markdown-body svg,
.markdown-body iframe {
  max-width: 100%;
  height: auto;
  display: block;
}
/* Wide code blocks (e.g. a long terminal paste) scroll horizontally
   inside themselves instead of pushing the whole pane wide. */
.markdown-body pre {
  max-width: 100%;
  overflow-x: auto;
}
.markdown-body h1 { font-size: 1.8em; margin: 0.6em 0 0.4em; font-weight: 700; }
.markdown-body h2 { font-size: 1.5em; margin: 1em 0 0.4em; font-weight: 700; }
.markdown-body h3 { font-size: 1.2em; margin: 0.8em 0 0.3em; font-weight: 600; }
.markdown-body h4 { font-size: 1.0em; margin: 0.6em 0 0.3em; font-weight: 600; }
.markdown-body p { margin: 0.6em 0; }
.markdown-body ul, .markdown-body ol { margin: 0.4em 0 0.6em; padding-left: 1.6em; }
.markdown-body li { margin: 0.2em 0; }
.markdown-body li > p { margin: 0; }
.markdown-body code:not(pre code) {
  background: rgba(120, 130, 150, 0.18);
  padding: 1px 5px;
  border-radius: 3px;
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 0.9em;
}
.markdown-body pre {
  background: #282c34;
  border-radius: 6px;
  padding: 12px 14px;
  overflow-x: auto;
  margin: 0.6em 0;
  font-size: 13px;
  position: relative;
}

.code-copy {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 5px;
  color: #cdd6f4;
  padding: 0;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 0.15s, background 0.15s, color 0.15s, border-color 0.15s;
}

.code-copy svg { display: block; }

.markdown-body pre:hover .code-copy,
.message-content pre:hover .code-copy,
.code-copy:focus-visible,
.code-copy:hover {
  opacity: 1;
}

.code-copy:hover {
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.22);
  color: #fff;
}

.code-copy.ok {
  opacity: 1;
  color: #a6e3a1;
  border-color: rgba(166, 227, 161, 0.4);
}

.code-copy.err {
  opacity: 1;
  color: #f38ba8;
  border-color: rgba(243, 139, 168, 0.4);
}
.markdown-body pre code {
  font-family: ui-monospace, SFMono-Regular, "JetBrains Mono", monospace;
  color: #abb2bf;
}
.markdown-body blockquote {
  border-left: 3px solid var(--accent);
  padding: 4px 12px;
  margin: 0.6em 0;
  color: var(--text-muted);
}
.markdown-body a {
  color: var(--accent);
  text-decoration: none;
}
.markdown-body a:hover { text-decoration: underline; }
.markdown-body table {
  border-collapse: collapse;
  margin: 0.8em 0;
}
.markdown-body th, .markdown-body td {
  border: 1px solid var(--border);
  padding: 6px 10px;
  text-align: left;
}
.markdown-body th { background: var(--bg-elevated); }

/* ─── Admonitions (course pages use :::objective / :::tip / etc.) ─── */
.markdown-body .admonition {
  /* The .course-host > * centering rule applies max-width to top-level
     paragraphs / lists, but admonitions render as <aside> which marked
     emits as raw HTML — in some environments those don't pick up the
     direct-child rule, so we anchor max-width here too. Matches the
     1100 px column the rest of the prose uses. */
  max-width: 1100px;
  margin: 1em auto;
  padding: 14px 16px 14px 18px;
  border-left: 4px solid var(--accent);
  border-radius: 4px;
  background: rgba(59, 130, 246, 0.10);
  color: var(--text);
}

.markdown-body .admonition-title {
  font-weight: 700;
  font-size: 0.9em;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-bottom: 6px;
  color: var(--accent);
}

.markdown-body .admonition-objective { border-color: #3b82f6; background: rgba(59, 130, 246, 0.10); }
.markdown-body .admonition-objective .admonition-title { color: #60a5fa; }

.markdown-body .admonition-tip { border-color: #10b981; background: rgba(16, 185, 129, 0.10); }
.markdown-body .admonition-tip .admonition-title { color: #34d399; }

.markdown-body .admonition-warning { border-color: #f59e0b; background: rgba(245, 158, 11, 0.10); }
.markdown-body .admonition-warning .admonition-title { color: #fbbf24; }

.markdown-body .admonition-infobox { border-color: #818cf8; background: rgba(129, 140, 248, 0.10); }
.markdown-body .admonition-infobox .admonition-title { color: #a5b4fc; }

.markdown-body .admonition-exercise { border-color: #38bdf8; background: rgba(56, 189, 248, 0.10); }
.markdown-body .admonition-exercise .admonition-title { color: #7dd3fc; }

.markdown-body .admonition p:first-child { margin-top: 0; }
.markdown-body .admonition p:last-child { margin-bottom: 0; }

/* Vertical resize handles between sidebar/editor and editor/chat.
   4 px wide, transparent until hover so they don't visually break
   up the layout. Width persists per-pane in localStorage via
   pane-resizers.js. */
.pane-resizer {
  flex: 0 0 4px;
  cursor: col-resize;
  background: transparent;
  position: relative;
  z-index: 5;
}
.pane-resizer:hover,
.pane-resizer.active {
  background: var(--accent, #6366f1);
}
/* Hide the handle when its neighbour pane is collapsed — otherwise
   you can grab a 4 px sliver that resizes a hidden element. */
.workspace:has(.sidebar.hidden) .pane-resizer[data-resize="sidebar"],
.workspace:has(.chat-pane.hidden) .pane-resizer[data-resize="chat"] {
  display: none;
}
body.pane-resizing,
body.pane-resizing * {
  user-select: none;
  cursor: col-resize !important;
}

/* Files-panel upload progress strip. Shown while at least one drop
   is in flight; hides itself when the last upload finishes. Single
   aggregate row regardless of how many files are uploading. */
.files-upload-progress {
  padding: 6px 8px 8px;
  border-top: 1px solid var(--border-dim, #1f2937);
  border-bottom: 1px solid var(--border-dim, #1f2937);
  font-size: 0.85em;
  background: var(--surface-elev, #111827);
}
.files-upload-label {
  margin-bottom: 4px;
  color: var(--muted, #9ca3af);
  font-family: var(--font-mono, monospace);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.files-upload-bar {
  height: 4px;
  border-radius: 2px;
  background: var(--border-dim, #1f2937);
  overflow: hidden;
}
.files-upload-bar-fill {
  height: 100%;
  width: 0%;
  background: var(--accent, #6366f1);
  transition: width 0.15s linear;
}

/* 🧠 toggle next to the model picker — bright when thinking is on,
   dimmed when off. Per-persona state persists in localStorage. */
.think-toggle {
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  padding: 2px 6px;
  margin-left: 4px;
  cursor: pointer;
  font-size: 1.1em;
  line-height: 1;
  opacity: 0.35;
  filter: grayscale(1);
  transition: opacity 0.15s, filter 0.15s, border-color 0.15s;
}
.think-toggle:hover { opacity: 0.7; }
.think-toggle.active {
  opacity: 1;
  filter: none;
  border-color: var(--accent-dim, #6366f1);
}

/* Streaming reasoning trail. Sits above the assistant's main content;
   <details> is open while tokens stream in, auto-closes on `done` so
   the answer becomes focal. Click the summary to re-expand. */
.message-thinking {
  margin: 0 0 0.6em;
  font-size: 0.85em;
  color: var(--muted, #9ca3af);
  border-left: 2px solid var(--accent-dim, #4b5563);
  padding-left: 0.6em;
}
.message-thinking > summary {
  cursor: pointer;
  user-select: none;
  font-style: italic;
  opacity: 0.75;
  list-style: none;
  outline: none;
}
.message-thinking > summary::before {
  content: '▸ ';
  display: inline-block;
  transition: transform 0.15s ease;
}
.message-thinking[open] > summary::before { transform: rotate(90deg); }
.message-thinking > summary:hover { opacity: 1; }
.message-thinking > pre {
  margin: 0.35em 0 0;
  padding: 0;
  background: transparent;
  border: none;
  font-family: var(--font-mono, monospace);
  font-size: 0.95em;
  white-space: pre-wrap;
  max-height: 14em;
  overflow-y: auto;
  color: inherit;
}
.message-thinking[open] > pre:empty::after {
  content: '▍';
  animation: blink 1s steps(1) infinite;
  opacity: 0.5;
}

/* messages already use white-space: pre-wrap from earlier — undo for markdown */
.message-content.markdown-body { white-space: normal; }
.message-content { white-space: normal; }

/* Chat bubbles use IM-style tight spacing; course reader stays airy. */
.message-content.markdown-body { line-height: 1.35; font-size: 13.5px; }
.message-content p { margin: 0.5em 0; }
.message-content p:empty { display: none; }
.message-content .mermaid-diagram {
  position: relative;
  background: rgba(255,255,255,0.02);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 12px;
  margin: 10px 0;
  text-align: center;
  overflow-x: auto;
  min-height: 60px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.message-content .mermaid-diagram svg {
  max-width: 100%;
  height: auto;
}
.message-content .mermaid-copy {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text-muted);
  cursor: pointer;
  opacity: 0;
  transition: opacity 120ms;
  z-index: 1;
}
.message-content .mermaid-diagram:hover .mermaid-copy { opacity: 1; }
.message-content .mermaid-copy:hover  { color: var(--fg); }
.message-content .mermaid-copy.ok     { color: #a6e3a1; }
.message-content .mermaid-copy.err    { color: #f38ba8; }
.message-content .mermaid {
  background: rgba(255,255,255,0.02);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 16px;
  margin: 10px 0;
  text-align: center;
  overflow-x: auto;
}
.message-content ul,
.message-content ol { margin: 0.2em 0 0.25em; padding-left: 1.4em; }
.message-content li { margin: 0; line-height: 1.4; }
.message-content li > p { margin: 0; }
.message-content li > p + p { margin-top: 0.15em; }
.message-content li + li { margin-top: 0.2em; }
.message-content li > ul li + li,
.message-content li > ol li + li { margin-top: 0.15em; }
.message-content li > ul,
.message-content li > ol { margin: 0.1em 0 0.1em; }

/* Nicer horizontal rule — gradient fade, less harsh than solid */
.message-content hr {
  border: none;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--border) 15%, var(--border) 85%, transparent);
  margin: 1em 0;
}

/* Headings: same blue-white family as body (#d6ecff), brighter by level.
   Hierarchy through brightness only — no color temperature switch. */
.message-content h1,
.message-content h2,
.message-content h3,
.message-content h4 {
  font-weight: 700;
  color: #ecf5ff;
}
.message-content h1,
.message-content h2 {
  margin: 1.25em 0 0.4em;
}
.message-content h3,
.message-content h4 {
  margin: 0.9em 0 0.3em;
}
.message-content h1 { font-size: 1.3em; }
.message-content h2 {
  font-size: 1.2em;
  padding-bottom: 0.2em;
  border-bottom: 1px solid rgba(100, 160, 210, 0.18);
}
.message-content h3 { font-size: 1.05em; color: #daeaf8; }
.message-content h4 { font-size: 1em;    color: #cde0f0; }
.message-content pre {
  position: relative; /* anchor for the absolutely-positioned .code-copy */
  margin: 0.6em 0;
  padding: 6px 44px 6px 10px; /* reserve right padding for the copy button */
  font-size: 12.5px;
  line-height: 1.45;
  background: #282c34;
  border-radius: 6px;
  overflow-x: auto;
}
.message-content blockquote {
  margin: 0.4em 0;
  padding: 0.2em 0.75em;
  border-left: 3px solid rgba(34, 211, 238, 0.35);
  color: var(--text-muted);
}

/* KaTeX display blocks get their own breathing room — they're
   centered by default but inside a tight chat bubble they need a
   bit of vertical air to read */
.markdown-body .math-display {
  margin: 0.5em 0;
  text-align: center;
  overflow-x: auto;
  overflow-y: hidden;
  padding: 4px 0;
}

.markdown-body .katex { font-size: 1em; }
.markdown-body .katex-display { margin: 0; }

/* Inline math inherits text color from surrounding bubble; KaTeX
   uses its own font but should match parent color */
.message-user .katex { color: var(--text); }
.message-content > *:first-child { margin-top: 0; }
.message-content > *:last-child { margin-bottom: 0; }

/* ─── Agent tool trail (above the assistant message bubble content) ─── */
.tool-trail {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 6px;
}

.tool-call {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px;
  padding: 6px 10px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 6px;
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 12px;
  color: var(--text);
}

.tool-call-icon { opacity: 0.7; }
.tool-call-name { color: var(--accent); font-weight: 600; }
.tool-call-args { color: var(--text-muted); overflow-wrap: anywhere; }

/* run_command call: show like a shell prompt */
.run-cmd-label { color: #a6e3a1; }
.tool-call:has(.run-cmd-label) .tool-call-icon {
  color: #a6e3a1;
  opacity: 1;
  font-weight: 700;
}

/* Inline terminal for run_command output */
.inline-terminal {
  width: 100%;
  margin-top: 6px;
  background: #070d14;
  border: 1px solid rgba(255,255,255,0.10);
  border-radius: 6px;
  overflow: hidden;
}
.inline-terminal.err { border-color: rgba(243,139,168,0.35); }
.terminal-output {
  margin: 0;
  padding: 10px 12px;
  font-family: ui-monospace, SFMono-Regular, 'Cascadia Code', monospace;
  font-size: 12px;
  line-height: 1.5;
  color: #cdd6f4;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  max-height: 320px;
  overflow-y: auto;
}
.inline-terminal.err .terminal-output { color: #f38ba8; }

.tool-result {
  width: 100%;
  margin-top: 4px;
  font-size: 12px;
}

.tool-result summary {
  cursor: pointer;
  color: var(--text-muted);
  padding: 2px 0;
  list-style: none;
}

.tool-result summary::-webkit-details-marker { display: none; }
.tool-result summary::before {
  content: '▸';
  display: inline-block;
  width: 12px;
  color: var(--text-muted);
}
.tool-result[open] summary::before { content: '▾'; }

.tool-result.ok summary { color: #a6e3a1; }
.tool-result.err summary { color: #f38ba8; }

.delegate-card {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 6px 10px;
  background: rgba(99, 102, 241, 0.08);
  border: 1px solid rgba(99, 102, 241, 0.25);
  border-radius: 6px;
  font-size: 12px;
  font-family: ui-monospace, SFMono-Regular, monospace;
}
.delegate-card.ok  { border-color: rgba(166, 227, 161, 0.35); background: rgba(166, 227, 161, 0.06); }
.delegate-card.err { border-color: rgba(243, 139, 168, 0.35); background: rgba(243, 139, 168, 0.06); }
.delegate-icon  { font-size: 13px; }
.delegate-skill { color: #a5b4fc; font-weight: 600; }
.delegate-status { color: var(--text-muted); }
.delegate-card.ok  .delegate-status { color: #a6e3a1; }
.delegate-card.err .delegate-status { color: #f38ba8; }

.exercise-card {
  margin: 10px 0;
  padding: 10px 12px;
  border: 1px solid rgba(122, 162, 247, 0.35);
  border-radius: 6px;
  background: rgba(122, 162, 247, 0.06);
}
.exercise-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  margin: -10px -12px 10px -12px;
  background: rgba(122, 162, 247, 0.14);
  border-bottom: 1px solid rgba(122, 162, 247, 0.22);
  border-radius: 5px 5px 0 0;
}
.exercise-task {
  flex: 1;
  font-size: 15px;
  font-weight: 600;
  color: #f9e2af; /* Catppuccin yellow for emphasis */
  line-height: 1.5;
  letter-spacing: 0.01em;
}
.exercise-task::before {
  content: '🎯';
  margin-right: 8px;
  font-size: 14px;
  opacity: 1;
}
.exercise-lang {
  padding: 1px 6px;
  font-size: 10px;
  font-family: ui-monospace, SFMono-Regular, monospace;
  letter-spacing: 0.04em;
  border-radius: 3px;
  background: rgba(122, 162, 247, 0.18);
  color: #a5b4fc;
  text-transform: uppercase;
}
.exercise-editor {
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 8px 10px;
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--fg);
  background: rgba(0, 0, 0, 0.28);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 4px;
  resize: vertical;
  outline: none;
}
.exercise-editor:focus { border-color: rgba(122, 162, 247, 0.55); }
.exercise-editor:disabled { opacity: 0.65; cursor: default; }

/* CodeMirror-backed editor host (preferred when language is supported).
   The fallback textarea above carries its own border + background;
   here the host owns those instead, so CM's stock chrome stays minimal. */
.exercise-editor-host {
  display: block;
  background: rgba(0, 0, 0, 0.28);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 4px;
  overflow: hidden;
}
.exercise-editor-host:focus-within { border-color: rgba(122, 162, 247, 0.55); }
.exercise-editor-host.disabled { opacity: 0.65; pointer-events: none; }
.exercise-editor-host .cm-editor {
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 12.5px;
  line-height: 1.45;
  background: transparent;
  max-height: 360px;
  outline: none;
}
.exercise-editor-host .cm-scroller { padding: 4px 0; }
.exercise-editor-host .cm-content { padding: 4px 10px; }
.exercise-editor-host .cm-gutters { background: transparent; border-right-color: rgba(255,255,255,0.05); }

/* Interactive Terminal overrides */
.exercise-editor-host .xterm {
  padding: 8px 10px;
  background: transparent;
}
.exercise-editor-host .xterm-viewport {
  overflow-y: hidden !important; /* Hide native scrollbar; we want it to fit nicely */
}
.exercise-actions {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}
.exercise-run,
.exercise-submit {
  padding: 5px 14px;
  font-size: 12px;
  font-family: inherit;
  border-radius: 4px;
  background: transparent;
  cursor: pointer;
}
.exercise-run {
  border: 1px solid rgba(166, 227, 161, 0.55);
  color: #a6e3a1;
}
.exercise-run:hover:not(:disabled) {
  background: rgba(166, 227, 161, 0.15);
  color: #cdd6f4;
}
.exercise-submit {
  border: 1px solid rgba(122, 162, 247, 0.55);
  color: #a5b4fc;
}
.exercise-submit:hover:not(:disabled) {
  background: rgba(122, 162, 247, 0.18);
  color: #cdd6f4;
}
.exercise-run:disabled,
.exercise-submit:disabled { opacity: 0.55; cursor: default; }

/* Output pane that appears after the student clicks Aja. ok = green
   left-border, err = red. Wraps and stays in monospace so the raw
   stdout/stderr layout survives. */
.exercise-output {
  margin-top: 8px;
  padding: 6px 10px;
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 12px;
  line-height: 1.4;
  color: var(--fg);
  background: rgba(0, 0, 0, 0.30);
  border-left: 3px solid rgba(255, 255, 255, 0.18);
  border-radius: 3px;
  max-height: 200px;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
}
.exercise-output.ok  { border-left-color: #a6e3a1; }
.exercise-output.err { border-left-color: #f38ba8; }
.exercise-output.hidden { display: none; }

.tool-result pre {
  margin: 4px 0 0;
  padding: 6px 8px;
  background: rgba(0, 0, 0, 0.30);
  border-radius: 4px;
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 11.5px;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 240px;
  overflow-y: auto;
}
.message-user .message-content code:not(pre code) {
  background: rgba(34, 211, 238, 0.14);
  color: inherit;
}
.message-user .message-content pre {
  background: rgba(0, 0, 0, 0.30);
}
.message-user .message-content a {
  color: var(--accent);
  text-decoration: underline;
}


.cm-host .cm-editor {
  height: 100%;
}

.cm-host .cm-scroller {
  font-family: ui-monospace, SFMono-Regular, "JetBrains Mono", monospace;
  font-size: 13px;
}

.messages {
  flex: 1;
  overflow-y: auto;
  scroll-behavior: smooth;
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

@keyframes messageFadeIn {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

.message {
  /* 80ch reads well on a wide pane, but on a narrow viewport (mobile,
     side-by-side panes) the bubble would still try to be ~640 px wide
     and push code blocks / long URLs past the right edge. min(...,100%)
     caps it at whichever is smaller, and min-width:0 stops the flex
     parent from giving the bubble extra room to fit unwrapping content. */
  max-width: min(80ch, 100%);
  min-width: 0;
  overflow-wrap: anywhere;
  animation: messageFadeIn 0.35s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.message-content pre,
.message-content table {
  max-width: 100%;
}

.message-user {
  align-self: flex-end;
  background: linear-gradient(135deg, rgba(34, 211, 238, 0.16), rgba(34, 211, 238, 0.04));
  color: var(--text);
  padding: 8px 14px;
  border-radius: 12px 12px 2px 12px;
  border: 1px solid rgba(34, 211, 238, 0.24);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.message-user.solution-ok {
  position: relative;
  border-color: rgba(166, 227, 161, 0.5);
  background: linear-gradient(135deg, rgba(166, 227, 161, 0.15), rgba(166, 227, 161, 0.03));
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(166, 227, 161, 0.1);
}
.message-user.solution-ok::after {
  content: '✓';
  position: absolute;
  top: 6px;
  right: 10px;
  font-size: 13px;
  font-weight: 700;
  color: #a6e3a1;
  line-height: 1;
}
.message-user.solution-retry {
  position: relative;
  border-color: rgba(251, 191, 36, 0.45);
  background: linear-gradient(135deg, rgba(251, 191, 36, 0.12), rgba(251, 191, 36, 0.02));
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.message-user.solution-retry::after {
  content: '↻';
  position: absolute;
  top: 6px;
  right: 10px;
  font-size: 13px;
  color: #fbbf24;
  line-height: 1;
}

.message-assistant {
  align-self: flex-start;
  background: rgba(12, 26, 44, 0.65);
  backdrop-filter: blur(8px);
  padding: 8px 14px;
  border-radius: 12px 12px 12px 2px;
  border: 1px solid rgba(34, 211, 238, 0.08);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.message-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 3px;
  font-size: 11px;
  color: var(--text-muted);
}

.message-author {
  font-weight: 700;
  /* --msg-persona-color is snapshotted per-message at creation time so
     switching persona doesn't recolor old messages. Falls back to the
     live --active-persona-color for any message that predates the fix,
     then to the brand orange. */
  color: var(--msg-persona-color, var(--active-persona-color, var(--accent-hot)));
  text-shadow: 0 0 6px color-mix(in srgb, var(--msg-persona-color, var(--active-persona-color, var(--accent-hot))) 40%, transparent);
}

/* Active persona name in the chat header — matches message-author. */
.chat-pane-persona #active-persona-name {
  color: var(--active-persona-color, var(--accent-hot));
  text-shadow: 0 0 6px color-mix(in srgb, var(--active-persona-color, var(--accent-hot)) 40%, transparent);
}

/* ── "Spark burst" when an assistant message completes.
   The ✨ icon scales briefly and a glowing halo radiates from it via the
   ::after pseudo, while the whole bubble gets a fleeting orange edge.
   ~1 s total. Triggered by JS adding .spark-done in the SSE finally. */
.message-assistant .message-icon {
  position: relative;
  display: inline-block;
  transform-origin: center;
}

@keyframes sparkIconPop {
  0%   { transform: scale(1)   rotate(0deg); }
  40%  { transform: scale(1.45) rotate(15deg); filter: drop-shadow(0 0 8px rgba(251, 146, 60, 0.8)); }
  100% { transform: scale(1)   rotate(0deg); filter: none; }
}

@keyframes sparkHalo {
  0%   { opacity: 0;    transform: translate(-50%, -50%) scale(0.4); }
  40%  { opacity: 0.85; }
  100% { opacity: 0;    transform: translate(-50%, -50%) scale(3.0); }
}

@keyframes sparkEdge {
  0%   { box-shadow: 0 0 0   rgba(251, 146, 60, 0.0); }
  30%  { box-shadow: 0 0 22px rgba(251, 146, 60, 0.45); }
  100% { box-shadow: 0 0 0   rgba(251, 146, 60, 0.0); }
}

.message-assistant.spark-done .message-icon {
  animation: sparkIconPop 0.7s ease-out 1;
}
.message-assistant.spark-done .message-icon::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(251,146,60,0.55) 0%, rgba(251,146,60,0) 65%);
  pointer-events: none;
  animation: sparkHalo 0.9s ease-out 1;
}
.message-assistant.spark-done {
  animation: sparkEdge 0.9s ease-out 1;
}

.message-model {
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 10.5px;
  opacity: 0.7;
  margin-left: auto;
}

.message-stats {
  margin-top: 6px;
  padding-top: 5px;
  border-top: 1px dashed rgba(255, 255, 255, 0.08);
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 10.5px;
  color: var(--text-muted);
  opacity: 0.8;
}

.message-actions {
  display: flex;
  gap: 2px;
  margin-top: 5px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s;
}
.message-user .message-actions { justify-content: flex-end; }
.message-assistant .message-actions { justify-content: flex-start; }
.message:hover .message-actions,
.message:focus-within .message-actions { opacity: 1; pointer-events: auto; }

.msg-action-btn {
  background: none;
  border: 1px solid transparent;
  border-radius: 4px;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 12px;
  line-height: 1.4;
  padding: 1px 7px;
}
.msg-action-btn:hover {
  background: rgba(255, 255, 255, 0.07);
  border-color: var(--border);
  color: var(--text);
}
.msg-action-btn--primary {
  border-color: var(--border);
  color: var(--text);
}
.msg-action-btn--primary:hover {
  background: rgba(34, 211, 238, 0.15);
  border-color: rgba(34, 211, 238, 0.4);
  color: var(--text);
}

.msg-edit-wrap { display: flex; flex-direction: column; gap: 6px; }
.msg-edit-textarea {
  background: var(--bg-input, var(--bg-surface));
  border: 1px solid var(--border);
  border-radius: 6px;
  box-sizing: border-box;
  color: var(--text);
  font-family: inherit;
  font-size: inherit;
  line-height: 1.45;
  min-height: 64px;
  padding: 6px 8px;
  resize: vertical;
  width: 100%;
}
.msg-edit-textarea:focus { border-color: rgba(34, 211, 238, 0.5); outline: none; }
.msg-edit-btns { display: flex; gap: 6px; justify-content: flex-end; }

.message-content {
  white-space: pre-wrap;
  word-wrap: break-word;
}

.message-assistant.thinking .message-content::after {
  content: '▍';
  animation: blink 1s steps(1) infinite;
}

@keyframes blink {
  50% { opacity: 0; }
}

/* ─── Form ─── */
.chat-form {
  display: flex;
  gap: 6px;
  padding: 8px 12px;
  border-top: 1px solid var(--border);
  background: var(--bg-surface);
  position: relative;
}

.chat-form textarea {
  flex: 1;
  padding: 6px 10px;
  background: var(--bg-base);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  font: inherit;
  resize: vertical;
  min-height: 34px;
  max-height: 200px;
  line-height: 1.35;
}

.chat-form textarea:focus {
  outline: none;
  /* Border + glow follow the active persona — chat reads as "talking
     to <persona>" even without looking at the header. */
  border-color: var(--active-persona-color, var(--accent));
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--active-persona-color, var(--accent)) 50%, transparent),
    0 0 12px color-mix(in srgb, var(--active-persona-color, var(--accent)) 30%, transparent);
}

.chat-image-input { display: none; }

.chat-image-preview {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  padding: 4px 0 2px;
}
.chat-image-preview img {
  max-height: 72px;
  max-width: 120px;
  border-radius: 4px;
  border: 1px solid var(--border);
  object-fit: cover;
}
.chat-image-remove {
  background: var(--bg-surface);
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 4px;
  width: 18px;
  height: 18px;
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  flex-shrink: 0;
}
.chat-image-remove:hover { color: #f87171; border-color: #f87171; }

.chat-send {
  width: 38px;
  flex-shrink: 0;
  padding: 0;
  background: var(--active-persona-color, var(--accent));
  color: #061018;
  border: none;
  border-radius: 8px;
  font-size: 18px;
  font-weight: 700;
  cursor: pointer;
  transition: filter 0.15s, box-shadow 0.15s, background 0.2s;
  box-shadow: 0 0 10px color-mix(in srgb, var(--active-persona-color, var(--accent)) 25%, transparent);
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: center;
}

.chat-send:hover:not(:disabled) {
  filter: brightness(1.1);
  box-shadow: 0 0 18px color-mix(in srgb, var(--active-persona-color, var(--accent)) 45%, transparent);
}

.chat-send:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ── Admin panel tabs (Nodes / Users) ── */
.admin-tabs {
  display: flex;
  border-bottom: 1px solid var(--border);
  background: rgba(34, 211, 238, 0.03);
}
.admin-tab {
  flex: 1;
  background: none;
  border: none;
  color: var(--text-muted);
  font: inherit;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  padding: 8px 10px;
  cursor: pointer;
  border-bottom: 2px solid transparent;
}
.admin-tab:hover { color: var(--text); }
.admin-tab.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
  text-shadow: 0 0 6px rgba(34, 211, 238, 0.3);
}
.admin-tab-pane.hidden { display: none; }
.admin-tab-pane {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

/* User rows in the Users tab. */
.users-list {
  flex: 1;
  overflow-y: auto;
  padding: 6px 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.user-row {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-left: 3px solid var(--text-muted);
  border-radius: 5px;
  padding: 6px 9px;
  font-size: 12px;
}
.user-row.user-online    { border-left-color: var(--accent); }
.user-row.user-offline   { border-left-color: var(--text-muted); opacity: 0.85; }
.user-row-head {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}
.user-login { font-weight: 700; color: var(--text); flex: 1; }
.user-admin-pill {
  font-size: 9px;
  letter-spacing: 1px;
  padding: 1px 5px;
  border-radius: 2px;
  background: rgba(251, 146, 60, 0.12);
  color: var(--accent-hot);
  border: 1px solid rgba(251, 146, 60, 0.4);
  text-transform: uppercase;
}
.user-state {
  font-size: 9px;
  letter-spacing: 1px;
  padding: 1px 6px;
  border-radius: 2px;
}
.user-online    .user-state { color: var(--accent);     background: rgba(34, 211, 238, 0.12); }
.user-offline   .user-state { color: var(--text-muted); background: rgba(108, 112, 134, 0.15); }
.user-fullname { color: var(--text-muted); font-size: 11px; margin-top: 2px; }
.user-meta {
  display: flex;
  justify-content: space-between;
  font-size: 10px;
  color: var(--text-muted);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  margin-top: 3px;
  gap: 8px;
}
.user-email { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Persona switch pulse — JS adds .persona-switching to .chat-pane
   for ~600 ms when the user picks a new persona. A short bottom-up
   sweep in the persona's color signals "you are now talking to X". */
@keyframes personaSwitchSweep {
  0%   { box-shadow: inset 0 -60px 40px -40px color-mix(in srgb, var(--active-persona-color, var(--accent)) 60%, transparent); }
  100% { box-shadow: inset 0 -60px 40px -40px transparent; }
}
.chat-pane.persona-switching {
  animation: personaSwitchSweep 0.6s ease-out 1;
}

/* ── Persona edit ── */
.persona-edit {
  /* No margin-auto here — ⓘ already grabs that. */
  opacity: 0.4;
  color: var(--text-muted);
  font-size: 14px;
  width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 3px;
  flex-shrink: 0;
  transition: opacity 0.1s, color 0.1s, background 0.1s;
}
.persona-item:hover .persona-edit { opacity: 0.8; }
.persona-edit:hover {
  opacity: 1 !important;
  color: var(--persona-color, var(--accent));
  background: rgba(251, 146, 60, 0.12);
}

.persona-dialog {
  background: var(--bg-surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 22px 26px;
  min-width: 520px;
  max-width: 640px;
  width: 90vw;
  box-shadow: 0 32px 70px rgba(0, 0, 0, 0.55);
}
.persona-dialog::backdrop { background: rgba(0, 0, 0, 0.55); backdrop-filter: blur(3px); }
.persona-dialog h3 {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 13px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 14px;
}
.persona-dialog-form label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 10px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  margin-bottom: 10px;
}
.persona-dialog-form input[type="text"],
.persona-dialog-form input[type="color"],
.persona-dialog-form textarea {
  background: var(--bg-base);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 6px 9px;
  font: inherit;
  font-size: 13px;
  text-transform: none;
}
.persona-dialog-form input[type="color"] {
  height: 32px;
  padding: 2px;
  cursor: pointer;
}
.persona-dialog-form textarea {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 12px;
  line-height: 1.45;
  resize: vertical;
}
.persona-dialog-form input:focus,
.persona-dialog-form textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--glow-accent);
}
.persona-dialog-row {
  display: flex;
  gap: 10px;
}
.persona-dialog-row > .flex-1 { flex: 1; }
.persona-dialog-check {
  flex-direction: row !important;
  align-items: center;
  gap: 8px !important;
  text-transform: none !important;
  font-size: 12px !important;
  color: var(--text) !important;
  letter-spacing: 0 !important;
}
.persona-dialog-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 14px;
}
.persona-dialog-actions .flex-1 { flex: 1; }
.persona-dialog-actions button {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
  padding: 6px 14px;
  border-radius: 4px;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.persona-dialog-actions .persona-dialog-save {
  background: var(--accent);
  border-color: var(--accent);
  color: #061018;
  font-weight: 700;
}
.persona-dialog-actions .persona-dialog-reset {
  color: var(--accent-hot);
  border-color: rgba(251, 146, 60, 0.4);
}
.persona-dialog-actions .persona-dialog-reset:hover {
  background: rgba(251, 146, 60, 0.12);
}

/* Persona ⓘ info + ✎ edit buttons — visible by default at low opacity
   so the affordance is discoverable without a hover, and brighten on
   hover. The first one auto-margins to push both to the right. */
.persona-info {
  margin-left: auto;
  opacity: 0.4;
  color: var(--text-muted);
  font-size: 14px;
  width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 3px;
  flex-shrink: 0;
  transition: opacity 0.1s, color 0.1s, background 0.1s;
}
.persona-item:hover .persona-info { opacity: 0.8; }
.persona-info:hover {
  opacity: 1 !important;
  color: var(--persona-color, var(--accent));
  background: rgba(34, 211, 238, 0.1);
}
/* ✎ sits flush against ⓘ, no margin-auto for the second hover icon. */
.persona-item .persona-info + .persona-edit { margin-left: 4px; }

.persona-info-dialog {
  background: var(--bg-surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-left: 4px solid var(--persona-color, var(--accent));
  border-radius: 10px;
  padding: 18px 22px 16px;
  min-width: 520px;
  max-width: 720px;
  width: 90vw;
  max-height: 80vh;
  box-shadow: 0 32px 70px rgba(0, 0, 0, 0.55);
}
.persona-info-dialog::backdrop {
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(3px);
}
.persona-info-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}
.persona-info-icon {
  font-size: 28px;
  line-height: 1;
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--persona-color, var(--accent)) 50%, transparent));
}
.persona-info-text { flex: 1; min-width: 0; }
.persona-info-text h3 {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 14px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--persona-color, var(--accent));
  margin: 0 0 4px;
}
.persona-info-text p {
  color: var(--text-muted);
  font-size: 12px;
  margin: 0;
}
.persona-info-edit-link {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-muted);
  padding: 4px 12px;
  border-radius: 4px;
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  cursor: pointer;
}
.persona-info-edit-link:hover {
  color: var(--persona-color, var(--accent));
  border-color: var(--persona-color, var(--accent));
}
.persona-info-close {
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  padding: 0 6px;
}
.persona-info-close:hover { color: var(--text); }
.persona-info-body {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 12px;
  line-height: 1.55;
  color: var(--text);
  background: var(--bg-base);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 12px 14px;
  white-space: pre-wrap;
  word-wrap: break-word;
  max-height: 60vh;
  overflow-y: auto;
  margin: 0;
}

/* Icon picker for the persona editor. The wrap holds the text input,
   the picker button and the popover grid. Grid is absolutely
   positioned just under the input so it doesn't push other rows. */
.pe-icon-wrap {
  position: relative;
  display: flex;
  gap: 4px;
}
.pe-icon-wrap input { flex: 1; }
.pe-icon-pick {
  width: 32px;
  background: var(--bg-base);
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 4px;
  font: inherit;
  cursor: pointer;
}
.pe-icon-pick:hover { color: var(--accent); border-color: var(--accent); }
.pe-icon-grid {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 5;
  margin-top: 4px;
  max-height: 220px;
  overflow-y: auto;
  background: var(--bg-base);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(36px, 1fr));
  gap: 2px;
  box-shadow: 0 16px 32px rgba(0, 0, 0, 0.5);
}
.pe-icon-grid.hidden { display: none; }
.pe-icon-cell {
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  padding: 4px;
  font-size: 18px;
  cursor: pointer;
  line-height: 1;
  height: 32px;
}
.pe-icon-cell:hover {
  background: rgba(34, 211, 238, 0.1);
  border-color: var(--accent);
}

/* Preload button on each node row — sits next to Revoke. */
.node-preload {
  background: transparent;
  color: var(--accent);
  border: 1px solid rgba(34, 211, 238, 0.4);
  border-radius: 3px;
  padding: 1px 8px;
  font: inherit;
  font-size: 10px;
  letter-spacing: 0.5px;
  cursor: pointer;
  margin-right: 4px;
}
.node-preload:hover {
  background: rgba(34, 211, 238, 0.12);
  box-shadow: 0 0 8px rgba(34, 211, 238, 0.3);
}

.preload-title {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 12px;
  letter-spacing: 1.4px;
  color: var(--accent);
  text-transform: uppercase;
  margin-bottom: 8px;
}
.preload-body {
  max-height: 60vh;
  overflow-y: auto;
  background: var(--bg-base);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 6px;
  margin: 10px 0;
}
.preload-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 8px;
  cursor: pointer;
  font-size: 12px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}
.preload-row:hover { background: rgba(34, 211, 238, 0.06); border-radius: 3px; }
.preload-name { flex: 1; }
.preload-hot {
  color: var(--accent);
  font-size: 12px;
  text-shadow: 0 0 4px var(--accent);
}

/* While the user holds Shift+Alt, brighten the per-card shortcut
   badge so the available targets are obvious before they press a
   digit. Listener toggles .splash-shortcut-hint on <body>. */
body.splash-shortcut-hint .splash-card-key {
  opacity: 1;
  color: var(--persona-color, var(--accent));
  border-color: var(--persona-color, var(--accent));
  background: color-mix(in srgb, var(--persona-color, var(--accent)) 12%, transparent);
  box-shadow: 0 0 8px color-mix(in srgb, var(--persona-color, var(--accent)) 35%, transparent);
}

/* ─── Chat drop target ─── */
.chat-pane.chat-drop-over {
  outline: 2px dashed var(--accent);
  outline-offset: -3px;
  background: color-mix(in srgb, var(--accent) 5%, transparent);
}

/* ─── Zen mode — hides sidebar / editor / appbar so only the chat
   remains. JS toggles .zen-mode on .shell; Shift+Alt+Z or Esc exits. ─── */
.shell.zen-mode .activity-bar,
.shell.zen-mode .sidebar,
.shell.zen-mode .pane-resizer,
.shell.zen-mode .editor-pane,
.shell.zen-mode .appbar {
  display: none;
}
.shell.zen-mode .workspace {
  justify-content: center;
}
.shell.zen-mode .chat-pane {
  width: 100%;
  max-width: 100%;
  flex: 1;
  border-left: none;
}
/* Use more of the screen in Zen mode — prose stays readable while
   code blocks and exercise cards finally get the room they need. */
.shell.zen-mode .message { max-width: min(980px, 100%); }
.shell.zen-mode .messages { padding: 16px 32px; }
/* Solution bubbles (user messages with a code block) stretch toward
   the available width so the submitted code reads at exercise-card
   sizing instead of squeezing into a narrow chat balloon. Plain text
   user messages keep their content-sized width — only :has(pre)
   bubbles grow. */
.shell.zen-mode .message-user:has(pre) {
  width: 100%;
  max-width: 720px;
}

/* Right-rail sidebar (created by JS only when Zen is active). Lists
   every exercise the tutor has proposed in this session with its
   status; clicking jumps the chat to that bubble so the student can
   navigate without scrolling by hand. */
.zen-sidebar {
  width: 260px;
  flex-shrink: 0;
  border-left: 1px solid var(--border);
  background: var(--bg-surface);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.zen-sidebar-header {
  padding: 10px 14px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  font-weight: 700;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 1.2px;
  border-bottom: 1px solid var(--border);
}
.zen-sidebar-list {
  flex: 1;
  overflow-y: auto;
  padding: 8px 0;
  margin: 0;
  list-style: none;
}
.zen-sidebar-list:empty::before {
  content: attr(data-empty);
  display: block;
  padding: 14px;
  color: var(--text-muted);
  font-size: 12px;
  font-style: italic;
}
.zen-step {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px;
  font-size: 12px;
  line-height: 1.35;
  color: var(--fg);
  cursor: pointer;
  border-left: 2px solid transparent;
  transition: background 100ms;
}
.zen-step:hover { background: rgba(255, 255, 255, 0.04); }
.zen-step .zen-step-num {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 700;
  background: rgba(255, 255, 255, 0.08);
  color: var(--text-muted);
}
.zen-step .zen-step-task {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.zen-step.ok    .zen-step-num { background: rgba(166, 227, 161, 0.22); color: #a6e3a1; }
.zen-step.retry .zen-step-num { background: rgba(251, 191, 36, 0.22); color: #fbbf24; }
.zen-step.current { border-left-color: var(--accent); background: rgba(34, 211, 238, 0.06); }
.zen-step.current .zen-step-num { background: rgba(34, 211, 238, 0.22); color: var(--accent); }

/* ── Zen save button ─────────────────────────────────────────────────── */
.zen-save-btn {
  background: transparent;
  border: none;
  font-size: 15px;
  padding: 2px 6px;
  cursor: pointer;
  opacity: 0.6;
  transition: opacity 120ms;
}
.zen-save-btn:hover { opacity: 1; }

/* ── Zen scope overlay ───────────────────────────────────────────────── */
.zen-scope {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
  background: var(--bg);
  z-index: 5;
  padding: 40px;
}
.zen-scope-label {
  font-size: 18px;
  color: var(--fg);
  font-weight: 500;
  text-align: center;
}
.zen-scope-row {
  display: flex;
  gap: 8px;
  width: 100%;
  max-width: 480px;
}
.zen-scope-input {
  flex: 1;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--fg);
  padding: 10px 14px;
  font-size: 15px;
  outline: none;
}
.zen-scope-input:focus { border-color: var(--accent); }
.zen-scope-start {
  background: var(--accent);
  color: #07101e;
  border: none;
  border-radius: 8px;
  padding: 10px 18px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}

/* ── Zen summary modal ───────────────────────────────────────────────── */
.zen-summary-modal {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.65);
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
}
.zen-summary-modal.hidden { display: none; }
.zen-summary-box {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  width: min(680px, 92vw);
  max-height: 80vh;
  display: flex;
  flex-direction: column;
}
.zen-summary-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
  font-weight: 600;
  font-size: 14px;
}
.zen-summary-close {
  background: transparent;
  border: none;
  font-size: 18px;
  cursor: pointer;
  opacity: 0.6;
  line-height: 1;
  padding: 0 4px;
}
.zen-summary-close:hover { opacity: 1; }
.zen-summary-body {
  flex: 1;
  overflow-y: auto;
  padding: 18px 20px;
  font-size: 14px;
  line-height: 1.6;
}
.zen-summary-footer {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  padding: 12px 18px;
  border-top: 1px solid var(--border);
}
.zen-summary-footer button {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--fg);
  padding: 6px 14px;
  font-size: 13px;
  cursor: pointer;
}
.zen-summary-footer button:hover { border-color: var(--accent); }

/* ── Zen level selector ──────────────────────────────────────────────── */
.zen-level-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
}
.zen-level-label {
  font-size: 12px;
  color: var(--fg-muted, #64748b);
}
.zen-level-btn {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--fg-muted, #94a3b8);
  padding: 3px 12px;
  font-size: 12px;
  cursor: pointer;
  transition: border-color 120ms, color 120ms;
}
.zen-level-btn[data-level="noviisi"]:hover,
.zen-level-btn[data-level="noviisi"].active {
  border-color: #4ade80; color: #4ade80;
}
.zen-level-btn[data-level="kokenut"]:hover,
.zen-level-btn[data-level="kokenut"].active {
  border-color: #fb923c; color: #fb923c;
}
.zen-level-btn[data-level="ekspertti"]:hover,
.zen-level-btn[data-level="ekspertti"].active {
  border-color: #f87171; color: #f87171;
}
.zen-level-btn.active { font-weight: 600; }

/* ── Zen tutorial cards ──────────────────────────────────────────────── */
.zen-tutorials-section {
  margin-top: 20px;
  width: 100%;
}
.zen-tutorials-label {
  font-size: 12px;
  color: var(--fg-muted, #94a3b8);
  text-align: center;
  margin: 0 0 10px;
  letter-spacing: 0.03em;
}
/* Filter pill bar */
.ztc-filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 12px;
}
.ztc-filter-pill {
  padding: 4px 12px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-radius: 99px;
  border: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.02);
  color: var(--text-muted);
  cursor: pointer;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}
.ztc-filter-pill:hover {
  color: var(--text);
  border-color: var(--text-muted);
  background: rgba(255, 255, 255, 0.05);
}
.ztc-filter-pill.active {
  border-color: var(--accent);
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  box-shadow: 0 0 10px rgba(34, 211, 238, 0.15);
}

.zen-tutorial-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 10px;
}
.zen-tutorial-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  padding: 14px 16px;
  background: rgba(12, 26, 44, 0.65);
  border: 1px solid var(--border);
  border-radius: 12px;
  cursor: pointer;
  backdrop-filter: blur(8px);
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1),
              border-color 0.25s cubic-bezier(0.4, 0, 0.2, 1), 
              box-shadow 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
.zen-tutorial-card:hover {
  transform: translateY(-3px);
  border-color: var(--accent);
  background: rgba(12, 26, 44, 0.85);
  box-shadow: 
    0 8px 16px rgba(0, 0, 0, 0.4),
    0 0 12px color-mix(in srgb, var(--accent) 20%, transparent);
}
/* Completed state */
.zen-tutorial-card.ztc-done {
  border-color: color-mix(in srgb, var(--accent) 40%, var(--border));
}
.zen-tutorial-card.ztc-done .ztc-title { color: var(--text-muted); }

/* Completion toggle button */
.ztc-check {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 18px;
  height: 18px;
  padding: 0;
  font-size: 11px;
  line-height: 18px;
  text-align: center;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}
.ztc-check:hover {
  border-color: var(--accent);
  color: var(--accent);
  transform: scale(1.1);
}
.ztc-check.done {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 20%, transparent);
  color: var(--accent);
  box-shadow: 0 0 8px rgba(34, 211, 238, 0.25);
}

/* Admin "add" card */
.zen-tutorial-card.ztc-add {
  border-style: dashed;
  opacity: 0.6;
}
.zen-tutorial-card.ztc-add:hover {
  opacity: 1;
  border-color: var(--accent);
  box-shadow: 0 0 10px rgba(34, 211, 238, 0.1);
}

/* Admin add form */
.ztc-add-form {
  margin-top: 10px;
  padding: 12px 14px;
  background: var(--bg-panel, #1e293b);
  border: 1px solid var(--border, #334155);
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.ztc-add-title { font-size: 12px; font-weight: 600; color: var(--fg, #e2e8f0); margin-bottom: 2px; }
.ztc-add-input {
  padding: 5px 8px;
  font-size: 12px;
  background: var(--bg, #0f172a);
  border: 1px solid var(--border, #334155);
  border-radius: 5px;
  color: var(--fg, #e2e8f0);
  width: 100%;
  box-sizing: border-box;
}
.ztc-add-input:focus { outline: none; border-color: var(--accent); }
.ztc-add-actions { display: flex; gap: 6px; margin-top: 2px; }
.ztc-add-save {
  padding: 4px 12px;
  font-size: 12px;
  border-radius: 5px;
  border: none;
  background: var(--accent);
  color: #fff;
  cursor: pointer;
}
.ztc-add-cancel {
  padding: 4px 10px;
  font-size: 12px;
  border-radius: 5px;
  border: 1px solid var(--border, #334155);
  background: transparent;
  color: var(--fg-muted, #94a3b8);
  cursor: pointer;
}

.ztc-icon { font-size: 22px; line-height: 1; }
.ztc-title { font-size: 13px; font-weight: 600; color: var(--fg, #e2e8f0); }
.ztc-desc  { font-size: 11px; color: var(--fg-muted, #94a3b8); line-height: 1.4; }

/* ── Zen resume section ──────────────────────────────────────────────── */
.zen-resume-section {
  margin-top: 20px;
  width: 100%;
}
.zen-resume-label {
  font-size: 12px;
  color: var(--fg-muted, #94a3b8);
  text-align: center;
  margin: 0 0 10px;
  letter-spacing: 0.03em;
}
.zen-resume-chips {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 8px;
}
.zen-resume-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  padding: 10px 12px;
  background: var(--bg-panel, #1e293b);
  border: 1px solid var(--border, #334155);
  border-radius: 8px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
  text-align: left;
}
.zen-resume-card:hover {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, var(--bg-panel, #1e293b));
}
.zrc-icon  { font-size: 18px; line-height: 1; }
.zrc-title { font-size: 13px; font-weight: 600; color: var(--fg, #e2e8f0); }
.zrc-date  { font-size: 11px; color: var(--fg-muted, #94a3b8); }

/* ── Zen project bar ─────────────────────────────────────────────────── */
.zen-project-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 14px;
  font-size: 12px;
  background: color-mix(in srgb, var(--accent) 6%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 20%, transparent);
  color: var(--fg-muted, #94a3b8);
}
.zen-pb-icon  { font-size: 13px; }
.zen-pb-label { font-weight: 600; color: var(--fg, #e2e8f0); }
.zen-pb-path  { opacity: 0.55; font-family: ui-monospace, monospace; font-size: 11px; }

/* ── Reconnect notice ────────────────────────────────────────────────── */
.reconnect-notice {
  color: var(--fg-muted, #94a3b8);
  font-size: 13px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 0;
}
.reconnect-notice .reconnect-icon { font-size: 15px; }

.message {
  position: relative;
}
.message-del {
  position: absolute;
  top: 6px;
  right: 6px;
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 16px;
  line-height: 1;
  padding: 4px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 120ms, color 120ms;
}
.message:hover .message-del {
  opacity: 1;
}
.message-del:hover {
  color: #ff4a4a;
}

/* ── Contextual Definitions (Hover-def) ──
   Subtle by design: no color shift in prose flow, only a faint dotted
   underline that hints "hover for definition" without screaming. Body
   data-glossary="off" disables both the underline and the tooltip so
   users who find it distracting can toggle the whole feature. */
.hover-def {
  border-bottom: 1px dotted color-mix(in srgb, currentColor 35%, transparent);
  cursor: help;
  position: relative;
  text-decoration: none;
  font-style: normal;
  color: inherit;
  transition: border-color 0.15s;
}

.hover-def:hover {
  border-bottom-color: color-mix(in srgb, currentColor 80%, transparent);
}

body[data-glossary="off"] .hover-def {
  border-bottom: none;
  cursor: text;
  pointer-events: none;
}
body[data-glossary="off"] .hover-def:hover::after,
body[data-glossary="off"] .hover-def:hover::before {
  display: none;
}

.hover-def:hover::after {
  content: attr(data-def);
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  background: var(--bg-surface, #1e293b);
  color: var(--fg, #e2e8f0);
  padding: 8px 12px;
  border-radius: 6px;
  border: 1px solid var(--border, #334155);
  box-shadow: 0 4px 16px rgba(0,0,0,0.4);
  white-space: normal;
  width: max-content;
  max-width: 250px;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 0.85rem;
  line-height: 1.4;
  z-index: 100;
  margin-bottom: 8px;
  text-align: left;
}

.hover-def:hover::before {
  content: "";
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: var(--border, #334155);
  margin-bottom: -4px;
  z-index: 101;
}


/* ─── Tauluseinä (BBS) — standalone /bbs page ────────────────────────────
   Full-window community bulletin board with thread list, thread detail,
   markdown editor (toolbar + preview), and search. Separate from the
   AIDE chat shell — only this CSS block applies on the /bbs route. */

body.bbs-body {
  margin: 0;
  background: var(--bg, #0f172a);
  color: var(--fg, #e2e8f0);
  font-family: 'Inter', system-ui, sans-serif;
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.bbs-topbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 18px;
  border-bottom: 1px solid var(--border, #334155);
  background: var(--bg-surface, #1e293b);
  flex-shrink: 0;
}
.bbs-back {
  color: var(--text-dim, #94a3b8);
  text-decoration: none;
  font-size: 0.9rem;
  padding: 4px 8px;
  border-radius: 4px;
}
.bbs-back:hover { color: var(--fg, #e2e8f0); background: rgba(148,163,184,0.1); }
.bbs-brand {
  margin: 0;
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.bbs-search-wrap { flex: 1; max-width: 480px; }
.bbs-search {
  width: 100%;
  background: var(--bg, #0f172a);
  border: 1px solid var(--border, #334155);
  border-radius: 6px;
  color: var(--fg, #e2e8f0);
  padding: 7px 12px;
  font-size: 0.9rem;
}
.bbs-search:focus { outline: 2px solid var(--accent, #3b82f6); outline-offset: -1px; }
.bbs-id-pill {
  background: rgba(59, 130, 246, 0.15);
  color: var(--accent, #60a5fa);
  border: 1px solid rgba(59, 130, 246, 0.35);
  padding: 5px 12px;
  border-radius: 999px;
  font-size: 0.85rem;
  cursor: pointer;
  user-select: none;
}
.bbs-id-pill:hover { background: rgba(59, 130, 246, 0.25); }
.bbs-new-btn {
  background: var(--accent, #3b82f6);
  color: #fff;
  border: 0;
  border-radius: 6px;
  padding: 7px 14px;
  font-size: 0.9rem;
  cursor: pointer;
  font-weight: 500;
}
.bbs-new-btn:hover { filter: brightness(1.1); }

.bbs-main {
  flex: 1;
  overflow-y: auto;
  padding: 18px 24px 60px;
  max-width: 920px;
  width: 100%;
  margin: 0 auto;
  box-sizing: border-box;
}

.bbs-loading, .bbs-empty, .bbs-error, .bbs-empty-replies {
  font-size: 0.9rem;
  color: var(--text-dim, #94a3b8);
  text-align: center;
  padding: 24px;
}
.bbs-error { color: #ef4444; }

/* ── Thread list ──────────────────────────────────────────────────────── */
/* Tight, scannable rows: title + meta on two lines, snippet inlined into
   the meta row as an ellipsised tail. Designed for high density when the
   board fills up (~12 threads per viewport). */
.bbs-thread-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.bbs-thread-card {
  background: var(--bg-surface, #1e293b);
  border: 1px solid var(--border, #334155);
  border-radius: 6px;
  padding: 6px 12px;
  cursor: pointer;
  transition: border-color 0.1s, background 0.1s;
}
.bbs-thread-card:hover {
  border-color: var(--accent, #3b82f6);
  background: rgba(59, 130, 246, 0.06);
}
.bbs-card-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 1px;
}
.bbs-card-title {
  font-weight: 600;
  font-size: 0.95rem;
  flex: 1;
  word-break: break-word;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bbs-cat {
  font-size: 0.7rem;
  color: var(--text-dim, #94a3b8);
  background: rgba(148,163,184,0.15);
  padding: 2px 8px;
  border-radius: 10px;
  white-space: nowrap;
}
.bbs-replycount {
  font-size: 0.78rem;
  color: var(--text-dim, #94a3b8);
}
.bbs-card-meta {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 0.78rem;
  color: var(--text-dim, #94a3b8);
  overflow: hidden;
  white-space: nowrap;
}
.bbs-pseu { font-weight: 500; color: var(--accent, #60a5fa); flex-shrink: 0; }
.bbs-sep { opacity: 0.5; flex-shrink: 0; }
.bbs-time { flex-shrink: 0; }
.bbs-card-snippet {
  font-size: 0.78rem;
  color: var(--text-dim, #cbd5e1);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
  flex: 1;
}

/* ── Thread detail ────────────────────────────────────────────────────── */
.bbs-back-link {
  background: transparent;
  border: 0;
  color: var(--text-dim, #94a3b8);
  cursor: pointer;
  font-size: 0.85rem;
  padding: 4px 0;
  margin-bottom: 10px;
}
.bbs-back-link:hover { color: var(--fg, #e2e8f0); }

.bbs-op, .bbs-reply {
  background: var(--bg-surface, #1e293b);
  border: 1px solid var(--border, #334155);
  border-radius: 8px;
  padding: 14px 18px;
  margin-bottom: 10px;
}
.bbs-op { border-left: 3px solid var(--accent, #3b82f6); }
.bbs-op-head, .bbs-reply-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}
.bbs-op-title {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 600;
  flex: 1;
  word-break: break-word;
}
.bbs-op-meta, .bbs-reply-head {
  font-size: 0.78rem;
  color: var(--text-dim, #94a3b8);
}
.bbs-op-meta { margin-bottom: 8px; }
.bbs-op-body, .bbs-reply-body {
  font-size: 0.93rem;
  line-height: 1.6;
}
.bbs-op-body p, .bbs-reply-body p { margin: 0.4em 0; }
.bbs-del-thread, .bbs-del-reply {
  background: transparent;
  border: 0;
  color: var(--text-dim, #94a3b8);
  cursor: pointer;
  font-size: 1.1rem;
  line-height: 1;
  padding: 2px 6px;
  margin-left: auto;
}
.bbs-del-thread:hover, .bbs-del-reply:hover { color: #ef4444; }

.bbs-replies-head {
  margin: 22px 0 10px;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text-dim, #cbd5e1);
}
.bbs-reply-action {
  margin: 18px 0;
  text-align: center;
}

/* ── Editor dialog ────────────────────────────────────────────────────── */
.bbs-editor-dialog, .bbs-pseudo-dialog {
  background: var(--bg-surface, #1e293b);
  color: var(--fg, #e2e8f0);
  border: 1px solid var(--border, #334155);
  border-radius: 10px;
  padding: 0;
  max-width: 720px;
  width: 90%;
  max-height: 85vh;
}
.bbs-editor-dialog::backdrop, .bbs-pseudo-dialog::backdrop {
  background: rgba(0,0,0,0.5);
}
.bbs-editor-form {
  display: flex;
  flex-direction: column;
  max-height: 85vh;
}
.bbs-editor-head {
  display: flex;
  align-items: center;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border, #334155);
}
.bbs-editor-head h2 {
  margin: 0;
  font-size: 1.05rem;
  flex: 1;
}
.bbs-editor-close {
  background: transparent;
  border: 0;
  color: var(--text-dim, #94a3b8);
  cursor: pointer;
  font-size: 1.4rem;
  line-height: 1;
}
.bbs-editor-fields {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 18px 0;
}
.bbs-editor-title-input, .bbs-editor-cat-input {
  background: var(--bg, #0f172a);
  border: 1px solid var(--border, #334155);
  color: var(--fg, #e2e8f0);
  border-radius: 6px;
  padding: 8px 12px;
  font-size: 0.95rem;
}
.bbs-editor-title-input { font-size: 1.05rem; font-weight: 500; }
.bbs-editor-toolbar {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 8px 18px;
  border-bottom: 1px solid var(--border, #334155);
  flex-wrap: wrap;
}
.bbs-tb {
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-dim, #cbd5e1);
  cursor: pointer;
  padding: 4px 10px;
  border-radius: 4px;
  font-size: 0.85rem;
  font-family: inherit;
  min-width: 28px;
}
.bbs-tb:hover { background: rgba(148,163,184,0.1); border-color: var(--border, #334155); }
.bbs-toolbar-spacer { flex: 1; }
.bbs-tb-preview { font-size: 0.82rem; }
.bbs-editor-bodywrap {
  padding: 12px 18px;
  flex: 1;
  overflow-y: auto;
  min-height: 200px;
}
.bbs-editor-content {
  width: 100%;
  background: var(--bg, #0f172a);
  border: 1px solid var(--border, #334155);
  color: var(--fg, #e2e8f0);
  border-radius: 6px;
  padding: 10px 12px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.9rem;
  line-height: 1.55;
  box-sizing: border-box;
  resize: vertical;
  min-height: 240px;
}
.bbs-editor-preview {
  background: var(--bg, #0f172a);
  border: 1px solid var(--border, #334155);
  border-radius: 6px;
  padding: 12px 16px;
  min-height: 240px;
  font-size: 0.92rem;
  line-height: 1.6;
}
.bbs-editor-footer {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 18px;
  border-top: 1px solid var(--border, #334155);
}
.bbs-editor-hint {
  flex: 1;
  font-size: 0.78rem;
  color: var(--text-dim, #94a3b8);
}
.bbs-btn-primary {
  background: var(--accent, #3b82f6);
  color: #fff;
  border: 0;
  border-radius: 5px;
  padding: 7px 16px;
  font-size: 0.9rem;
  cursor: pointer;
  font-weight: 500;
}
.bbs-btn-primary:hover { filter: brightness(1.1); }
.bbs-btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }
.bbs-btn-secondary {
  background: transparent;
  color: var(--text-dim, #cbd5e1);
  border: 1px solid var(--border, #334155);
  border-radius: 5px;
  padding: 7px 16px;
  font-size: 0.9rem;
  cursor: pointer;
}
.bbs-btn-secondary:hover { background: rgba(148,163,184,0.08); }

/* ── Pseudonym dialog ─────────────────────────────────────────────────── */
.bbs-pseudo-dialog form {
  padding: 18px 22px 16px;
  min-width: 320px;
}
.bbs-pseudo-dialog h3 { margin: 0 0 6px; font-size: 1.05rem; }
.bbs-pseudo-hint {
  font-size: 0.82rem;
  color: var(--text-dim, #94a3b8);
  margin: 0 0 12px;
  line-height: 1.45;
}
#bbs-pseudo-input {
  width: 100%;
  background: var(--bg, #0f172a);
  border: 1px solid var(--border, #334155);
  color: var(--fg, #e2e8f0);
  border-radius: 6px;
  padding: 8px 12px;
  font-size: 0.95rem;
  box-sizing: border-box;
}
.bbs-pseudo-error {
  font-size: 0.82rem;
  color: #ef4444;
  min-height: 1.2em;
  margin-top: 6px;
}
.flex-1 { flex: 1; }

/* Activity-bar anchor variant — the 📌 button in chat shell is now a
   link to /bbs, not a panel toggle. Match the .ab-btn look. */
.ab-btn.ab-btn-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  color: inherit;
}

/* ── New BBS Overhaul Styles ────────────────────────────────────────── */
.bbs-filters-bar {
  display: flex;
  gap: 8px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}
.bbs-filter-pill {
  background: rgba(148, 163, 184, 0.08);
  border: 1px solid var(--border, #334155);
  color: var(--text-dim, #94a3b8);
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 0.8rem;
  cursor: pointer;
  transition: all 0.15s ease;
  font-weight: 500;
}
.bbs-filter-pill:hover {
  background: rgba(148, 163, 184, 0.15);
  color: var(--fg, #e2e8f0);
  border-color: var(--text-dim, #94a3b8);
}
.bbs-filter-pill.active {
  background: var(--accent, #3b82f6);
  color: #fff;
  border-color: var(--accent, #3b82f6);
  box-shadow: 0 0 10px rgba(59, 130, 246, 0.4);
}

.bbs-solved-badge {
  font-size: 0.72rem;
  color: #10b981;
  background: rgba(16, 185, 129, 0.12);
  border: 1px solid rgba(16, 185, 129, 0.3);
  padding: 2px 8px;
  border-radius: 10px;
  white-space: nowrap;
  margin-left: 8px;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
}
.bbs-thread-card.solved {
  border-left: 3px solid #10b981;
}
.bbs-op.solved {
  border-left: 3px solid #10b981;
}

.bbs-likes-meta {
  font-size: 0.75rem;
  color: var(--text-dim, #94a3b8);
  background: rgba(148, 163, 184, 0.08);
  padding: 2px 6px;
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
}
.bbs-likes-meta.liked {
  color: var(--accent, #60a5fa);
  background: rgba(59, 130, 246, 0.12);
  border-color: rgba(59, 130, 246, 0.3);
}
.bbs-like-btn {
  background: rgba(148, 163, 184, 0.08);
  border: 1px solid var(--border, #334155);
  color: var(--text-dim, #94a3b8);
  border-radius: 6px;
  padding: 4px 10px;
  font-size: 0.8rem;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: all 0.15s ease;
}
.bbs-like-btn:hover {
  background: rgba(148, 163, 184, 0.15);
  color: var(--fg, #e2e8f0);
  border-color: var(--text-dim, #94a3b8);
}
.bbs-like-btn.liked {
  color: var(--accent, #60a5fa);
  background: rgba(59, 130, 246, 0.12);
  border-color: var(--accent, #3b82f6);
}

.bbs-accepted-reply {
  border: 1px solid #10b981 !important;
  background: rgba(16, 185, 129, 0.04) !important;
  box-shadow: 0 0 12px rgba(16, 185, 129, 0.1);
}
.bbs-accepted-badge {
  font-size: 0.75rem;
  color: #10b981;
  background: rgba(16, 185, 129, 0.12);
  border: 1px solid rgba(16, 185, 129, 0.3);
  padding: 3px 10px;
  border-radius: 10px;
  font-weight: 600;
  margin-left: 8px;
  display: inline-flex;
  align-items: center;
}
.bbs-accept-btn {
  background: transparent;
  border: 1px dashed var(--border, #334155);
  color: var(--text-dim, #94a3b8);
  border-radius: 5px;
  padding: 4px 8px;
  font-size: 0.75rem;
  cursor: pointer;
  transition: all 0.15s ease;
}
.bbs-accept-btn:hover {
  background: rgba(16, 185, 129, 0.08);
  color: #10b981;
  border-color: #10b981;
}
.bbs-accept-btn.accepted {
  background: rgba(16, 185, 129, 0.12);
  color: #10b981;
  border-color: #10b981;
  border-style: solid;
}

.bbs-ai-tutor-card {
  border: 1px solid rgba(168, 85, 247, 0.3) !important;
  background: rgba(168, 85, 247, 0.04) !important;
  box-shadow: 0 0 15px rgba(168, 85, 247, 0.08);
}
.bbs-ai-pseu {
  color: #c084fc !important;
  font-weight: 600 !important;
}

.bbs-op-actions-right, .bbs-reply-actions-right {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}

.hidden { display: none !important; }


/* ─── Dashboard — /dashboard standalone page ──────────────────────────────
   Per-user activity overview. Designed for warmth and confidence:
   a hero greeting up top with the user's pseudonym + headline stat,
   then a colour-coded card grid where each metric type owns its own
   accent hue. No charting library — CSS handles all the visuals. */

body.dash-body {
  margin: 0;
  background:
    radial-gradient(circle at 0% 0%, rgba(59,130,246,0.08), transparent 40%),
    radial-gradient(circle at 100% 0%, rgba(168,85,247,0.06), transparent 45%),
    var(--bg, #0f172a);
  color: var(--fg, #e2e8f0);
  font-family: 'Inter', system-ui, sans-serif;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* ── Topbar ───────────────────────────────────────────────────────────── */
.dash-topbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 24px;
  border-bottom: 1px solid rgba(148,163,184,0.12);
  background: rgba(15, 23, 42, 0.65);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  flex-shrink: 0;
}
.dash-back {
  color: var(--text-dim, #94a3b8);
  text-decoration: none;
  font-size: 0.88rem;
  padding: 5px 10px;
  border-radius: 6px;
  transition: background 0.15s, color 0.15s;
}
.dash-back:hover { color: var(--fg, #e2e8f0); background: rgba(148,163,184,0.08); }
.dash-brand {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--text-dim, #cbd5e1);
  text-transform: uppercase;
  flex: 1;
}
.dash-pill {
  background: linear-gradient(135deg, rgba(59,130,246,0.2), rgba(168,85,247,0.18));
  color: #c7d2fe;
  border: 1px solid rgba(99, 102, 241, 0.35);
  padding: 5px 14px;
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 500;
}
.dash-refresh {
  background: transparent;
  border: 1px solid rgba(148,163,184,0.2);
  color: var(--text-dim, #cbd5e1);
  cursor: pointer;
  padding: 5px 11px;
  border-radius: 6px;
  font-size: 1rem;
  transition: all 0.15s;
}
.dash-refresh:hover {
  background: rgba(148,163,184,0.08);
  color: var(--fg, #e2e8f0);
  transform: rotate(45deg);
}

.dash-main {
  flex: 1;
  padding: 28px 32px 80px;
  max-width: 1180px;
  width: 100%;
  margin: 0 auto;
  box-sizing: border-box;
}
.dash-loading, .dash-empty, .dash-error {
  font-size: 0.92rem;
  color: var(--text-dim, #94a3b8);
  text-align: center;
  padding: 32px 16px;
  background: rgba(30, 41, 59, 0.4);
  border: 1px dashed rgba(148,163,184,0.15);
  border-radius: 10px;
}
.dash-error { color: #ef4444; }

/* ── Hero — greeting + headline stat ──────────────────────────────────── */
.dash-hero {
  display: flex;
  align-items: center;
  gap: 22px;
  padding: 24px 28px;
  margin-bottom: 24px;
  background:
    linear-gradient(135deg, rgba(59,130,246,0.12), rgba(168,85,247,0.08)),
    rgba(30, 41, 59, 0.55);
  border: 1px solid rgba(99, 102, 241, 0.22);
  border-radius: 14px;
  box-shadow: 0 8px 24px -12px rgba(59,130,246,0.25);
}
.dash-avatar {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: linear-gradient(135deg, #6366f1, #ec4899);
  color: #fff;
  font-size: 1.4rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  box-shadow: 0 4px 14px -4px rgba(99, 102, 241, 0.55);
}
.dash-hero-text { flex: 1; min-width: 0; }
.dash-hello {
  display: block;
  color: var(--text-dim, #94a3b8);
  font-size: 0.85rem;
  margin-bottom: 2px;
}
.dash-user-name {
  display: block;
  font-size: 1.4rem;
  font-weight: 600;
  color: var(--fg, #e2e8f0);
}
.dash-user-sub {
  display: block;
  color: var(--text-dim, #94a3b8);
  font-size: 0.8rem;
  margin-top: 2px;
}
.dash-hero-headline {
  text-align: right;
  flex-shrink: 0;
}
.dash-hero-num {
  display: block;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 2.2rem;
  font-weight: 700;
  color: var(--fg, #e2e8f0);
  line-height: 1;
  background: linear-gradient(135deg, #60a5fa, #c084fc);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  font-variant-numeric: tabular-nums;
}
.dash-hero-lbl {
  display: block;
  color: var(--text-dim, #94a3b8);
  font-size: 0.78rem;
  margin-top: 4px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* ── KPI strip — 3 small stat tiles ───────────────────────────────────── */
.dash-kpi-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  margin-bottom: 18px;
}
.dash-kpi {
  background: rgba(30, 41, 59, 0.55);
  border: 1px solid rgba(148,163,184,0.1);
  border-radius: 12px;
  padding: 14px 18px;
  position: relative;
  overflow: hidden;
  transition: transform 0.15s, border-color 0.15s;
}
.dash-kpi:hover {
  transform: translateY(-2px);
  border-color: rgba(99, 102, 241, 0.3);
}
.dash-kpi::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--kpi-accent, #60a5fa);
  border-radius: 3px 0 0 3px;
}
.dash-kpi-icon {
  font-size: 1.3rem;
  margin-bottom: 4px;
  filter: saturate(1.1);
}
.dash-kpi-val {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 1.6rem;
  font-weight: 600;
  color: var(--fg, #e2e8f0);
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
.dash-kpi-lbl {
  font-size: 0.75rem;
  color: var(--text-dim, #94a3b8);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-top: 2px;
}
.dash-kpi-sub {
  font-size: 0.78rem;
  color: var(--text-dim, #94a3b8);
  margin-top: 4px;
}

/* ── Card grid ────────────────────────────────────────────────────────── */
.dash-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
  gap: 16px;
}
.dash-card {
  background:
    linear-gradient(180deg, rgba(99,102,241,0.04), transparent 80%),
    rgba(30, 41, 59, 0.55);
  border: 1px solid rgba(148,163,184,0.12);
  border-radius: 12px;
  padding: 18px 22px;
  position: relative;
  transition: transform 0.15s, border-color 0.15s, box-shadow 0.15s;
}
.dash-card:hover {
  transform: translateY(-2px);
  border-color: rgba(99, 102, 241, 0.28);
  box-shadow: 0 12px 28px -16px rgba(0,0,0,0.55);
}
.dash-card-wide { grid-column: 1 / -1; }

.dash-card-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}
.dash-card-icon {
  font-size: 1.2rem;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: var(--card-tint, rgba(99,102,241,0.15));
  flex-shrink: 0;
}
.dash-card h2 {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--fg, #e2e8f0);
  letter-spacing: 0;
  text-transform: none;
}
.dash-card-sub {
  margin-left: auto;
  font-size: 0.78rem;
  color: var(--text-dim, #94a3b8);
  font-variant-numeric: tabular-nums;
}

/* Per-card colour identity. Set via inline custom property in JS. */
.dash-card[data-tone="tokens"]    { --card-tint: rgba(59,130,246,0.18);   --kpi-accent: #60a5fa; }
.dash-card[data-tone="nodes"]     { --card-tint: rgba(245,158,11,0.18);   --kpi-accent: #fbbf24; }
.dash-card[data-tone="courses"]   { --card-tint: rgba(168,85,247,0.18);   --kpi-accent: #c084fc; }
.dash-card[data-tone="exercises"] { --card-tint: rgba(34,197,94,0.18);    --kpi-accent: #4ade80; }
.dash-card[data-tone="community"] { --card-tint: rgba(236,72,153,0.18);   --kpi-accent: #f472b6; }

.dash-kpi[data-tone="tokens"]    { --kpi-accent: #60a5fa; }
.dash-kpi[data-tone="exercises"] { --kpi-accent: #4ade80; }
.dash-kpi[data-tone="tutorials"] { --kpi-accent: #c084fc; }

/* ── Number rows inside cards ─────────────────────────────────────────── */
.dash-bignums {
  display: flex;
  gap: 28px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.dash-bignum { display: flex; flex-direction: column; gap: 4px; min-width: 100px; }
.dash-bn-val {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 1.65rem;
  font-weight: 600;
  color: var(--fg, #e2e8f0);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.dash-bn-lbl {
  font-size: 0.73rem;
  color: var(--text-dim, #94a3b8);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* ── Table styling — for per-model token use and node list ───────────── */
.dash-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
  margin-top: 6px;
}
.dash-table th, .dash-table td {
  text-align: left;
  padding: 8px 10px;
}
.dash-table thead th {
  color: var(--text-dim, #94a3b8);
  font-weight: 500;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  border-bottom: 1px solid rgba(148,163,184,0.18);
}
.dash-table tbody tr {
  border-bottom: 1px solid rgba(148,163,184,0.08);
  transition: background 0.1s;
}
.dash-table tbody tr:last-child { border-bottom: none; }
.dash-table tbody tr:hover { background: rgba(99,102,241,0.06); }
.dash-table .dash-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}
.dash-table .dash-mname {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.82rem;
  color: #c7d2fe;
}
.dash-models code {
  background: rgba(99,102,241,0.12);
  color: #c7d2fe;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 0.75rem;
  margin-right: 4px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}

/* ── Nodes — pretty dot ───────────────────────────────────────────────── */
.dash-dot {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  margin-right: 8px;
  vertical-align: middle;
  flex-shrink: 0;
}
.dash-dot-on {
  background: #22c55e;
  box-shadow: 0 0 0 3px rgba(34,197,94,0.18), 0 0 10px rgba(34,197,94,0.6);
  animation: dash-pulse 2.4s ease-in-out infinite;
}
.dash-dot-off { background: #64748b; }
@keyframes dash-pulse {
  0%, 100% { box-shadow: 0 0 0 3px rgba(34,197,94,0.14), 0 0 6px rgba(34,197,94,0.4); }
  50%      { box-shadow: 0 0 0 5px rgba(34,197,94,0.04), 0 0 12px rgba(34,197,94,0.7); }
}
.dash-node-name { display: inline-flex; align-items: center; }
.dash-node-offline td { opacity: 0.5; }

/* ── Courses — progress rows ──────────────────────────────────────────── */
.dash-course {
  margin-bottom: 14px;
}
.dash-course:last-child { margin-bottom: 0; }
.dash-course-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  font-size: 0.88rem;
  margin-bottom: 6px;
}
.dash-course-title { font-weight: 500; color: var(--fg, #e2e8f0); }
.dash-course-count {
  color: var(--text-dim, #94a3b8);
  font-variant-numeric: tabular-nums;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.78rem;
}
.dash-course-pct {
  font-size: 0.72rem;
  font-weight: 600;
  color: #c084fc;
  margin-left: 6px;
}
.dash-bar {
  height: 8px;
  background: rgba(148,163,184,0.1);
  border-radius: 999px;
  overflow: hidden;
  position: relative;
}
.dash-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, #a855f7, #ec4899);
  border-radius: 999px;
  transition: width 0.5s ease;
  box-shadow: 0 0 8px rgba(168,85,247,0.4);
}

/* ── Exercises — language chips ───────────────────────────────────────── */
.dash-lang-list {
  list-style: none;
  padding: 0;
  margin: 14px 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.dash-lang-list li {
  background: rgba(34,197,94,0.1);
  border: 1px solid rgba(34,197,94,0.2);
  padding: 4px 12px;
  border-radius: 14px;
  font-size: 0.78rem;
  color: #bbf7d0;
  font-variant-numeric: tabular-nums;
}
.dash-lang-list code {
  font-size: 0.78rem;
  color: #4ade80;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  margin-right: 6px;
}

/* ── Mini grid — tutorials + BBS ──────────────────────────────────────── */
.dash-mini-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 18px;
}
.dash-mini { display: flex; flex-direction: column; gap: 6px; }
.dash-mini-lbl {
  font-size: 0.72rem;
  color: var(--text-dim, #94a3b8);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.dash-mini-val {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--fg, #e2e8f0);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.dash-mini .dash-bar { margin-top: 2px; }

/* ── Footer ───────────────────────────────────────────────────────────── */
.dash-foot {
  margin-top: 24px;
  font-size: 0.72rem;
  color: var(--text-dim, #94a3b8);
  text-align: right;
  font-style: italic;
}

/* Responsive — collapse hero on narrow screens */
@media (max-width: 640px) {
  .dash-hero {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
  }
  .dash-hero-headline { text-align: left; }
  .dash-main { padding: 18px 16px 60px; }
}

/* ─── Lesson suggestion (hybrid pipeline) ─────────────────────────────────
   Header 💡 button + modal dialog for proposing a new learning lesson
   based on the recent chat. The submit path is wired
   (POST /api/tutorials/suggest); the LLM-auto-fill is a JS stub —
   see app-lesson-suggest.js TODO markers. */

.lesson-suggest-btn {
  background: transparent;
  border: 0;
  color: var(--text-dim, #94a3b8);
  cursor: pointer;
  font-size: 1.05rem;
  padding: 4px 8px;
  border-radius: 6px;
  transition: background 0.15s, color 0.15s;
}
.lesson-suggest-btn:hover {
  background: rgba(168,85,247,0.12);
  color: #c084fc;
}

.lesson-suggest-dialog {
  background: var(--bg-surface, #1e293b);
  color: var(--fg, #e2e8f0);
  border: 1px solid var(--border, #334155);
  border-radius: 10px;
  padding: 0;
  max-width: 720px;
  width: 90%;
  max-height: 85vh;
}
.lesson-suggest-dialog::backdrop { background: rgba(0,0,0,0.5); }
.lesson-suggest-form {
  display: flex;
  flex-direction: column;
  max-height: 85vh;
}
.lesson-suggest-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border, #334155);
}
.lesson-suggest-head h2 { margin: 0; font-size: 1.05rem; flex: 1; }
.lesson-suggest-close {
  background: transparent;
  border: 0;
  color: var(--text-dim, #94a3b8);
  cursor: pointer;
  font-size: 1.4rem;
  line-height: 1;
}
.lesson-suggest-hint {
  margin: 0;
  padding: 10px 18px;
  font-size: 0.82rem;
  color: var(--text-dim, #94a3b8);
  line-height: 1.45;
  background: rgba(168,85,247,0.05);
  border-bottom: 1px solid rgba(148,163,184,0.1);
}
.lesson-suggest-generating {
  padding: 18px;
  text-align: center;
  font-style: italic;
  color: var(--text-dim, #94a3b8);
}
.lesson-suggest-fields {
  padding: 14px 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  overflow-y: auto;
  flex: 1;
}
.lesson-suggest-row {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}
.lesson-suggest-fields label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 0.8rem;
  color: var(--text-dim, #94a3b8);
}
.lesson-suggest-fields input,
.lesson-suggest-fields textarea {
  background: var(--bg, #0f172a);
  border: 1px solid var(--border, #334155);
  color: var(--fg, #e2e8f0);
  border-radius: 6px;
  padding: 7px 10px;
  font-size: 0.92rem;
  font-family: inherit;
}
.lesson-suggest-fields textarea {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.85rem;
  line-height: 1.5;
  resize: vertical;
  min-height: 160px;
}
.lesson-suggest-footer {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 18px;
  border-top: 1px solid var(--border, #334155);
}
.lesson-suggest-status {
  font-size: 0.82rem;
  color: var(--text-dim, #94a3b8);
}
.lesson-suggest-status[data-kind="err"] { color: #ef4444; }
.lesson-suggest-status[data-kind="ok"] { color: #22c55e; }

/* ─── Global Scrollbar Redesign ─── */
::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}
::-webkit-scrollbar-track {
  background: transparent;
}
::-webkit-scrollbar-thumb {
  background: rgba(34, 211, 238, 0.12);
  border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
  background: rgba(34, 211, 238, 0.3);
}

/* ─── Premium Glassmorphic Dialog Modals ─── */
dialog {
  background: rgba(10, 20, 36, 0.85) !important;
  backdrop-filter: blur(16px) saturate(180%);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  border: 1px solid rgba(34, 211, 238, 0.16) !important;
  border-radius: 16px !important;
  box-shadow: 
    0 24px 60px rgba(0, 0, 0, 0.65),
    0 0 35px rgba(34, 211, 238, 0.08) !important;
  color: var(--text) !important;
}

dialog::backdrop {
  background: rgba(4, 10, 20, 0.65) !important;
  backdrop-filter: blur(6px) !important;
  -webkit-backdrop-filter: blur(6px) !important;
}
