/* ---------------------------------------------------------------- tokens -- */
:root {
  --bg: #0b0d12;
  --bg-1: #11141b;
  --bg-2: #161a23;
  --bg-3: #1d222d;
  --line: #262c38;
  --line-soft: #1e2430;
  --text: #e6e9ef;
  --text-dim: #9aa3b2;
  --text-faint: #6b7488;
  --accent: #d97757;
  --accent-soft: rgba(217, 119, 87, .14);
  --ok: #4ade80;
  --warn: #fbbf24;
  --err: #f87171;
  --info: #60a5fa;
  --radius: 12px;
  --radius-sm: 8px;
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, sans-serif;
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-top, 0px);
  --tabbar-h: 58px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 15px;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
}

button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--info); }

/* ------------------------------------------------------------------ boot -- */
.boot { position: fixed; inset: 0; display: grid; place-items: center; background: var(--bg); z-index: 100; }
.spinner {
  width: 28px; height: 28px; border-radius: 50%;
  border: 2.5px solid var(--line); border-top-color: var(--accent);
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ----------------------------------------------------------------- login -- */
.login { position: fixed; inset: 0; display: grid; place-items: center; padding: 24px; z-index: 90; }
.login-card {
  width: 100%; max-width: 340px; background: var(--bg-1);
  border: 1px solid var(--line); border-radius: 18px; padding: 30px 24px 24px;
  display: flex; flex-direction: column; gap: 12px; text-align: center;
  box-shadow: 0 24px 60px rgba(0,0,0,.5);
}
.login-mark { display: flex; justify-content: center; margin-bottom: 4px; }
.login-card h1 { margin: 0; font-size: 20px; font-weight: 650; letter-spacing: -.01em; }
.login-card p { margin: 0 0 8px; font-size: 13.5px; }
.login-card input {
  background: var(--bg-3); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 12px 14px; outline: none; width: 100%;
}
.login-card input:focus { border-color: var(--accent); }
.login-error {
  background: rgba(248,113,113,.12); border: 1px solid rgba(248,113,113,.3);
  color: #fca5a5; border-radius: var(--radius-sm); padding: 9px 12px; font-size: 13px;
}

/* ------------------------------------------------------------------- app -- */
.app { display: flex; flex-direction: column; height: 100dvh; }

.topbar {
  display: flex; align-items: center; gap: 10px;
  padding: calc(var(--safe-t) + 9px) 12px 9px;
  background: var(--bg-1); border-bottom: 1px solid var(--line);
  flex: 0 0 auto; min-height: 52px;
}
.brand { display: flex; align-items: center; gap: 8px; font-weight: 620; font-size: 14.5px; }
.brand-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-faint); }
.layout { display: flex; flex: 1 1 auto; min-height: 0; }

.sidenav {
  display: none; flex-direction: column; gap: 2px; width: 208px; flex: 0 0 208px;
  padding: 12px 10px; background: var(--bg-1); border-right: 1px solid var(--line);
}
.nav-spacer { flex: 1 1 auto; }
.nav-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 10px 12px; border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--text-dim); cursor: pointer; text-align: left;
  font-size: 14px; transition: background .12s, color .12s;
}
.nav-item:hover { background: var(--bg-2); color: var(--text); }
.nav-item.active { background: var(--accent-soft); color: var(--accent); }
.nav-item.danger:hover { color: var(--err); }

.content { flex: 1 1 auto; min-width: 0; min-height: 0; position: relative; }
.tab-panel { display: none; height: 100%; overflow: hidden; }
.tab-panel.active { display: flex; flex-direction: column; }

.tabbar {
  display: flex; flex: 0 0 auto; background: var(--bg-1);
  border-top: 1px solid var(--line); padding-bottom: var(--safe-b);
}
.tab-btn {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 9px 4px; background: none; border: 0; color: var(--text-faint);
  font-size: 10.5px; cursor: pointer;
}
.tab-btn.active { color: var(--accent); }

@media (max-width: 859px) {
  /* bottom tabbar handles navigation on mobile */
  #nav-toggle { display: none; }
}

@media (min-width: 860px) {
  .only-mobile { display: none !important; }
  .sidenav { display: flex; }
}

/* --------------------------------------------------------------- scroller -- */
.scroll { flex: 1 1 auto; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 14px; padding-bottom: 28px; }
.scroll::-webkit-scrollbar, .pre::-webkit-scrollbar { width: 8px; height: 8px; }
.scroll::-webkit-scrollbar-thumb, .pre::-webkit-scrollbar-thumb { background: var(--line); border-radius: 4px; }

/* ----------------------------------------------------------------- cards -- */
.card {
  background: var(--bg-1); border: 1px solid var(--line);
  border-radius: var(--radius); margin-bottom: 12px; overflow: hidden;
}
.card-head {
  display: flex; align-items: center; gap: 8px; padding: 12px 14px;
  border-bottom: 1px solid var(--line-soft);
}
.card-head h2, .card-head h3 { margin: 0; font-size: 13.5px; font-weight: 620; letter-spacing: .01em; }
.card-head .spacer { flex: 1 1 auto; }
.card-body { padding: 14px; display: flex; flex-direction: column; gap: 12px; }
.card-body.tight { gap: 8px; }
.card.collapsible .card-head { cursor: pointer; user-select: none; }
.card.collapsed .card-body { display: none; }
.card.collapsible .chevron { transition: transform .18s; color: var(--text-faint); }
.card.collapsed .chevron { transform: rotate(-90deg); }

.section-title {
  font-size: 11px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-faint); font-weight: 640; margin: 4px 0 2px;
}

/* --------------------------------------------------------------- controls -- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 8px 13px; border-radius: var(--radius-sm); border: 1px solid var(--line);
  background: var(--bg-3); color: var(--text); cursor: pointer;
  font-size: 13px; font-weight: 520; white-space: nowrap;
  transition: background .12s, border-color .12s, opacity .12s;
}
.btn:hover:not(:disabled) { background: #232935; border-color: #333c4d; }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #1a0d07; font-weight: 600; }
.btn.primary:hover:not(:disabled) { background: #e08663; border-color: #e08663; }
.btn.ghost { background: transparent; }
.btn.danger { color: var(--err); border-color: rgba(248,113,113,.3); }
.btn.danger:hover:not(:disabled) { background: rgba(248,113,113,.12); }
.btn.sm { padding: 5px 9px; font-size: 12px; }
.btn.block { width: 100%; }
.btn-row { display: flex; flex-wrap: wrap; gap: 8px; }

.icon-btn {
  display: grid; place-items: center; width: 34px; height: 34px; flex: 0 0 auto;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--bg-2); color: var(--text-dim); cursor: pointer;
}
.icon-btn:hover { color: var(--text); background: var(--bg-3); }

.field { display: flex; flex-direction: column; gap: 5px; }
.field label { font-size: 11.5px; color: var(--text-dim); font-weight: 560; }
.field .hint { font-size: 11.5px; color: var(--text-faint); }
input[type=text], input[type=password], input[type=url], select, textarea {
  background: var(--bg-3); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 9px 11px; outline: none; width: 100%; min-width: 0;
}
input:focus, select:focus, textarea:focus { border-color: var(--accent); }
textarea { resize: vertical; font-family: var(--mono); font-size: 12.5px; line-height: 1.5; }
select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--text-faint) 50%), linear-gradient(135deg, var(--text-faint) 50%, transparent 50%); background-position: right 14px center, right 9px center; background-size: 5px 5px; background-repeat: no-repeat; padding-right: 30px; }
.row { display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap; }
.row > .field { flex: 1 1 160px; }
.switch { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-dim); cursor: pointer; }
.switch input { width: auto; accent-color: var(--accent); }

/* ---------------------------------------------------------------- pieces -- */
.chip {
  display: inline-flex; align-items: center; gap: 5px; padding: 3px 8px;
  border-radius: 999px; background: var(--bg-3); border: 1px solid var(--line);
  font-size: 11.5px; color: var(--text-dim); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.chip.ok { color: var(--ok); border-color: rgba(74,222,128,.28); background: rgba(74,222,128,.1); }
.chip.warn { color: var(--warn); border-color: rgba(251,191,36,.28); background: rgba(251,191,36,.1); }
.chip.err { color: var(--err); border-color: rgba(248,113,113,.28); background: rgba(248,113,113,.1); }
.chip.accent { color: var(--accent); border-color: rgba(217,119,87,.32); background: var(--accent-soft); }
.dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: 0 0 auto; }

.list { display: flex; flex-direction: column; gap: 6px; }
.list-item {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px;
  background: var(--bg-2); border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm); cursor: pointer; transition: border-color .12s, background .12s;
}
.list-item:hover { border-color: var(--line); background: var(--bg-3); }
.list-item.selected { border-color: var(--accent); background: var(--accent-soft); }
.list-item .grow { flex: 1 1 auto; min-width: 0; }
.list-item .title { font-size: 13.5px; font-weight: 550; display: flex; align-items: center; gap: 6px; }
.list-item .sub {
  font-size: 11.5px; color: var(--text-faint); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.list-item .actions { display: flex; gap: 5px; flex: 0 0 auto; }

/* The launcher's rows carry a second line of git controls, so they wrap. */
.rc-row { flex-wrap: wrap; cursor: default; }

/* Too narrow for the name and the start buttons to share a line: give each
   the full width and center it. Daemon output stays left, since a centered
   block of terminal text reads as decoration. */
@media (max-width: 859px) {
  .rc-row .grow { flex: 1 1 100%; text-align: center; }
  .rc-row .title, .rc-row .sub { justify-content: center; }
  .rc-row .btn-row { flex: 1 1 100%; justify-content: center; }
  .rc-row .rc-why { text-align: left; }
}

.rc-git {
  flex: 1 1 100%; display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  padding-top: 9px; margin-top: 2px; border-top: 1px solid var(--line-soft);
}
.rc-git .rc-branch {
  flex: 1 1 140px; min-width: 0; max-width: 260px;
  padding: 5px 26px 5px 9px; font-size: 12px;
  background-position: right 11px center, right 6px center;
}
.rc-git .btn { flex: 0 0 auto; }
.rc-git-mark { display: flex; color: var(--text-faint); flex: 0 0 auto; }

/* A recommendation's second line is a sentence, not a file path: ellipsising it
   loses the reason for the recommendation, so it wraps instead. The name above
   it is a long plugin id, which wraps rather than pushing the button off. */
.rec-row { cursor: default; align-items: flex-start; }
.rec-row .title { flex-wrap: wrap; word-break: break-word; }
.rec-row .sub { white-space: normal; overflow: visible; line-height: 1.45; }

/* Too narrow for a sentence and a button side by side: give the button its own
   full-width line under the text. */
@media (max-width: 599px) {
  .rec-row { flex-wrap: wrap; }
  .rec-row .actions { flex: 1 1 100%; }
  .rec-row .actions .btn { flex: 1 1 auto; justify-content: center; }
}

.mono { font-family: var(--mono); font-size: 12.5px; }
.muted { color: var(--text-dim); }
.faint { color: var(--text-faint); }
.small { font-size: 12px; }
.empty { padding: 26px 14px; text-align: center; color: var(--text-faint); font-size: 13px; }
.kv { display: grid; grid-template-columns: minmax(90px, auto) 1fr; gap: 6px 14px; font-size: 12.5px; }
.kv dt { color: var(--text-faint); }
.kv dd { margin: 0; font-family: var(--mono); word-break: break-all; }

.pre {
  background: #08090d; border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
  padding: 11px 12px; font-family: var(--mono); font-size: 12px; line-height: 1.55;
  white-space: pre-wrap; word-break: break-word; overflow: auto; max-height: 340px;
  color: #cfd6e2; margin: 0;
}
.pre.err { color: #fca5a5; }
.pre.short { max-height: 180px; }

.subtabs {
  display: flex; gap: 4px; overflow-x: auto; padding: 10px 12px 0;
  border-bottom: 1px solid var(--line); background: var(--bg-1); flex: 0 0 auto;
  scrollbar-width: none;
}
.subtabs::-webkit-scrollbar { display: none; }
.subtab {
  padding: 7px 12px 9px; background: none; border: 0; border-bottom: 2px solid transparent;
  color: var(--text-faint); font-size: 13px; cursor: pointer; white-space: nowrap;
}
.subtab.active { color: var(--accent); border-bottom-color: var(--accent); }

/* A tab strip that picks a value rather than a view - used by the model picker.
   Wraps rather than scrolls: on a phone the positions stack instead of hiding
   the one on the end, which is the whole choice being made. */
.seg {
  display: flex; flex-wrap: wrap; gap: 3px; padding: 3px;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.seg-btn {
  flex: 1 1 auto; padding: 8px 12px; border: 0; border-radius: 6px;
  background: none; color: var(--text-dim); cursor: pointer;
  font-size: 13px; white-space: nowrap; transition: background .12s, color .12s;
}
.seg-btn:hover:not(.active) { background: var(--bg-3); color: var(--text); }
.seg-btn.active { background: var(--accent-soft); color: var(--accent); font-weight: 560; }

/* ---------------------------------------------------------------- toasts -- */
.toasts {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--tabbar-h) + var(--safe-b) + 12px);
  display: flex; flex-direction: column; gap: 8px; z-index: 60;
  width: min(440px, calc(100vw - 24px)); pointer-events: none;
}
@media (min-width: 860px) { .toasts { bottom: 16px; left: auto; right: 16px; transform: none; } }
.toast {
  background: var(--bg-3); border: 1px solid var(--line); border-left: 3px solid var(--info);
  border-radius: var(--radius-sm); padding: 10px 13px; font-size: 13px;
  box-shadow: 0 10px 30px rgba(0,0,0,.45); pointer-events: auto;
  animation: toast-in .18s ease-out;
}
.toast.ok { border-left-color: var(--ok); }
.toast.err { border-left-color: var(--err); }
.toast.warn { border-left-color: var(--warn); }
.toast .t-title { font-weight: 600; margin-bottom: 2px; }
.toast .t-body { color: var(--text-dim); font-size: 12.5px; white-space: pre-wrap; word-break: break-word; max-height: 130px; overflow: auto; }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } }

/* ----------------------------------------------------------------- modal -- */
.modal-root {
  position: fixed; inset: 0; z-index: 80; background: rgba(0,0,0,.62);
  display: grid; place-items: center; padding: 16px; backdrop-filter: blur(3px);
}
.modal {
  background: var(--bg-1); border: 1px solid var(--line); border-radius: 16px;
  width: min(680px, 100%); max-height: min(86dvh, 800px);
  display: flex; flex-direction: column; overflow: hidden;
  box-shadow: 0 24px 70px rgba(0,0,0,.6);
}
.modal-head { display: flex; align-items: center; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--line); }
.modal-head h3 { margin: 0; font-size: 14.5px; font-weight: 620; flex: 1 1 auto; }
.modal-body { padding: 16px; overflow-y: auto; display: flex; flex-direction: column; gap: 12px; }
.modal-body textarea { min-height: 320px; }
.modal-foot { display: flex; gap: 8px; justify-content: flex-end; padding: 12px 16px; border-top: 1px solid var(--line); }

.job-log { max-height: 300px; }
.progress { height: 2px; background: var(--line); border-radius: 2px; overflow: hidden; }
.progress i { display: block; height: 100%; width: 40%; background: var(--accent); animation: slide 1.1s ease-in-out infinite; }
@keyframes slide { 0% { margin-left: -40%; } 100% { margin-left: 100%; } }

/* ----------------------------------------------------------------- last -- */
/* The `hidden` attribute only carries a user-agent `display: none`, and any
   author `display` rule outranks it - .boot, .login, .app and .modal-root all
   set one. Without this the boot overlay stays painted over the whole page and
   the UI never gets past the spinner. Last in the file and !important so it
   wins on both source order and the cascade. */
[hidden] { display: none !important; }
