/**
 * @file home.css
 * @description Styles for KOTI, the home path (koti- prefix): the welcome, the numbered step list
 *   with exactly one step open and the rest named-but-dimmed, the prompt block, the paste box and
 *   its error state. Theme tokens only — no hardcoded colours, no rgba(255,255,255,…).
 *
 *   The step list is deliberately plain. The screen has one job at a time, so anything that draws
 *   the eye away from the open step is working against it.
 * @version-history
 *   v2.0.0 — 2026-08-18 — The four room cards left the finished home (status-view turn), so their
 *     styles leave too; in their place .koti-chatdoor (the one door to the chat) and .koti-matline
 *     (the mat address as one line under the greeting).
 *   v1.2.0 — 2026-08-17 — .koti-hist-*: the whole record behind the card. Grouped by day, because
 *     a hundred rows each saying "3 d ago" is a list nobody can navigate, and the archive under a
 *     rule of its own so opening it is a decision rather than a scroll.
 *   v1.1.0 — 2026-08-16 — .koti-feed-quiet: the feed's quiet-days nudge, a dashed door into the
 *     chat rather than an alarm.
 *   v1.0.0 — 2026-08-07 — Initial (remake phase 3).
 *   v1.0.1 — 2026-08-07 — Rooms block gets a bottom margin: measured 0px between it and the done
 *     mat card on the finished home, so the two bordered cards collided.
 *   v1.1.0 — 2026-08-07 — The header (nameplate + settings) and the settings dialog. The dialog
 *     overrides .modal's single-box scroll so the tab row cannot scroll out of reach.
 */

.koti {
  max-width: 720px;
  margin: 0 auto;
  padding: 2rem 1.25rem 4rem;
  color: var(--text);
}

.koti-loading { display: flex; justify-content: center; padding: 4rem 0; }

/* ── Welcome ── */
.koti-welcome { margin-bottom: 2rem; }
.koti-h1 {
  font-size: 1.9rem;
  font-weight: 800;
  letter-spacing: -0.4px;
  margin: 0 0 0.6rem;
  line-height: 1.2;
}
.koti-welcome-sub { color: var(--text-dim); font-size: 1.05rem; margin: 0; }

/* ── The step list ── */
.koti-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1rem; }

.koti-step {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  padding: 1.25rem 1.35rem;
}
/* The open step is the only thing on the page with an accent edge. */
.koti-step-open { border-color: var(--accent); }
.koti-step-done { border-color: var(--success); }
.koti-step-dim { opacity: 0.55; background: var(--surface); }

.koti-step-head { display: flex; align-items: center; gap: 0.7rem; margin-bottom: 0.6rem; }
.koti-step-num {
  flex: none;
  width: 1.75rem; height: 1.75rem;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-full);
  border: 1px solid var(--border);
  background: var(--bg-dim);
  font-size: 0.85rem; font-weight: 700;
  color: var(--text-dim);
}
.koti-step-open .koti-step-num { border-color: var(--accent); color: var(--accent); }
.koti-step-num-done { border-color: var(--success); color: var(--success); }

.koti-step-title { font-size: 1.15rem; font-weight: 700; margin: 0; }
.koti-step-lede { color: var(--text-dim); font-size: 0.98rem; line-height: 1.55; margin: 0 0 1.1rem; }
.koti-step-dim .koti-step-lede { margin-bottom: 0; }

/* ── The prompt block ── */
.koti-prompt {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-dim);
  margin-bottom: 1.25rem;
  overflow: hidden;
}
.koti-prompt-head {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.6rem 0.85rem;
  border-bottom: 1px solid var(--border);
}
.koti-prompt-label {
  font-size: 0.78rem; text-transform: uppercase; letter-spacing: 1.2px;
  color: var(--muted); font-weight: 700;
}
/* Copy stays the button; the chevron is a small sibling, never a chooser in front of it. */
.koti-prompt-actions { display: flex; align-items: center; gap: 0.4rem; }
.koti-prompt-actions > :first-child { flex: 1 1 auto; }
.koti-prompt-more {
  flex: none; padding: 0.35rem 0.5rem; line-height: 1;
  font-size: 0.9rem; color: var(--muted);
}
.koti-prompt-menu {
  display: flex; flex-direction: column; align-items: stretch;
  border-bottom: 1px solid var(--border);
  background: var(--card);
}
.koti-prompt-menu-item {
  text-align: left; padding: 0.55rem 0.85rem; font-size: 0.85rem;
  border-radius: 0;
}
.koti-prompt-menu-item + .koti-prompt-menu-item { border-top: 1px solid var(--border); }

.koti-prompt-body {
  margin: 0;
  padding: 0.85rem;
  /* The prompt is long on purpose; a scroll box keeps the paste box on screen. */
  max-height: 14rem;
  overflow: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--text-dim);
  white-space: pre-wrap;
  word-break: break-word;
}

/* ── The paste box ── */
.koti-paste-label {
  display: block;
  font-size: 0.9rem; font-weight: 600;
  margin-bottom: 0.4rem;
}
.koti-paste {
  width: 100%;
  box-sizing: border-box;
  padding: 0.75rem 0.85rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  color: var(--text);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.85rem;
  line-height: 1.5;
  resize: vertical;
}
.koti-paste:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }

/* ── The error, which never clears the box ── */
.koti-error {
  margin-top: 1rem;
  border: 1px solid var(--danger);
  border-radius: var(--radius-sm);
  background: var(--bg-dim);
  padding: 0.85rem 1rem;
}
.koti-error-text { margin: 0 0 0.4rem; font-weight: 600; color: var(--text); }
.koti-error-hint { margin: 0; font-size: 0.9rem; color: var(--text-dim); line-height: 1.5; }
.koti-fallback-btn { margin-top: 0.6rem; }

.koti-actions { display: flex; gap: 0.7rem; flex-wrap: wrap; margin-top: 1.25rem; }

/* ── The finished mat ── */
.koti-mat-links { display: flex; align-items: center; gap: 0.9rem; flex-wrap: wrap; }
.koti-mat-url {
  font-size: 0.85rem; color: var(--text-dim);
  word-break: break-all;
}

/* ── Step 2: naming, the two ways of doing it, and the wait ── */
.koti-hint { font-size: 0.88rem; color: var(--text-dim); margin: 0 0 0.6rem; }
.koti-input {
  width: 100%;
  box-sizing: border-box;
  padding: 0.65rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  color: var(--text);
  font-size: 1rem;
  font-family: inherit;
}
.koti-input:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }

.koti-named { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 1rem; }
.koti-named-label { color: var(--text-dim); font-size: 0.92rem; }
.koti-named-value { font-size: 1rem; }
.koti-rename { font-size: 0.85rem; }

.koti-modes { display: flex; gap: 0.5rem; margin-bottom: 1rem; flex-wrap: wrap; }
.koti-mode-on { border-color: var(--accent); color: var(--accent); }

.koti-manual { margin: 0 0 1rem; padding-left: 1.3rem; display: flex; flex-direction: column; gap: 0.6rem; }
.koti-manual-step { font-size: 0.95rem; line-height: 1.55; color: var(--text-dim); }

/* The waiting state. Its whole job is to say the ball is in the other window. */
.koti-waiting {
  display: flex; align-items: flex-start; gap: 0.8rem;
  margin-top: 1.25rem;
  padding: 0.9rem 1rem;
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-dim);
}
.koti-waiting-dot {
  flex: none;
  width: 0.6rem; height: 0.6rem;
  margin-top: 0.4rem;
  border-radius: var(--radius-full);
  background: var(--accent);
  animation: koti-pulse 1.4s ease-in-out infinite;
}
@keyframes koti-pulse { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .koti-waiting-dot { animation: none; opacity: 1; } }
.koti-waiting-title { margin: 0 0 0.25rem; font-weight: 600; }
.koti-waiting-body { margin: 0; font-size: 0.92rem; color: var(--text-dim); line-height: 1.5; }

.koti-step .agc-step { margin-top: 1.25rem; }
.koti-step .agc-explain { margin: 0.5rem 0 0.8rem; line-height: 1.5; }
/* The badge + countdown row is one line at tab width and two on a phone. Without this it broke
   between "Expires in:" and the clock, which reads as a rendering fault rather than a wrap.
   Scoped to the step variant so the profile tab keeps the row it has always had. */
.koti-step .agc-step .agc-card > .flex-row:first-child { flex-wrap: wrap; row-gap: 0.35rem; }
.koti-step .agc-step .agc-card > .flex-row:first-child .text-caption { white-space: nowrap; }

/* ── The connected agent ── */
.koti-agent-card {
  border: 1px solid var(--success);
  border-radius: var(--radius);
  background: var(--card);
  padding: 1.25rem 1.35rem;
  margin-bottom: 1rem;
}
.koti-agent-head { display: flex; align-items: center; gap: 0.7rem; }
/* The dot carries the state. It was green in CSS regardless of what the agent was actually doing. */
.koti-agent-dot {
  flex: none; width: 0.6rem; height: 0.6rem;
  border-radius: var(--radius-full); background: var(--success);
}
.koti-agent-dot--problem { background: var(--danger); }
.koti-agent-dot--idle { background: var(--text-muted); }
.koti-agent-dot--new,
.koti-agent-dot--onboarding { background: var(--warning); }
.koti-agent-name { font-size: 1.15rem; font-weight: 700; }
.koti-agent-sub { font-size: 0.9rem; color: var(--text-dim); }
.koti-agent-toggle { margin-top: 0.7rem; font-size: 0.88rem; }
.koti-agent-details { margin: 0.8rem 0 0; display: grid; grid-template-columns: auto 1fr; gap: 0.35rem 1rem; }
.koti-agent-details dt { font-size: 0.85rem; color: var(--muted); }
.koti-agent-details dd { margin: 0; font-size: 0.9rem; }
.koti-agent-gaii { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; word-break: break-all; }
.koti-agent-manage { display: inline-block; margin-top: 0.9rem; }

/* One line of feedback, only for things that went wrong. */
.koti-toast {
  position: fixed; left: 50%; bottom: 1.25rem; transform: translateX(-50%);
  max-width: min(90vw, 30rem);
  padding: 0.7rem 1rem;
  border: 1px solid var(--danger);
  border-radius: var(--radius-sm);
  background: var(--card);
  color: var(--text);
  font-size: 0.92rem;
  z-index: 50;
}

@media (max-width: 560px) {
  .koti { padding: 1.25rem 1rem 3rem; }
  .koti-h1 { font-size: 1.55rem; }
  .koti-step { padding: 1rem 1rem; }
  .koti-prompt-body { max-height: 10rem; font-size: 0.78rem; }
  /* One full-width button per row: a half-width primary action on a phone reads as optional. */
  .koti-actions > * { width: 100%; }
  .koti-prompt-head > * { width: 100%; }
}

/* ── Branch B: the screen that must not read as an insult ── */
/* Warm border, not a danger one. The person did nothing wrong; their tool has a limit. */
.koti-b { border-color: var(--warn); }
.koti-b .koti-step-num { border-color: var(--warn); color: var(--warn); }

.koti-b-way, .koti-b-again {
  margin-top: 1.4rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--border);
}
.koti-b-way-title { font-size: 1.02rem; font-weight: 700; margin: 0 0 0.4rem; }
.koti-b-way-body { color: var(--text-dim); font-size: 0.96rem; line-height: 1.55; margin: 0 0 1rem; }

.koti-b-apps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.7rem; }
.koti-b-app {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-dim);
  padding: 0.75rem 0.9rem;
}
.koti-b-app-head { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.koti-b-app-name { font-weight: 700; font-size: 0.98rem; }
/* The plan line is the single most common reason a setup fails, so it is not a footnote. */
.koti-b-app-plans { margin: 0.35rem 0 0; font-size: 0.88rem; color: var(--text-dim); line-height: 1.5; }
.koti-b-app-docs { display: inline-block; margin-top: 0.4rem; font-size: 0.85rem; }

/* ── The feed: what has happened. Quiet by design — it reports, it does not compete. ── */
.koti-feed { margin-top: 2.5rem; }
.koti-feed-title {
  font-size: 0.82rem; text-transform: uppercase; letter-spacing: 1.4px;
  color: var(--muted); font-weight: 700; margin: 0 0 0.9rem;
}
/* The quiet nudge: when nothing has happened for days, the feed opens with the next move
   instead of a list that ends in the past. A door, not an alarm. */
.koti-feed-quiet {
  display: block; margin: 0 0 0.9rem; padding: 0.7rem 0.9rem;
  border: 1px dashed var(--border); border-radius: 10px;
  font-size: 0.92rem; color: var(--text); text-decoration: none;
  background: var(--surface);
}
.koti-feed-quiet:hover { border-color: var(--accent); }
.koti-feed-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.1rem; }
.koti-feed-item { display: flex; gap: 0.75rem; align-items: flex-start; padding: 0.5rem 0; }
.koti-feed-dot {
  flex: none; width: 0.5rem; height: 0.5rem; margin-top: 0.45rem;
  border-radius: var(--radius-full); background: var(--border);
}
/* The one row that is happening NOW gets the accent — it is the one to act on. */
.koti-feed-item-live .koti-feed-dot { background: var(--accent); }
.koti-feed-body { display: flex; align-items: baseline; gap: 0.6rem; flex-wrap: wrap; }
.koti-feed-line { font-size: 0.95rem; color: var(--text); text-decoration: none; }
a.koti-feed-line:hover { text-decoration: underline; }
.koti-feed-when { font-size: 0.8rem; color: var(--muted); }
/* The door to the whole record. A link, not a button: it goes somewhere, it does nothing. */
.koti-feed-more {
  display: inline-block; margin-top: 0.7rem;
  font-size: 0.88rem; color: var(--accent); text-decoration: none;
}
.koti-feed-more:hover { text-decoration: underline; }

/* ── The whole record: the full window, day by day, and the archive under it ── */
/* Narrower than the home. This page is read top to bottom, and a line of running text across a
   wide screen is one a reader loses their place in. */
.koti-hist { max-width: 46rem; }
.koti-hist-back {
  display: inline-block; margin-bottom: 1.2rem;
  font-size: 0.88rem; color: var(--muted); text-decoration: none;
}
.koti-hist-back:hover { color: var(--accent); }
.koti-hist-list { display: flex; flex-direction: column; gap: 1.4rem; }
.koti-hist-day { display: flex; flex-direction: column; gap: 0.2rem; }
/* The day heading is the structure of this page. It is quiet, but it is the thing being scanned,
   so it sits apart from its rows rather than on top of them. */
.koti-hist-daytitle {
  font-size: 0.78rem; text-transform: uppercase; letter-spacing: 1.2px;
  color: var(--muted); font-weight: 700; margin: 0 0 0.3rem;
  padding-bottom: 0.35rem; border-bottom: 1px solid var(--border);
}
.koti-hist-empty { font-size: 0.95rem; color: var(--text-dim); line-height: 1.6; }
.koti-hist-archive { margin-top: 2.6rem; padding-top: 1.6rem; border-top: 1px solid var(--border); }
.koti-hist-archtitle {
  font-size: 0.82rem; text-transform: uppercase; letter-spacing: 1.4px;
  color: var(--muted); font-weight: 700; margin: 0 0 0.4rem;
}
.koti-hist-archnote { margin: 0 0 1rem; font-size: 0.9rem; color: var(--text-dim); line-height: 1.6; }
.koti-hist-more { margin-top: 1.2rem; }
.koti-hist-error { margin-top: 1rem; font-size: 0.9rem; color: var(--danger); }

/* ── The door to the chat, and the mat address line (status-view home) ── */
.koti-chatdoor {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  margin: 1.4rem 0;
  padding: 1.1rem 1.2rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  flex-wrap: wrap;
}
.koti-chatdoor-lede { margin: 0; font-size: 0.95rem; line-height: 1.5; color: var(--text); }
.koti-chatdoor-cta { flex: none; }
.koti-matline { margin: 0.5rem 0 0; font-size: 0.88rem; color: var(--text-dim); }
.koti-matline a { color: var(--accent); text-decoration: none; }
.koti-matline a:hover { text-decoration: underline; }

/* ── The front door on the landing page ── */
.koti-door { max-width: 720px; margin: 0 auto 2.5rem; padding: 2rem 1.25rem 0; }
.koti-door-title {
  font-size: 2.1rem; font-weight: 800; letter-spacing: -0.5px;
  line-height: 1.15; margin: 0 0 1.5rem; color: var(--text);
}
.koti-door-agent {
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  background: var(--card);
  padding: 1.15rem 1.25rem;
  margin-bottom: 1.25rem;
}
.koti-door-agent-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.koti-door-agent-title { margin: 0 0 0.3rem; font-size: 1.1rem; font-weight: 700; }
.koti-door-agent-sub { margin: 0; font-size: 0.95rem; color: var(--text-dim); line-height: 1.5; max-width: 34rem; }
.koti-door-after { margin-top: 1rem; padding-top: 0.9rem; border-top: 1px solid var(--border); }
.koti-door-after p { margin: 0 0 0.5rem; font-size: 0.9rem; color: var(--text-dim); line-height: 1.5; }
.koti-door-after p:last-child { margin-bottom: 0; }

.koti-door-entrances { display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap; }
.koti-door-register {
  display: flex; flex-direction: column; gap: 0.15rem;
  padding: 0.8rem 1.1rem;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text); text-decoration: none;
}
.koti-door-register:hover { border-color: var(--accent); }
.koti-door-register-title { font-weight: 700; font-size: 1rem; }
.koti-door-register-sub { font-size: 0.85rem; color: var(--text-dim); }
/* Coming back is stepping into somewhere of your own, so the door is a keyhole. */
.koti-door-signin {
  display: inline-flex; align-items: center; gap: 0.5rem;
  color: var(--text-dim); text-decoration: none; font-size: 0.98rem;
}
.koti-door-signin:hover { color: var(--accent); }
.koti-keyhole { flex: none; }

/* ── The header: a nameplate, and one way into the settings. ── */
.koti-header {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding-bottom: 0.9rem; margin-bottom: 1.4rem;
  border-bottom: 1px solid var(--border);
}
.koti-name {
  font-weight: 650; font-size: 1.02rem; color: var(--text);
  /* A long display name shortens rather than pushing the settings button off the row. */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.koti-settings-btn {
  flex: none;
  display: inline-flex; align-items: center; gap: 0.4rem;
  font-size: 0.88rem;
}
.koti-cog { flex: none; opacity: 0.8; }

/* ── The settings dialog ──
   The shared .modal scrolls as ONE box (max-height 85vh + overflow-y:auto), which for a tabbed
   dialog scrolls the tab row out of sight — you lose the way back to the other tabs. Here the box
   is a column: title and tabs hold still, the panel underneath is what moves. */
.koti-settings-modal {
  width: 44rem;
  display: flex; flex-direction: column;
  overflow: hidden;                 /* the panel owns the scrolling, not the box */
}
/* The shared .modal-body sits between the box and our panel. Without letting it shrink, the panel
   inherits no height limit, grows to its content, and everything past the dialog edge is clipped by
   the overflow:hidden above — measured at 1280x460: 1373px of Wallet inside a 439px dialog, with
   nothing scrolling. Scoped to this dialog so no other modal changes. */
.koti-settings-modal .modal-body { flex: 1 1 auto; min-height: 0; display: flex; }
.koti-settings { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; width: 100%; }
.koti-settings-tabs {
  flex: none;
  margin-bottom: 1rem;
  /* Four tabs must fit a 390px phone: let them wrap rather than overflow the dialog sideways. */
  flex-wrap: wrap; max-width: 100%;
}
.koti-settings-panel {
  min-height: 0; overflow-y: auto;
  /* Room for a focus ring on the first control instead of clipping it at the edge. */
  padding: 0.15rem;
}
.koti-settings-switch {
  margin-top: 2rem; padding-top: 1.1rem;
  border-top: 1px solid var(--border);
  display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap;
  font-size: 0.88rem; color: var(--muted);
}

@media (max-width: 560px) {
  /* The dialog goes edge to edge rather than keeping a 44rem box on a phone. */
  .koti-settings-modal { width: 100%; }
  .koti-settings-tabs { width: 100%; }
  .koti-settings-tabs .seg-btn { flex: 1 1 auto; }
  .koti-door { padding: 1.25rem 1rem 0; }
  .koti-door-title { font-size: 1.65rem; }
  .koti-door-agent-head > * { width: 100%; }
  .koti-door-entrances > * { width: 100%; box-sizing: border-box; }
}

/* ── The intent pool: one list of what you mean to do here ────────────────── */
/* Human-written intents and system suggestions share one list; the second line says which is
   which. Empty renders nothing at all — see components/IntentPool.js. */
/* Open items. One list of what you are going to do here; the prompt that takes the whole list
   into a chat sits at the TOP, not on every row (P16). Rows carry the state control and nothing
   else, because on and off are the only two things an item can be (P19). */
.open-items { margin: 1.5rem 0 0; }
.open-items-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.75rem; flex-wrap: wrap; margin: 0 0 0.6rem;
}
.open-items-title {
  font-size: 0.78rem; text-transform: uppercase; letter-spacing: 1.2px;
  color: var(--muted); font-weight: 700; margin: 0;
}
.open-items-count {
  display: inline-block; margin-left: 0.35rem; padding: 0 0.4rem;
  border-radius: 999px; background: var(--bg); color: var(--text);
  font-size: 0.72rem; letter-spacing: 0;
}
.open-items-list { list-style: none; margin: 0; padding: 0; }
.open-items-row {
  display: flex; align-items: flex-start; gap: 0.7rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--border);
}
.open-items-row:last-child { border-bottom: 0; }
.open-items-main { flex: 1 1 auto; min-width: 0; }
.open-items-item { font-size: 0.95rem; line-height: 1.35; overflow-wrap: anywhere; }
.open-items-meta { font-size: 0.78rem; color: var(--muted); margin-top: 0.15rem; }
.open-items-control { flex: none; display: flex; align-items: center; gap: 0.35rem; }
.open-items-hand { font-size: 0.8rem; max-width: 10rem; }

/* The light. Three states, because the thing it reports has three (P5): not on the list, waiting,
   being worked on. It is a light and not a checkbox precisely so the third one can exist — an agent
   takes an item and the person sees it happen where the thing is. */
.open-toggle {
  display: inline-flex; align-items: center; gap: 0.4rem;
  background: none; border: 0; padding: 0.2rem; cursor: pointer; line-height: 1;
}
.open-toggle-light {
  width: 10px; height: 10px; border-radius: 50%;
  border: 1px solid var(--border); background: transparent;
  transition: background-color 120ms ease, border-color 120ms ease;
}
.open-toggle:hover .open-toggle-light { border-color: var(--muted); }
.open-toggle--open .open-toggle-light { background: var(--warning); border-color: var(--warning); }
.open-toggle--working .open-toggle-light {
  background: var(--success); border-color: var(--success);
  animation: open-toggle-pulse 1.8s ease-in-out infinite;
}
/* Somebody is working on it RIGHT NOW: the one state that is about this moment rather than a
   standing fact, so it is the one that moves. */
@keyframes open-toggle-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}
@media (prefers-reduced-motion: reduce) {
  .open-toggle--working .open-toggle-light { animation: none; }
}
.open-toggle:disabled { opacity: 0.5; cursor: default; }
.open-toggle-text { font-size: 0.8rem; color: var(--muted); }
.open-toggle--open .open-toggle-text, .open-toggle--working .open-toggle-text { color: var(--text); }

/* The header button. Hidden at zero, so it never shows a badge that has to be explained. */
.open-items-btn {
  display: inline-flex; align-items: center; gap: 0.25rem;
  background: none; border: 0; cursor: pointer; padding: 0.25rem 0.4rem;
  color: var(--muted); font-size: 0.85rem;
}
.open-items-btn:hover { color: var(--text); }
.open-items-btn-count { font-weight: 700; color: var(--text); }


@media (max-width: 640px) {
  /* The row wraps rather than squeezing the title into a column two words wide, and the title
     stops short of the corner so it never runs under the dots. What used to be here gave the
     control width:100% and dropped it onto its own line: measured at 390 the dots sat 64px down
     and 296px from the right, which is not a corner. The one rule this whole design rests on is
     that the control is in the same place every time, so it does not get a mobile exception. */
  .open-items-row { flex-wrap: wrap; }
  .open-items-main { padding-right: 2rem; }
}


/* The fleet line on the agent card is a link: it names a number you can do something about. */
.koti-agent-others { display: inline-block; text-decoration: underline; text-underline-offset: 2px; }
.koti-agent-others:hover { color: var(--text); }

/* A list row owns its corner too, same as a card — at every width. */
.open-items-row { position: relative; }
.open-items-row .card-menu { top: 0.35rem; right: 0; }

/* The one-time line that teaches the corner. It is gone for good once the menu has been opened. */
.koti-teach { margin: 0.75rem 0 0; font-size: 0.82rem; color: var(--muted); line-height: 1.45; }

/* Every card that carries the dots needs to be their containing block, or they escape upward to
   whatever ancestor is positioned. Measured once at 263px above the card it belonged to. */
.koti-step { position: relative; }

/* Who put it here is a second fact, on its own line, so it survives whatever else the row says. */
.open-items-byai { display: block; margin-top: 0.1rem; color: var(--accent); }
