/* start — the calm front door.
   Design intent: paper, not dashboard. One accent colour, used only where something is ALIVE.
   No shadows competing for attention, no gradients, no chrome. Everything that is not a name,
   a sentence or a live signal is dimmed out of the way.
   Mobile-first: the base rules are the iPhone layout; media queries only widen it. */

:root {
  /* ONE scheme, deliberately (Elias 2026-07-30): no dark mode. color-scheme:light pins form
     controls and scrollbars to it too, so a device in dark mode cannot repaint half the page. */
  color-scheme: light;

  /* Warm paper ground — softer than white, easier to sit in front of at night. */
  --bg: #f5f4f0;
  --card: #fbfaf7;
  --card-hover: #fffefc;
  --ink: #201f1c;
  --ink-soft: #4d4b45;
  --dim: #85827a;
  --rule: #e3e0d8;
  --rule-strong: #cfcbc0;
  --accent: #5f7d6b;      /* muted sage — the only colour with a job */
  --live: #45865f;
  --danger: #a1584a;

  --radius: 14px;
  --gap: 10px;
  --page-max: 1080px;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  --sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, "Segoe UI", sans-serif;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 16px/1.55 var(--sans);
  /* Safe areas keep the standalone iPhone app clear of the notch and home indicator. */
  padding: 0 env(safe-area-inset-right) calc(48px + env(safe-area-inset-bottom)) env(safe-area-inset-left);
  -webkit-font-smoothing: antialiased;
}

/* ---------- top bar ---------- */
/* Sticky so search is always one tap away however far down the page he is. */
.topbar {
  position: sticky;
  top: 0;
  z-index: 10;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(1.4) blur(14px);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color .2s ease;
  padding-top: env(safe-area-inset-top);
}
.topbar.scrolled { border-bottom-color: var(--rule); }

.topbar-inner {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 13px 18px;
  display: flex;
  align-items: center;
  gap: 14px;
}

.brand {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .01em;
  color: var(--ink);
  text-decoration: none;
  flex: 0 0 auto;
}

.search {
  flex: 1;
  min-width: 0;
  /* Capped: stretched edge-to-edge on a 15" screen a search field reads as a demand rather than
     an option. It only needs to be wide enough to hold a word. */
  max-width: 380px;
  font: 15px var(--sans);
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 10px;
  padding: 9px 12px;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color .15s ease, background .15s ease;
}
.search::placeholder { color: var(--dim); }
.search:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--card-hover);
}
.search::-webkit-search-cancel-button { -webkit-appearance: none; }

/* ---------- page ---------- */
.page {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 22px 18px 0;
}

.block { margin-bottom: 34px; }
.block[hidden] { display: none; }

.block-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 0 2px 11px;
}

.block-head h2 {
  margin: 0;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--dim);
}

.block-note {
  font: 11px/1 var(--mono);
  letter-spacing: .04em;
  color: var(--dim);
}

.block-hint {
  margin: -7px 2px 11px;
  font-size: 13px;
  color: var(--dim);
}

/* ---------- app grid ---------- */
.grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--gap);
}

.card {
  display: block;
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 14px 16px;
  text-decoration: none;
  color: inherit;
  transition: border-color .15s ease, background .15s ease, transform .15s ease;
}
.card[hidden] { display: none; }

.card-name {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 15.5px;
  font-weight: 600;
  letter-spacing: -.005em;
  color: var(--ink);
}

.card-tag {
  font: 10px/1 var(--mono);
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--dim);
  border: 1px solid var(--rule-strong);
  border-radius: 4px;
  padding: 3px 5px;
}

.card-blurb {
  margin: 5px 0 0;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--ink-soft);
  text-wrap: pretty;
}

.card-host {
  margin: 8px 0 0;
  font: 11px/1 var(--mono);
  color: var(--dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Pointer devices only — on touch these states just flash on tap and read as noise. */
@media (hover: hover) {
  .card:hover {
    background: var(--card-hover);
    border-color: var(--rule-strong);
    transform: translateY(-1px);
  }
}
.card:active { transform: scale(.995); }

/* ---------- sessions ---------- */
.sessions { display: flex; flex-direction: column; gap: 7px; }

.session {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 12px;
  padding: 11px 10px 11px 13px;
}
.session[hidden] { display: none; }
.session.system { opacity: .72; }

/* The jump target IS the row body: the biggest, easiest tap on the whole card. */
/* Wraps to two lines on a phone, collapses to one on a wide screen — same markup, no breakpoint.
   Full-width rows carrying a two-line stack left a lot of empty space on the 15" layout. */
.session-jump {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 12px;
  text-decoration: none;
  color: inherit;
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

/* flex-basis 220px is the wrap trigger: below it the meta line drops underneath, above it they share a row. */
.session-line { flex: 1 1 220px; display: flex; align-items: center; gap: 8px; min-width: 0; }

/* Filled dot = attached right now; hollow = running but nobody is looking at it. */
.dot {
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  border: 1.5px solid var(--live);
  background: transparent;
}
.dot.attached { background: var(--live); }
.dot.shell { border-color: var(--dim); }

.session-name {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -.005em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.session-kind {
  flex: 0 0 auto;
  font: 10px/1 var(--mono);
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--dim);
}

.session-meta {
  flex: 0 1 auto;
  margin: 0 0 0 15px;
  display: flex;
  gap: 9px;
  font: 11px/1.35 var(--mono);
  color: var(--dim);
  min-width: 0;
}
.session-cwd { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Inline rename: the name is replaced in place, so the row never jumps. */
.session-rename {
  flex: 1;
  min-width: 0;
  font: 15px var(--sans);
  font-weight: 600;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--accent);
  border-radius: 8px;
  padding: 6px 9px;
}
.session-rename:focus { outline: none; }

/* 40px square: comfortably tappable on the phone without dominating the row. */
.act {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border: 1px solid transparent;
  border-radius: 10px;
  background: none;
  color: var(--dim);
  font: 14px/1 var(--sans);
  cursor: pointer;
  transition: color .15s ease, background .15s ease, border-color .15s ease;
}
@media (hover: hover) {
  .act:hover { color: var(--ink); background: var(--bg); border-color: var(--rule); }
  .act.kill:hover { color: var(--danger); }
}
.act.armed {
  color: var(--danger);
  border-color: var(--danger);
  width: auto;
  padding: 0 11px;
  font-size: 12px;
  font-weight: 600;
}

.system-toggle {
  margin-top: 9px;
  border: 0;
  background: none;
  padding: 6px 2px;
  font: 12px var(--sans);
  color: var(--dim);
  cursor: pointer;
}
@media (hover: hover) { .system-toggle:hover { color: var(--ink); } }

.sessions-empty, .empty {
  margin: 0;
  padding: 16px 2px;
  font-size: 14px;
  color: var(--dim);
}

.err { color: var(--danger); }

/* ---------- focus, motion, width ---------- */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 6px;
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}

/* iPhone landscape / small tablets */
@media (min-width: 620px) {
  .grid { grid-template-columns: 1fr 1fr; }
}
/* 15" MacBook Air and anything wider */
@media (min-width: 1000px) {
  .grid { grid-template-columns: 1fr 1fr 1fr; }
  .page { padding-top: 30px; }
  .block { margin-bottom: 42px; }
}

/* ---------- login ---------- */
.login {
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: 24px;
}
.login form {
  width: 100%;
  max-width: 320px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  text-align: center;
}
.login .brand { font-size: 17px; margin-bottom: 6px; }
.login input {
  font: 16px var(--sans); /* 16px keeps iOS Safari from zooming the page on focus */
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 10px;
  padding: 12px 14px;
  text-align: center;
}
.login input:focus { outline: none; border-color: var(--accent); }
.login button {
  font: 15px var(--sans);
  font-weight: 600;
  color: var(--bg);
  background: var(--accent);
  border: 0;
  border-radius: 10px;
  padding: 12px;
  cursor: pointer;
}
.login .msg { font-size: 13px; color: var(--danger); min-height: 18px; margin: 0; }
