/* kv2-launchpad — App-specific styles. Tokens from kapable-theme.css.
   v4 "engineering paper" grammar (IMP-2073, BRAND.md layout grammar):
   structure is drawn in rules, not wrapped in boxes; the accent is the
   drawing ink; corners are machined (3px). Ratified direction:
   https://kapable.kapable.ai/artifacts/launchpad-redesign (v4). */

html, body { height: 100%; }
/* Reserve the scrollbar gutter permanently. Without it the centred shell
   shifts sideways the moment a list crosses the fold, so switching views
   nudges the whole page — the second half of the width-jank complaint (the
   first half was the eaten `main#app` rule below). A no-op where the platform
   draws overlay scrollbars. */
html { scrollbar-gutter: stable; }
* { margin: 0; padding: 0; }

body {
  background: var(--kp-bg); color: var(--kp-text);
  display: flex; flex-direction: column;
  min-height: 100vh; /* fallback for browsers without dvh */
  min-height: 100dvh;
}

/* ── Wallpaper — engineering paper (IMP-2590 lane treatment) ──────────────
   Fine dot grid + one ink-hairline drafting construction (circles + register
   cross marks), behind all content, both color schemes, hidden in print.
   Ink only, never accent — drafting geometry is never a brand-color field
   (BRAND.md). Tokens derived from --kp-text via color-mix at the exact
   alphas of the ratified OS-shell concept (job cad424f1/ref-stripped.html);
   attribute-selector form matches this theme's [data-theme] pattern rather
   than the concept's light-dark() function. */
[data-theme="light"] {
  --wp-dot:  color-mix(in oklch, var(--kp-text) 7%, transparent);
  --wp-line: color-mix(in oklch, var(--kp-text) 5.5%, transparent);
  --wp-mark: color-mix(in oklch, var(--kp-text) 11%, transparent);
}
[data-theme="dark"] {
  --wp-dot:  color-mix(in oklch, var(--kp-text) 5.5%, transparent);
  --wp-line: color-mix(in oklch, var(--kp-text) 5%, transparent);
  --wp-mark: color-mix(in oklch, var(--kp-text) 10%, transparent);
}
.wp-dots {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background-image: radial-gradient(var(--wp-dot) 1px, transparent 1.3px);
  background-size: 28px 28px;
}
.wallpaper {
  position: fixed; inset: 0; width: 100vw; height: 100vh; z-index: 0;
  pointer-events: none;
}
/* Everything that must read above the wallpaper layers (z 0). */
main#app, .kp-footer { position: relative; z-index: 1; }
/* #kapable-header's stacking (position:sticky, z-index:100, above main and
   above popovers at z 200 inside its own context) ships from the vendored
   kapable-header.css (header-v0.6.0+) — a local override here would win via
   source order and re-bury the tool-switcher panel again (IMP-2590 lane
   lesson); do not re-add one. */
@media print {
  .wp-dots, .wallpaper { display: none !important; }
}

/* ── Footer dock ───────────────────────────────────────────────────────────
   The launchpad's OS-shell footer dock (IMP-2590 v2/v3) was promoted to
   kapable-ui-assets as kapable-dock.css/js + kapable-accent-audition.js
   (dock-v0.1.0, IMP-2598) — vendored via vendor-assets.pins, not defined
   here. Do not redefine the .lp-dock… / .lp-accent-audit… / body.has-lp-dock
   rules locally;
   ⚠ AND never write a glob in a CSS comment as a prefix + asterisk + slash —
   that three-character sequence CLOSES the comment early, and the parser then
   eats the following rule as error-recovery. This exact line once read
   ".lp-dock" + star + "/" and silently deleted the `main#app` width rule
   below, which is what gave every launchpad page a content-dependent,
   janking shell width. Spell globs with an ellipsis, as above.
   That risks double-definition drift against the shared asset (which already
   ships its own body.has-lp-dock padding/FAB/toast reservations). Mount
   call: window.KapableDock.mount(...) in app.js (index.html) / an inline
   script (apps.html, drops.html). */

/* `width: 100%` is load-bearing, not decoration. body is a column flex
   container, so width here is the CROSS size; with `margin: 0 auto` the auto
   margins suppress the stretch, and an auto cross size then resolves to
   fit-content — i.e. the shell would be as wide as its widest row and would
   change width every time the list changed. Keep width and flex in the SAME
   rule as the margin so a future edit can't separate them again. */
main#app {
  flex: 1;
  width: 100%;
  padding: 40px 24px;
  max-width: 1180px;
  margin: 0 auto;
}
.loading { color: var(--kp-text-dim); text-align: center; padding: 60px 0; }
.muted { color: var(--kp-text-muted); font-size: 13px; }

/* Hydrated content arrives with one quiet rise from the skeleton — a single
   220ms settle, not an orchestrated sequence. Dies under reduced-motion. */
.lp-enter { animation: kp-enter 0.22s cubic-bezier(0.22, 1, 0.36, 1) both; }
@keyframes kp-enter {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}

/* Footer shortcut hint — only meaningful with a hardware keyboard, so it
   stays hidden on touch; revealed by app.js once the switcher has tiles. */
.footer-hint { display: none; }
@media (hover: hover) and (pointer: fine) {
  .kp-footer.has-cmdk .footer-hint { display: inline-flex; align-items: center; gap: 5px; }
}

/* Boot skeleton — the shell renders instantly, sections hydrate as data lands.
   The pulse dies under the global prefers-reduced-motion guard (static blocks). */
.skeleton-block {
  background: var(--kp-surface-hi);
  border-radius: 3px;
  animation: kp-skeleton 1.1s ease-in-out infinite alternate;
}
.skeleton-glyph { width: 24px; height: 24px; border-radius: 2px; flex-shrink: 0; }
.skeleton-line { height: 12px; }
@keyframes kp-skeleton {
  from { opacity: 0.55; }
  to   { opacity: 1; }
}

/* ── Masthead — the arrival moment ─────────────────────────────────────────
   Human register over machine register: the display-serif greeting sits on a
   mono readout of real facts, closed by the drafting double-rule. The person
   owns the moment; the org lives in the readout (no org-mark chip). */
.masthead { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; }
.masthead-main { min-width: 0; }
.masthead h1 {
  font-family: var(--kp-font-display);
  font-optical-sizing: auto;
  font-size: 35px; font-weight: 550;
  letter-spacing: -0.02em; line-height: 1.14;
  color: var(--kp-text);
}
.masthead-readout {
  margin-top: 8px;
  font-family: var(--kp-font-mono); font-size: 11.5px; letter-spacing: 0.01em;
  color: var(--kp-text-dim); text-transform: lowercase;
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
}
/* The page's one graphic: a quiet instrument trace of real org activity.
   Data, not decoration — hidden when there aren't ≥2 days to draw. */
.masthead-spark { flex-shrink: 0; margin: 0 0 2px; display: flex; flex-direction: column; align-items: flex-end; gap: 3px; }
.masthead-spark svg { display: block; }
.masthead-spark figcaption {
  font-family: var(--kp-font-mono); font-size: 9.5px; letter-spacing: 0.02em;
  text-transform: lowercase; color: var(--kp-text-dim);
  font-variant-numeric: tabular-nums;
}
.masthead-readout .sep { color: var(--kp-border-strong); }
.masthead-rule {
  margin: 18px 0 32px;
  border-top: 2px solid var(--kp-accent);
  position: relative;
}
.masthead-rule::after {
  content: ""; position: absolute; left: 0; right: 0; top: 2px;
  border-top: 1px solid var(--kp-accent-bg);
}

/* ── Platform atlas ─────────────────────────────────────────────────────────
   The directory is the graphic: one editorial arrival panel beside a precise
   product index. It keeps the launchpad task-first while giving the front door
   a composition that belongs to Kapable rather than a dashboard template. */
.atlas-layout {
  display: grid;
  grid-template-columns: minmax(250px, 0.7fr) minmax(0, 1.7fr);
  gap: 64px;
  align-items: start;
}
.atlas-intro {
  position: sticky;
  top: 24px;
  min-width: 0;
  padding-top: 18px;
  border-top: 2px solid var(--kp-accent);
}
.atlas-kicker {
  font-family: var(--kp-font-mono);
  font-size: 10px;
  letter-spacing: 0.02em;
  text-transform: lowercase;
  color: var(--kp-accent);
}
.atlas-intro h1 {
  margin: 20px 0 0;
  max-width: 8ch;
  font-family: var(--kp-font-display);
  font-optical-sizing: auto;
  font-size: 52px;
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1.02;
  color: var(--kp-text);
}
.atlas-summary {
  max-width: 34ch;
  margin: 22px 0 0;
  color: var(--kp-text-dim);
  font-size: 13px;
  line-height: 1.6;
}
.atlas-intro .masthead-readout { margin-top: 11px; }
.atlas-intro .masthead-spark {
  width: 100%;
  max-width: 280px;
  align-items: flex-start;
  gap: 7px;
  margin: 30px 0 0;
  padding: 12px 0 10px;
  border-top: 1px solid var(--kp-border);
  border-bottom: 1px solid var(--kp-border);
}
.atlas-intro .masthead-spark svg { width: 100%; height: auto; }
.atlas-intro .masthead-spark figcaption { text-align: left; }
.atlas-command {
  width: 100%;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 10px;
  margin-top: 26px;
  padding: 11px 0;
  border: 0;
  border-top: 1px solid var(--kp-border);
  border-bottom: 1px solid var(--kp-border);
  border-radius: 0;
  background: transparent;
  color: var(--kp-text-dim);
  text-align: left;
  cursor: pointer;
  transition: color 0.15s, background 0.15s;
}
.atlas-command:hover,
.atlas-command:focus-visible {
  color: var(--kp-text);
  background: var(--kp-accent-bg);
}
.atlas-command:focus-visible { outline: 2px solid var(--kp-accent); outline-offset: 2px; }
.atlas-command:disabled { cursor: default; opacity: 0.55; }
.atlas-command-prompt {
  font-family: var(--kp-font-mono);
  font-weight: 650;
  color: var(--kp-accent);
}
.atlas-command-label { font-size: 12.5px; }
.atlas-command .kp-kbd { font-size: 9.5px; }

.atlas-main { position: relative; min-width: 0; }
.atlas-main::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: -32px;
  width: 1px;
  background: var(--kp-border-subtle);
}
.atlas-main > .onboarding-card { margin: 0 0 24px; }
/* IMP-2590 v2: tightened from 38px — with the in-page platform directory
   gone (nav moved to the footer dock), fewer sections remain and the page
   should read as one instrument rather than a longer scroll with the old
   gaps. */
.atlas-section + .atlas-section,
.atlas-main > .activity-section { margin-top: 28px; }
.atlas-section .section-heading,
.atlas-main > .activity-section h2 { margin-top: 0; }
.atlas-section .section-heading .sh-n {
  font-variant-numeric: tabular-nums;
  color: var(--kp-text-dim);
}
.atlas-directory {
  border-top: 1px solid var(--kp-border);
}
.atlas-directory-head,
.atlas-directory-row {
  display: grid;
  grid-template-columns: 42px minmax(130px, 0.82fr) minmax(180px, 1.25fr) 96px;
  gap: 12px;
  align-items: center;
}
.atlas-directory-head {
  min-height: 34px;
  color: var(--kp-text-dim);
  font-family: var(--kp-font-mono);
  font-size: 9px;
  text-transform: lowercase;
}
.atlas-directory-row {
  min-height: 54px;
  border-top: 1px solid var(--kp-border-subtle);
  color: var(--kp-text);
  text-decoration: none;
  transition: color 0.15s, background 0.15s;
}
.atlas-directory-row:hover,
.atlas-directory-row:focus-visible {
  color: var(--atlas-hue, var(--kp-accent));
  background: var(--kp-accent-bg);
  box-shadow: inset 2px 0 0 var(--atlas-hue, var(--kp-accent));
  text-decoration: none;
}
.atlas-directory-row:focus-visible { outline: 2px solid var(--kp-accent); outline-offset: -2px; }
.atlas-directory-row:focus:not(:focus-visible) { outline: none; }
.atlas-directory-row[aria-disabled="true"] { opacity: 0.55; pointer-events: none; }
.atlas-directory-row[data-group="build"],
.atlas-chapter[data-group="build"] { --atlas-hue: var(--kp-accent); }
.atlas-directory-row[data-group="collaborate"],
.atlas-chapter[data-group="collaborate"] { --atlas-hue: var(--kp-icon-teal); }
.atlas-directory-row[data-group="operate"],
.atlas-chapter[data-group="operate"] { --atlas-hue: var(--kp-icon-indigo); }
.atlas-directory-row[data-group="more"],
.atlas-chapter[data-group="more"] { --atlas-hue: var(--kp-icon-violet); }
.atlas-ref {
  position: relative;
  justify-self: start;
  font-family: var(--kp-font-mono);
  font-size: 9.5px;
  font-variant-numeric: tabular-nums;
  color: var(--atlas-hue, var(--kp-accent));
}
.atlas-ref::before,
.atlas-ref::after {
  position: absolute;
  opacity: 0;
  transition: opacity 0.15s;
}
.atlas-ref::before { content: "["; left: -7px; }
.atlas-ref::after { content: "]"; right: -7px; }
.atlas-directory-row:hover .atlas-ref::before,
.atlas-directory-row:hover .atlas-ref::after,
.atlas-directory-row:focus-visible .atlas-ref::before,
.atlas-directory-row:focus-visible .atlas-ref::after { opacity: 1; }
.atlas-tool {
  font-family: var(--kp-font-display);
  font-optical-sizing: auto;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.1;
}
.atlas-purpose {
  min-width: 0;
  overflow: hidden;
  color: var(--kp-text-dim);
  font-size: 12px;
  line-height: 1.35;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: transform 0.15s;
}
.atlas-directory-row:hover .atlas-purpose,
.atlas-directory-row:focus-visible .atlas-purpose { transform: translateX(3px); }
/* Host fallback for customer rows without an owner-set description. */
.atlas-purpose-host {
  font-family: var(--kp-font-mono);
  font-size: 11px;
  letter-spacing: 0.01em;
}
.atlas-group {
  position: relative;
  min-height: 14px;
  color: var(--kp-text-dim);
  font-family: var(--kp-font-mono);
  font-size: 9px;
  text-align: right;
  text-transform: lowercase;
}
.atlas-group-rest,
.atlas-group-open {
  position: absolute;
  inset: 0 0 auto auto;
  white-space: nowrap;
  transition: opacity 0.15s;
}
.atlas-group-open { opacity: 0; color: var(--atlas-hue, var(--kp-accent)); }
.atlas-directory-row:hover .atlas-group-rest,
.atlas-directory-row:focus-visible .atlas-group-rest { opacity: 0; }
.atlas-directory-row:hover .atlas-group-open,
.atlas-directory-row:focus-visible .atlas-group-open { opacity: 1; }
.atlas-chapter {
  min-height: 38px;
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  border-top: 1px solid var(--kp-border);
  color: var(--kp-text-dim);
  font-family: var(--kp-font-mono);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: lowercase;
}
.atlas-chapter-ref {
  color: var(--atlas-hue, var(--kp-accent));
  font-variant-numeric: tabular-nums;
}
.atlas-chapter-name { color: var(--kp-text-dim); }
.atlas-chapter::after {
  content: "";
  height: 1px;
  flex: 1;
  background: var(--kp-border-subtle);
}
.atlas-chapter-count {
  order: 3;
  font-variant-numeric: tabular-nums;
}
.atlas-directory-head + .atlas-chapter { border-top: 0; }
.atlas-customer-directory .atlas-ref { color: var(--kp-success); }
.atlas-customer-directory .atlas-group-rest { color: var(--kp-success); }

.atlas-empty-apps {
  border-bottom: 1px solid var(--kp-border);
}
.atlas-ghost-row { border-top: 0; }
.atlas-ghost-row .atlas-ref { color: var(--kp-text-muted); }
.atlas-ghost-row .atlas-tool { color: var(--kp-text-dim); }
.atlas-ghost-row:hover { color: var(--kp-text); background: transparent; }
.atlas-ghost-row:hover .atlas-ref::before,
.atlas-ghost-row:hover .atlas-ref::after { opacity: 0; }
.atlas-ghost-row:hover .atlas-purpose { transform: none; }
.atlas-empty-action {
  justify-self: end;
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: 0 13px;
  border: 1px solid var(--kp-accent);
  border-radius: 3px;
  color: var(--kp-accent);
  font-size: 12.5px;
  font-weight: 600;
  white-space: nowrap;
  text-decoration: none;
  transition: color 0.15s, background 0.15s;
}
.atlas-empty-action:hover,
.atlas-empty-action:focus-visible {
  background: var(--kp-accent);
  color: var(--kp-bg);
  text-decoration: none;
}

/* ── Apps grid — the artifact's 2-column ruled-row directory (IMP-2590 lane
   treatment, THE A/B VARIABLE vs. the atlas ledger above). Ruled rows, not
   cards: 1px hairline separators, no border-radius beyond the machined 2-3px
   corners on the glyph. Each app gets a per-app hue via hueForName(), same
   as the customer-app rows, rather than the ledger's per-group hue. */
.apps-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 32px;
  border-top: 1px solid var(--kp-border);
}
.apps-grid-row {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 54px;
  padding: 10px 2px;
  border-bottom: 1px solid var(--kp-border-subtle);
  color: var(--kp-text);
  text-decoration: none;
  transition: color 0.15s, background 0.15s;
}
.apps-grid-row:hover,
.apps-grid-row:focus-visible {
  color: var(--app-hue, var(--kp-accent));
  background: var(--kp-accent-bg);
  text-decoration: none;
}
.apps-grid-row:focus-visible { outline: 2px solid var(--kp-accent); outline-offset: -2px; }
.apps-grid-row:focus:not(:focus-visible) { outline: none; }
.apps-grid-row[aria-disabled="true"] { opacity: 0.55; pointer-events: none; }
.app-mark {
  width: 26px; height: 26px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--kp-font-mono); font-weight: 650; font-size: 12px;
  color: var(--app-hue, var(--kp-accent));
  background: var(--kp-surface);
  border: 1px solid var(--kp-border); border-radius: var(--kp-radius-sm);
  user-select: none;
}
.apps-grid-body { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 1px; }
.apps-grid-name {
  font-size: 13.5px; font-weight: 600; letter-spacing: -0.005em;
  color: var(--kp-text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.apps-grid-desc {
  font-family: var(--kp-font-mono); font-size: 11px; letter-spacing: 0.01em;
  color: var(--kp-text-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.apps-grid-dot {
  width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0;
  background: var(--kp-border-strong);
}
.apps-grid-dot.ok { background: var(--kp-success); }
@media (max-width: 760px) {
  .apps-grid { grid-template-columns: 1fr; }
}

/* ── Section labels — the machine speaks on a drafting rule ──
   --kp-text-dim (not muted): 11px mono must hold WCAG AA on the garnet-ink
   papers; v0.7.0's muted lands ~3.5:1 at this size (audit P1). */
.section-heading,
.activity-section h2 {
  margin: 0 0 12px;
  font-family: var(--kp-font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: lowercase;
  color: var(--kp-text-dim);
  display: flex; align-items: center; gap: 12px;
}
.section-heading::after,
.activity-section h2::after {
  content: ""; flex: 1; height: 1px; background: var(--kp-border);
}
.section-heading { margin-top: 34px; }
.sh-n { color: var(--kp-text-dim); }

/* ── The org's apps — a ruled index drawn on the paper, no card container ── */
.app-index {
  display: grid; grid-template-columns: 1fr 1fr; gap: 0 48px;
  margin-bottom: 10px;
}
.app-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 4px; min-width: 0;
  border-bottom: 1px solid var(--kp-border-subtle);
  text-decoration: none; color: var(--kp-text);
  transition: background 0.15s, color 0.15s;
}
.app-row:hover, .app-row:focus-visible {
  background: var(--kp-accent-bg);
  text-decoration: none;
}
.app-row:hover .app-row-name, .app-row:focus-visible .app-row-name { color: var(--kp-accent); }
.app-row:focus-visible { outline: 2px solid var(--kp-accent); outline-offset: -2px; }
.app-row:focus:not(:focus-visible) { outline: none; }
.app-glyph {
  width: 24px; height: 24px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--kp-font-mono); font-weight: 650; font-size: 12px;
  color: var(--app-hue, var(--kp-accent));
  background: var(--kp-surface);
  border: 1px solid var(--kp-border); border-radius: 2px;
  user-select: none;
}
.app-row-name { font-size: 13.5px; font-weight: 600; flex-shrink: 0; transition: color 0.15s; }
.app-row-desc {
  font-size: 12.5px; color: var(--kp-text-dim); min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ── Onboarding — one calm ruled line, the page's only surviving panel
   (an interruption earns a container); full checklist expands on demand. ── */
.onboarding-card {
  background: var(--kp-surface);
  border: 1px solid var(--kp-border);
  border-radius: 3px;
  padding: 12px 16px;
  margin-bottom: 6px;
}
.setup-rail { display: flex; align-items: center; gap: 14px; min-height: 32px; }
.setup-segs { display: flex; gap: 4px; flex-shrink: 0; }
.setup-segs i { width: 20px; height: 3px; background: var(--kp-surface-hi); }
.setup-segs i.done { background: var(--kp-accent); }
.setup-count { font-family: var(--kp-font-mono); font-size: 11px; color: var(--kp-text-dim); flex-shrink: 0; }
.setup-next {
  font-size: 13.5px; color: var(--kp-text); min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.setup-next b { font-weight: 600; }
.setup-go {
  margin-left: auto; flex-shrink: 0;
  background: var(--kp-accent); color: var(--kp-surface);
  border: none; border-radius: 3px; padding: 7px 14px;
  font-size: 12.5px; font-weight: 600; cursor: pointer;
  font-family: var(--kp-font); text-decoration: none;
  display: inline-flex; align-items: center;
  transition: filter 0.15s;
}
[data-theme="dark"] .setup-go { color: var(--kp-bg); }
.setup-go:hover { filter: brightness(1.08); text-decoration: none; }
.setup-all {
  flex-shrink: 0; background: none; border: none; cursor: pointer;
  font-size: 12.5px; color: var(--kp-text-dim); font-family: var(--kp-font);
  padding: 7px 6px; border-radius: 3px;
  transition: color 0.15s;
}
.setup-all:hover { color: var(--kp-accent); }
/* When the rail has no Continue button (up-next step has no URL), the ghost
   button anchors the right edge instead. */
.setup-rail .setup-all:first-of-type { margin-left: auto; }
.setup-rail .setup-go + .setup-all { margin-left: 0; }
.onboarding-dismiss {
  flex-shrink: 0;
  background: transparent; border: none; color: var(--kp-text-muted);
  font-size: 20px; line-height: 1; cursor: pointer;
  border-radius: 3px;
  width: 32px; height: 32px; margin: -4px -6px -4px -2px;
  display: inline-flex; align-items: center; justify-content: center;
  transition: color 0.15s, background 0.15s;
}
.onboarding-dismiss:hover { color: var(--kp-text); background: var(--kp-surface-hi); }

.onboarding-steps {
  list-style: none; padding: 10px 0 2px; margin: 10px 0 0;
  border-top: 1px solid var(--kp-border-subtle);
  display: none; flex-direction: column; gap: 6px;
}
.onboarding-card.expanded .onboarding-steps { display: flex; }
.onboarding-step {
  display: flex; align-items: center; gap: 10px;
  padding: 5px 0; font-size: 13.5px;
}
.onboarding-marker {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%;
  border: 1.5px solid var(--kp-border); color: transparent;
  font-size: 11px; font-weight: 700;
  flex-shrink: 0;
}
.onboarding-marker.done {
  background: var(--kp-success);
  border-color: var(--kp-success);
  color: #fff;
}
.onboarding-label { flex: 1; color: var(--kp-text); }
.onboarding-label.done { color: var(--kp-text-dim); opacity: 0.6; }
.onboarding-action {
  font-size: 13px; font-weight: 500; color: var(--kp-accent);
  text-decoration: none;
  padding: 6px 12px; margin: -6px -12px;
  border-radius: 3px;
  min-height: 44px; min-width: 44px;
  display: inline-flex; align-items: center;
}
.onboarding-action:hover { text-decoration: none; background: var(--kp-accent-bg); }
.onboarding-step.up-next .onboarding-marker {
  border-color: var(--kp-accent);
  box-shadow: 0 0 0 3px var(--kp-accent-bg);
}
.onboarding-step.up-next .onboarding-label { font-weight: 500; }

/* Onboarding completion payoff — quiet acknowledgement, one dismiss from gone.
   The check draws itself once (450ms): motion in service of the state change. */
.onboarding-complete { padding: 16px 18px; }
.onboarding-complete-row { display: flex; align-items: center; gap: 14px; }
.onboarding-complete-mark { width: 26px; height: 26px; font-size: 14px; }
.onboarding-complete-mark svg { width: 14px; height: 14px; }
.onboarding-complete-mark svg path {
  stroke-dasharray: 24; stroke-dashoffset: 24;
  animation: kp-check-draw 0.45s cubic-bezier(0.22, 1, 0.36, 1) 0.05s forwards;
}
@keyframes kp-check-draw { to { stroke-dashoffset: 0; } }
.onboarding-complete-text { flex: 1; min-width: 0; }
.onboarding-title { font-size: 15px; font-weight: 600; margin: 0; color: var(--kp-text); }
.onboarding-sub { font-size: 12px; margin: 4px 0 0; color: var(--kp-text-dim); }
.onboarding-complete .onboarding-title {
  font-family: var(--kp-font-display);
  font-optical-sizing: auto;
  font-size: 17px; font-weight: 600;
}

/* ── Activity — ruled receipt rows, no box ── */
.activity-section { margin-top: 34px; }
.activity-timeline { display: flex; flex-direction: column; }
.activity-item {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 4px;
  border-bottom: 1px solid var(--kp-border-subtle);
  text-decoration: none; color: var(--kp-text);
  transition: background 0.15s ease;
}
.activity-glyph {
  font-family: var(--kp-font-mono); font-size: 11.5px; font-weight: 600;
  color: var(--kp-accent); width: 14px; text-align: center; flex-shrink: 0;
  user-select: none;
}
a.activity-item:hover { background: var(--kp-accent-bg); text-decoration: none; }
a.activity-item:hover .activity-time { color: var(--kp-text-dim); }
/* Ambient rows (sign-ins): present but visually behind real events. */
.activity-item-ambient { opacity: 0.55; }
.activity-item-ambient .activity-glyph { color: var(--kp-text-muted); }
a.activity-item-ambient:hover, .activity-item-ambient:hover { opacity: 1; }
a.activity-item:focus-visible { background: var(--kp-accent-bg); outline: 2px solid var(--kp-accent); outline-offset: -2px; }
a.activity-item:focus:not(:focus-visible) { outline: none; }
.activity-content { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.activity-title { font-size: 13px; font-weight: 500; color: var(--kp-text); }
.activity-count {
  display: inline-block; margin-left: 6px; padding: 0 6px;
  font-size: 10px; font-weight: 600; line-height: 16px;
  font-family: var(--kp-font-mono, ui-monospace, monospace);
  color: var(--kp-text-dim); background: var(--kp-surface);
  border: 1px solid var(--kp-border); border-radius: 2px;
  vertical-align: 1px;
}
.activity-detail { font-size: 12px; color: var(--kp-text-dim); }
/* Timestamps speak in the machine register: mono, tabular, quiet —
   dim, not muted: 10.5px must hold AA (audit P1). */
.activity-time {
  font-family: var(--kp-font-mono); font-size: 10.5px;
  font-variant-numeric: tabular-nums;
  color: var(--kp-text-dim); white-space: nowrap; flex-shrink: 0;
}

/* Quick actions empty state — machined chips, not cards */
.quick-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.quick-action {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 12px;
  background: var(--kp-surface); border: 1px solid var(--kp-border);
  border-radius: 3px;
  text-decoration: none; color: var(--kp-text);
  transition: border-color 0.15s, color 0.15s;
}
.quick-action:hover, .quick-action:focus-visible {
  border-color: var(--kp-accent); color: var(--kp-accent);
  text-decoration: none;
}
.quick-action:focus:not(:focus-visible) { outline: none; }
.quick-action-icon {
  display: flex; align-items: center; justify-content: center;
  color: var(--kp-text-dim); flex-shrink: 0;
}
.quick-action:hover .quick-action-icon { color: var(--kp-accent); }
.quick-action-info { display: flex; flex-direction: column; min-width: 0; }
.quick-action-name { font-weight: 600; font-size: 12.5px; }
.quick-action-desc { font-size: 11px; color: var(--kp-text-dim); }

/* ── Org picker — the doorway: a genuine interruption, so it keeps its
   containers; corners machined to match the grammar. ── */
.org-picker { max-width: 560px; margin: clamp(40px, 14vh, 120px) auto 0; }
.org-picker h1 {
  font-family: var(--kp-font-display);
  font-optical-sizing: auto;
  font-size: 30px; font-weight: 600; letter-spacing: -0.02em; margin-bottom: 6px;
}
.org-picker > .muted { margin-bottom: 28px; display: block; }

.org-grid { display: flex; flex-direction: column; gap: 10px; }

.org-avatar {
  flex-shrink: 0; width: 38px; height: 38px; border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  background: var(--kp-accent-bg); color: var(--app-hue, var(--kp-accent));
  font-weight: 700; font-size: 16px; user-select: none;
}
@supports (background: color-mix(in oklab, red 10%, blue)) {
  .org-avatar {
    background: color-mix(in oklab, var(--app-hue, var(--kp-accent)) 11%, var(--kp-surface));
  }
}
.org-card-main { display: flex; align-items: center; gap: 14px; min-width: 0; }

.org-card {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
  padding: 16px 20px;
  background: var(--kp-surface);
  border: 1px solid var(--kp-border);
  border-radius: 3px;
  text-decoration: none; color: var(--kp-text);
  transition: border-color 0.15s, background 0.15s;
}
.org-card:hover { border-color: var(--kp-accent); background: var(--kp-surface-hi); text-decoration: none; }
.org-card:focus-visible { border-color: var(--kp-accent); background: var(--kp-surface-hi); outline: 2px solid var(--kp-accent); outline-offset: 2px; }
.org-card:focus:not(:focus-visible) { outline: none; }
.org-card-name { font-weight: 600; font-size: 16px; }
.org-card-meta { display: flex; gap: 12px; align-items: center; }
.org-slug { color: var(--kp-text-dim); font-size: 12px; font-family: var(--kp-font-mono); }
.org-plan {
  color: var(--kp-accent); font-size: 10.5px; font-weight: 600;
  text-transform: lowercase; letter-spacing: 0.03em;
  font-family: var(--kp-font-mono);
  background: var(--kp-accent-bg);
  padding: 2px 8px; border-radius: 2px;
}
.org-role { color: var(--kp-text-dim); font-size: 12px; }

/* ── Cmd+K quick switcher — restyled toward the OS-shell concept's
   spotlight (IMP-2590 v3): CSS-only pass over the existing palette markup,
   no logic changes. This is a deliberate, scoped exception to the app's
   general "machined 3-4px corners" grammar — the operator explicitly asked
   for the concept's softer spotlight look on this ONE overlay component. ── */
.kp-cmdk-overlay {
  position: fixed; inset: 0; z-index: 1500; /* below toasts (2000) */
  background: color-mix(in oklch, var(--kp-bg) 55%, transparent);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 16vh 16px 0;
}
.kp-cmdk {
  width: min(560px, 100%);
  background: var(--kp-surface); border: 1px solid var(--kp-border-strong);
  border-radius: 12px; box-shadow: var(--kp-shadow-lg);
  overflow: hidden;
  animation: kp-cmdk-in 0.15s cubic-bezier(0.2, 0.9, 0.3, 1.2);
}
@keyframes kp-cmdk-in {
  from { opacity: 0; transform: translateY(-8px) scale(0.985); }
  to   { opacity: 1; transform: none; }
}
.kp-cmdk-input {
  width: 100%; border: 0; background: transparent;
  color: var(--kp-text); font-size: 15px; font-family: var(--kp-font);
  padding: 15px 18px; border-bottom: 1px solid var(--kp-border);
}
/* Focus indicator is the accent underline (an outline ring inside the panel
   double-borders); the caret + underline keep focus visible. */
.kp-cmdk-input:focus-visible { outline: none; border-bottom-color: var(--kp-accent); }
.kp-cmdk-input::placeholder { color: var(--kp-text-muted); }
.kp-cmdk-list { max-height: 340px; overflow-y: auto; padding: 6px; }
.kp-cmdk-item {
  display: flex; align-items: baseline; gap: 10px;
  padding: 9px 11px; border-radius: 7px;
  cursor: pointer;
}
.kp-cmdk-item.selected { background: var(--kp-accent-bg); }
.kp-cmdk-name { font-weight: 600; font-size: 14px; color: var(--kp-text); flex-shrink: 0; }
.kp-cmdk-desc {
  font-size: 12px; color: var(--kp-text-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.kp-cmdk-empty { padding: 14px; text-align: center; }
.kp-cmdk-hint {
  display: flex; align-items: center; gap: 5px;
  padding: 9px 16px; border-top: 1px solid var(--kp-border-subtle);
  font-family: var(--kp-font-mono); font-size: 10.5px; color: var(--kp-text-dim);
}
.kp-cmdk-hint .kp-kbd { margin-left: 7px; }
.kp-cmdk-hint .kp-kbd:first-child { margin-left: 0; }

/* Terminal view styles live in terminal.html (its own document); the shared
   pieces it takes from here are the tokens, fonts, and .kp-* primitives. */
.terminal-connecting, .terminal-error, .terminal-msg {
  padding: 24px; color: var(--kp-text-dim); font-size: 14px;
}
.terminal-error { color: var(--kp-danger); }

/* ── /apps — the fleet ledger ─────────────────────────────────────────────
   Environment lanes drawn as ruled chapters; each app is a ledger entry with
   that lane's real runtime state. Same paper, same ink: rules not boxes. */
.fleet-search { margin-top: 26px; width: 100%; }
.fleet-intro-actions {
  margin-top: 18px;
  display: flex; align-items: center; gap: 16px;
}
.fleet-console-link {
  font-family: var(--kp-font-mono); font-size: 10.5px;
  text-transform: lowercase; letter-spacing: 0.02em;
  color: var(--kp-text-dim); text-decoration: none;
  transition: color 0.15s;
}
.fleet-console-link:hover, .fleet-console-link:focus-visible {
  color: var(--kp-accent); text-decoration: none;
}

.fleet-lane-head[data-env="production"] { --atlas-hue: var(--kp-accent); }
.fleet-lane-head[data-env="internal"] { --atlas-hue: var(--kp-icon-violet); }
.fleet-lane { margin-bottom: 26px; }
.fleet-env-badge {
  order: 2;
  font-family: var(--kp-font-mono); font-size: 9px;
  padding: 1px 7px; border-radius: 2px;
  border: 1px solid var(--kp-border);
  color: var(--kp-text-muted);
}
.fleet-env-badge.routed {
  border-color: transparent;
  background: var(--kp-success-bg);
  color: var(--kp-success);
}

.fleet-row {
  display: grid;
  grid-template-columns: 28px minmax(150px, 0.9fr) minmax(170px, 1fr) auto;
  gap: 14px;
  align-items: center;
  min-height: 60px;
  padding: 8px 4px;
  border-top: 1px solid var(--kp-border-subtle);
  transition: background 0.15s;
}
.fleet-lane .fleet-row:first-child { border-top: 0; }
.fleet-row:hover { background: var(--kp-accent-bg); }
.fleet-id { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.fleet-name {
  font-family: var(--kp-font-display);
  font-optical-sizing: auto;
  font-size: 17px; font-weight: 600; letter-spacing: -0.015em; line-height: 1.15;
  color: var(--kp-text); text-decoration: none;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  transition: color 0.15s;
}
.fleet-name:hover, .fleet-name:focus-visible { color: var(--kp-accent); text-decoration: none; }
.fleet-host {
  font-family: var(--kp-font-mono); font-size: 10.5px;
  color: var(--kp-text-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fleet-status { min-width: 0; }
.fleet-status-grid {
  display: grid;
  grid-template-columns: 7px minmax(0, 1fr);
  column-gap: 7px;
  row-gap: 3px;
  align-items: center;
}
.fleet-status-line { display: contents; }
.fleet-dot {
  width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0;
  background: var(--kp-text-muted);
}
.fleet-dot.live { background: var(--kp-success); }
.fleet-dot.warn { background: var(--kp-warn); }
.fleet-dot.err { background: var(--kp-danger); }
.fleet-dot.paused, .fleet-dot.idle { background: var(--kp-text-muted); }
.fleet-dot.busy {
  background: var(--kp-accent);
  animation: fleet-pulse 1.2s ease-in-out infinite;
}
@keyframes fleet-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}
.fleet-status-label {
  font-family: var(--kp-font-mono); font-size: 11px;
  text-transform: lowercase; letter-spacing: 0.01em;
  color: var(--kp-text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fleet-row[data-status="idle"] .fleet-status-label,
.fleet-row[data-status="paused"] .fleet-status-label { color: var(--kp-text-dim); }
.fleet-meta {
  grid-column: 2;
  font-family: var(--kp-font-mono); font-size: 10px;
  font-variant-numeric: tabular-nums;
  color: var(--kp-text-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fleet-meta.err { color: var(--kp-danger); }
.fleet-meta.warn { color: var(--kp-warn); }
/* Failure reasons expand on click — errors are instructions, they must be readable. */
button.fleet-meta-expandable {
  background: none; border: 0; padding: 0; margin: 0;
  text-align: left; cursor: pointer; display: block; width: 100%;
}
button.fleet-meta-expandable:hover { text-decoration: underline dotted; text-underline-offset: 2px; }
button.fleet-meta-expandable:focus-visible { outline: 1px solid currentColor; outline-offset: 2px; border-radius: 2px; }
button.fleet-meta-expandable.expanded {
  white-space: normal; overflow: visible; text-overflow: clip;
  overflow-wrap: anywhere; line-height: 1.5; user-select: text;
}
.fleet-progress {
  grid-column: 2;
  display: block; width: min(180px, 100%); height: 2px;
  background: var(--kp-surface-hi); border-radius: 1px; overflow: hidden;
}
.fleet-progress i {
  display: block; height: 100%; background: var(--kp-accent);
  transition: width 0.6s ease;
}
.fleet-actions {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  justify-content: flex-end;
}
.fleet-action {
  font-family: var(--kp-font-mono); font-size: 10.5px;
  text-transform: lowercase; letter-spacing: 0.02em;
  color: var(--kp-text-dim);
  background: transparent; border: 1px solid var(--kp-border); border-radius: 3px;
  padding: 5px 10px; cursor: pointer; text-decoration: none;
  transition: color 0.15s, border-color 0.15s;
}
.fleet-action:hover, .fleet-action:focus-visible {
  color: var(--kp-accent); border-color: var(--kp-accent); text-decoration: none;
}
.fleet-action:disabled { opacity: 0.55; cursor: default; }
.fleet-action:disabled:hover { color: var(--kp-text-dim); border-color: var(--kp-border); }
.fleet-lanes { display: inline-flex; gap: 4px; margin-right: 4px; }
.fleet-lane-chip {
  font-family: var(--kp-font-mono); font-size: 9.5px;
  font-variant-numeric: tabular-nums;
  padding: 2px 7px; border-radius: 2px;
  border: 1px solid var(--kp-border);
  color: var(--kp-text-dim);
}
.fleet-lane-chip.busy { color: var(--kp-accent); border-color: var(--kp-accent); }
.fleet-lane-chip.warn { color: var(--kp-warn); }
.fleet-lane-chip.err { color: var(--kp-danger); border-color: var(--kp-danger); }
.fleet-none { padding: 18px 4px; }

/* ── /apps — register masthead additions: stats strip + status tabs ──────
   The fleet ledger's own front page: serif numerals colored by the semantic
   taxonomy (never branded), ruled strip, quiet mono tabs with counts. */
.fleet-stats {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 28px;
  margin-top: 22px; padding: 18px 0 16px;
  border-top: 1px solid var(--kp-border);
  border-bottom: 1px solid var(--kp-border);
}
.fleet-stats:has(.fleet-stat:nth-child(5)) { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.fleet-stat-k {
  font-family: var(--kp-font-mono); font-size: 10px; letter-spacing: 0.02em;
  text-transform: lowercase; color: var(--kp-text-dim);
}
.fleet-stat-v {
  margin-top: 6px;
  font-family: var(--kp-font-display);
  font-optical-sizing: auto;
  font-size: 29px; line-height: 1.15;
  font-variant-numeric: tabular-nums;
  color: var(--kp-text);
}
.fleet-stat-v.ok { color: var(--kp-success); }
.fleet-stat-v.bad { color: var(--kp-danger); }
.fleet-stat-v.warn { color: var(--kp-warn); }
.fleet-stat-v.acc { color: var(--kp-accent); }
.fleet-stat-n { margin-top: 2px; font-size: 11px; color: var(--kp-text-dim); }

.fleet-toolbar {
  display: flex; align-items: flex-end; gap: 18px; flex-wrap: wrap;
  margin-top: 22px;
}
.fleet-toolbar .fleet-search { margin-top: 0; flex: 1; min-width: 200px; }
.fleet-tabs {
  display: flex; align-items: baseline; gap: 14px;
  padding-bottom: 6px;
  font-family: var(--kp-font-mono); font-size: 11px; color: var(--kp-text-dim);
}
.fleet-tabs button {
  background: none; border: none; cursor: pointer;
  font: inherit; color: inherit;
  padding: 0 0 3px; border-bottom: 1px solid transparent;
}
.fleet-tabs button:hover { color: var(--kp-text); }
.fleet-tabs button.on { color: var(--kp-text); border-bottom-color: var(--kp-accent); }
.fleet-tabs button .c { margin-left: 4px; color: var(--kp-text-dim); font-variant-numeric: tabular-nums; }
.fleet-toolbar .fleet-intro-actions { margin-top: 0; margin-left: auto; }

@media (max-width: 720px) {
  .fleet-stats { grid-template-columns: 1fr 1fr; gap: 16px 14px; }
  /* The 5-cell variant above is a :has() selector, so it OUTRANKS the plain
     .fleet-stats rule on specificity regardless of order — without this
     matching override a five-cell strip stays five columns wide on a phone
     (found on /todos, which always has five; /apps only hits it mid-deploy). */
  .fleet-stats:has(.fleet-stat:nth-child(5)) { grid-template-columns: 1fr 1fr; }
  .fleet-tabs { overflow-x: auto; max-width: 100%; }
  .fleet-toolbar .fleet-intro-actions { margin-left: 0; }
}

@media (max-width: 720px) {
  .fleet-row {
    grid-template-columns: 28px minmax(0, 1fr);
    grid-auto-rows: auto;
    row-gap: 6px;
    min-height: 0;
    padding: 12px 4px;
  }
  .fleet-status { grid-column: 2; }
  .fleet-actions { grid-column: 2; justify-content: flex-start; }
}

/* ── /apps/{id} — app detail register ────────────────────────────────────
   The fleet row opens into the same ruled paper: one identity masthead, a
   live band when traffic exists, then operational cards divided by ink. */
.app-detail { max-width: 1040px; margin: 0 auto; }
.app-detail-skeleton { display: flex; flex-direction: column; gap: 20px; padding-top: 18px; }
.app-breadcrumb {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  margin-bottom: 20px;
  font-family: var(--kp-font-mono); font-size: 10.5px; color: var(--kp-text-dim);
}
.app-breadcrumb a { color: var(--kp-accent); text-decoration: none; }
.app-breadcrumb a:hover, .app-breadcrumb a:focus-visible { text-decoration: underline; text-underline-offset: 3px; }
.app-detail-head {
  padding: 0 0 22px;
  border-bottom: 2px solid var(--kp-accent);
  position: relative;
}
.app-detail-head::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -4px;
  border-bottom: 1px solid var(--kp-accent-bg);
}
.app-title-line {
  display: grid; grid-template-columns: 44px minmax(0, 1fr) auto;
  gap: 15px; align-items: center;
}
.app-detail-glyph { width: 44px; height: 44px; font-size: 17px; }
.app-title-copy { min-width: 0; }
.app-title-copy h1 {
  font-family: var(--kp-font-display); font-optical-sizing: auto;
  font-size: 36px; line-height: 1.08; font-weight: 550;
  letter-spacing: -0.025em; color: var(--kp-text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.app-title-copy code, .app-detail-id {
  font-family: var(--kp-font-mono); font-size: 10px; color: var(--kp-text-dim);
}
.app-title-status {
  display: flex; align-items: center; gap: 7px; margin-bottom: 3px;
  font-family: var(--kp-font-mono); font-size: 10px; color: var(--kp-text-dim);
}
.app-detail-id { max-width: 230px; overflow: hidden; text-overflow: ellipsis; }
.app-quick-actions { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-top: 20px; }
.app-quick-action { min-height: 30px; display: inline-flex; align-items: center; }
.app-quick-action.primary { color: var(--kp-bg); background: var(--kp-accent); border-color: var(--kp-accent); }
.app-quick-action.primary:hover, .app-quick-action.primary:focus-visible { color: var(--kp-bg); background: var(--kp-accent-hi); }
.app-quick-action.danger { color: var(--kp-danger); border-color: color-mix(in oklch, var(--kp-danger) 45%, var(--kp-border)); }
.app-action-error {
  margin-top: 12px; padding: 9px 11px; border-left: 2px solid var(--kp-danger);
  background: var(--kp-danger-bg); color: var(--kp-danger);
  font-family: var(--kp-font-mono); font-size: 11px; line-height: 1.5;
  overflow-wrap: anywhere;
}
.app-live-band {
  margin-top: 26px; padding: 15px 18px;
  display: flex; align-items: center; justify-content: space-between; gap: 18px;
  border: 1px solid color-mix(in oklch, var(--kp-success) 40%, var(--kp-border));
  border-left: 3px solid var(--kp-success); border-radius: 3px;
  color: var(--kp-success); background: var(--kp-success-bg); text-decoration: none;
  font-family: var(--kp-font-mono); font-size: 10.5px;
}
.app-live-band > span:first-child { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.app-live-band strong { font-family: var(--kp-font); font-size: 13px; color: var(--kp-text); }
.app-live-band code { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--kp-success); }
.app-live-band:hover, .app-live-band:focus-visible { border-color: var(--kp-success); text-decoration: none; }

.app-detail-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 28px; margin-top: 26px;
  border-bottom: 1px solid var(--kp-border);
}
.app-detail-card {
  min-width: 0; padding: 18px 2px 22px;
  border-top: 1px solid var(--kp-border);
}
.app-card-wide { grid-column: 1 / -1; }
.app-card-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 15px; }
.app-card-head h2 {
  font-family: var(--kp-font-mono); font-size: 11px; font-weight: 500;
  letter-spacing: 0.02em; color: var(--kp-text-muted);
}
.app-card-ref { font-family: var(--kp-font-mono); font-size: 9px; color: var(--kp-accent); }
.app-card-empty, .app-card-note { font-size: 12px; color: var(--kp-text-dim); line-height: 1.5; }
.app-card-value {
  font-family: var(--kp-font-display); font-size: 25px; line-height: 1.2;
  font-variant-numeric: tabular-nums; color: var(--kp-text);
}
.app-card-link {
  display: inline-block; margin-top: 13px; color: var(--kp-accent); text-decoration: none;
  font-family: var(--kp-font-mono); font-size: 10px;
}
.app-card-link:hover, .app-card-link:focus-visible { text-decoration: underline; text-underline-offset: 3px; }
.app-latest-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.app-latest-head code { font-family: var(--kp-font-mono); font-size: 10px; color: var(--kp-text-dim); }
.app-status-pill {
  padding: 2px 8px; border: 1px solid var(--kp-border); border-radius: 2px;
  font-family: var(--kp-font-mono); font-size: 10px; color: var(--kp-text-dim);
}
.app-status-pill.live { color: var(--kp-success); border-color: color-mix(in oklch, var(--kp-success) 50%, var(--kp-border)); }
.app-status-pill.busy { color: var(--kp-accent); border-color: var(--kp-accent); }
.app-status-pill.warn { color: var(--kp-warn); }
.app-status-pill.err { color: var(--kp-danger); border-color: var(--kp-danger); }
.app-deploy-list { list-style: none; margin: 8px 0 0; }
.app-deploy-row {
  display: grid; grid-template-columns: 7px minmax(0, 1fr); gap: 10px;
  align-items: start; padding: 9px 0; border-top: 1px solid var(--kp-border-subtle);
}
.app-deploy-row .fleet-dot { margin-top: 4px; }
.app-deploy-copy { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; min-width: 0; }
.app-deploy-copy strong { font-family: var(--kp-font-mono); font-size: 10.5px; font-weight: 500; color: var(--kp-text); }
.app-deploy-copy span { font-family: var(--kp-font-mono); font-size: 9.5px; color: var(--kp-text-dim); text-align: right; }
.app-facts { display: grid; gap: 8px; }
.app-fact { display: grid; grid-template-columns: 88px minmax(0, 1fr); gap: 12px; align-items: baseline; }
.app-fact dt { font-family: var(--kp-font-mono); font-size: 9.5px; color: var(--kp-text-dim); }
.app-fact dd { font-family: var(--kp-font-mono); font-size: 10.5px; color: var(--kp-text); overflow-wrap: anywhere; }
.app-fact a { color: var(--kp-accent); text-decoration: none; }
.app-fact a:hover, .app-fact a:focus-visible { text-decoration: underline; }
.app-env-chips { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 10px; }
.app-health-line { display: flex; align-items: center; gap: 9px; margin-bottom: 5px; }
.app-health-line strong { font-size: 14px; font-weight: 600; color: var(--kp-text); }
.app-health[data-health="live"] .app-health-line strong { color: var(--kp-success); }
.app-health[data-health="warn"] .app-health-line strong { color: var(--kp-warn); }
.app-health[data-health="err"] .app-health-line strong { color: var(--kp-danger); }

/* ── /apps/{id}/logs — a deliberately dark instrument inside either theme ─ */
.app-logs { max-width: 1120px; margin: 0 auto; }
.app-logs-head { margin-bottom: 15px; }
.app-logs-title { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; }
.app-logs-title h1 {
  font-family: var(--kp-font-display); font-size: 36px; line-height: 1.08;
  font-weight: 550; letter-spacing: -0.025em;
}
.app-logs-title p { margin-top: 4px; font-family: var(--kp-font-mono); font-size: 10.5px; color: var(--kp-text-dim); }
.app-stream-state { display: flex; align-items: center; gap: 7px; }
.app-stream-badge {
  display: inline-flex; align-items: center; gap: 5px; padding: 3px 8px;
  border: 1px solid var(--kp-border); border-radius: 2px;
  font-family: var(--kp-font-mono); font-size: 9px; color: var(--kp-text-dim);
}
.app-stream-badge[hidden] { display: none; }
.app-stream-badge.live { color: var(--kp-success); border-color: color-mix(in oklch, var(--kp-success) 45%, var(--kp-border)); }
.app-stream-badge.live i { width: 6px; height: 6px; border-radius: 50%; background: var(--kp-success); animation: fleet-pulse 1.5s ease-in-out infinite; }
.app-stream-badge.off { color: var(--kp-danger); }
.app-log-toolbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 20px; padding-top: 15px; border-top: 1px solid var(--kp-border);
}
.app-log-search { flex: 1; min-width: 180px; }
.app-log-levels, .app-log-actions { display: flex; align-items: center; gap: 5px; }
.app-log-levels button {
  padding: 4px 8px; border: 1px solid var(--kp-border); border-radius: 3px;
  background: transparent; color: var(--kp-text-dim); cursor: pointer;
  font-family: var(--kp-font-mono); font-size: 9.5px;
  opacity: 0.42; text-decoration: line-through;
}
.app-log-levels button.on { opacity: 1; text-decoration: none; }
.app-log-levels button.error.on { color: var(--kp-danger); border-color: color-mix(in oklch, var(--kp-danger) 45%, var(--kp-border)); }
.app-log-levels button.warn.on { color: var(--kp-warn); }
.app-log-levels button.info.on { color: var(--kp-info); }
.app-log-count { margin-left: auto; font-family: var(--kp-font-mono); font-size: 9.5px; color: var(--kp-text-dim); }
.app-log-viewer {
  min-height: 430px; max-height: 68vh; overflow: auto;
  padding: 14px 16px; border: 1px solid #30363d; border-radius: 3px;
  background: #0d1117; color: #c9d1d9;
  font-family: var(--kp-font-mono); font-size: 11.5px; line-height: 1.72;
  box-shadow: var(--kp-shadow);
}
.app-log-empty { padding: 100px 20px; text-align: center; color: #6e7681; }
.app-log-line { display: flex; align-items: baseline; gap: 8px; white-space: pre-wrap; overflow-wrap: anywhere; }
.app-log-line:hover { background: rgba(255,255,255,0.03); }
.app-log-line .ts { flex-shrink: 0; color: #6e7681; }
.app-log-line .lvl { flex: 0 0 42px; font-weight: 700; }
.app-log-line .lvl.error { color: #f87171; }
.app-log-line .lvl.warn { color: #fbbf24; }
.app-log-line .lvl.info { color: #60a5fa; }
.app-log-line .lvl.debug { color: #6e7681; }
.app-log-line .msg { min-width: 0; color: #c9d1d9; }
.app-log-stats { display: flex; gap: 18px; flex-wrap: wrap; padding: 9px 3px 0; font-family: var(--kp-font-mono); font-size: 9.5px; color: var(--kp-text-dim); }
.app-log-stats strong.error { color: var(--kp-danger); }
.app-log-stats strong.warn { color: var(--kp-warn); }
.app-log-stats strong.info { color: var(--kp-info); }

@media (max-width: 720px) {
  .app-title-line { grid-template-columns: 38px minmax(0, 1fr); }
  .app-detail-glyph { width: 38px; height: 38px; }
  .app-title-copy h1, .app-logs-title h1 { font-size: 31px; }
  .app-detail-id { display: none; }
  .app-detail-grid { grid-template-columns: minmax(0, 1fr); }
  .app-card-wide { grid-column: auto; }
  .app-live-band { align-items: flex-start; }
  .app-deploy-copy { flex-direction: column; gap: 2px; }
  .app-deploy-copy span { text-align: left; }
  .app-log-toolbar { align-items: stretch; }
  .app-log-search { flex-basis: 100%; }
  .app-log-count { margin-left: 0; align-self: center; }
  .app-log-viewer { min-height: 55vh; padding: 11px; font-size: 10.5px; }
  .app-log-line { display: grid; grid-template-columns: minmax(90px, auto) 40px minmax(0, 1fr); gap: 6px; }
  .app-log-line .ts:only-child { grid-column: 1 / -1; }
}

/* Apps review C08 (2026-09-06): on a phone, or under a finger, every action on the app page
   reaches 44 px. Padding counts toward the target; the glyph itself does not. Placed after the
   720px block so the 44 px glyph wins over its 38 px phone size. */
@media (max-width: 600px), (pointer: coarse) {
  .app-quick-action { min-height: 44px; padding-inline: 14px; }
  .app-detail-glyph, .app-glyph.app-detail-glyph { width: 44px; height: 44px; }
  .app-title-line { grid-template-columns: 44px minmax(0, 1fr); }
  .app-breadcrumb a { display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; padding-inline: 6px; margin-inline: -6px; }
  .app-facts dd a { display: inline-flex; align-items: center; min-height: 44px; overflow-wrap: anywhere; }
  .app-card-link { display: inline-flex; align-items: center; min-height: 44px; margin-top: 2px; }
}

/* ── /apps/{id}/settings + /lanes — strangler management ledger ────────── */
.app-manage { max-width: 1040px; margin: 0 auto; }
.app-manage-head {
  padding-bottom: 22px; margin-bottom: 18px;
  border-bottom: 2px solid var(--kp-accent); position: relative;
}
.app-manage-head::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -4px;
  border-bottom: 1px solid var(--kp-accent-bg);
}
.app-manage-title { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; }
.app-manage-title h1 {
  margin: 1px 0 3px; font: 550 36px/1.08 var(--kp-font-display);
  letter-spacing: -0.025em; color: var(--kp-text);
}
.app-manage-title > div > p:last-child { margin: 0; font-size: 12px; color: var(--kp-text-dim); }
.app-manage-kicker {
  margin: 0; font: 10px/1.3 var(--kp-font-mono); color: var(--kp-accent);
  text-transform: lowercase; letter-spacing: 0.03em;
}
.app-manage-links { display: flex; gap: 7px; flex-wrap: wrap; justify-content: flex-end; }
.app-manage-error {
  margin-top: 40px; padding: 24px; border: 1px solid var(--kp-danger);
  border-left-width: 3px; border-radius: 3px; background: var(--kp-danger-bg);
}
.app-manage-error h2 { margin: 0 0 5px; font-size: 16px; color: var(--kp-text); }
.app-manage-error p { margin: 0; font: 11px/1.55 var(--kp-font-mono); color: var(--kp-danger); }

.app-settings-nav {
  position: sticky; top: var(--fleet-header-h, 44px); z-index: 10;
  display: flex; gap: 18px; overflow-x: auto;
  margin: 0 0 22px; padding: 12px 0 8px;
  border-bottom: 1px solid var(--kp-border);
  background: color-mix(in srgb, var(--kp-bg) 94%, transparent);
  backdrop-filter: blur(10px);
}
.app-settings-nav a {
  flex: none; padding-bottom: 4px; border-bottom: 1px solid transparent;
  font: 10.5px/1 var(--kp-font-mono); color: var(--kp-text-dim); text-decoration: none;
}
.app-settings-nav a:hover, .app-settings-nav a:focus-visible {
  color: var(--kp-accent); border-color: var(--kp-accent); text-decoration: none;
}
.app-settings-sections { border-bottom: 1px solid var(--kp-border); }
.app-settings-section {
  display: grid; grid-template-columns: minmax(190px, 0.34fr) minmax(0, 1fr); gap: 34px;
  scroll-margin-top: 104px; padding: 30px 2px 34px; border-top: 1px solid var(--kp-border);
}
.app-settings-section:first-child { border-top: 0; }
.app-settings-section-head { display: grid; grid-template-columns: 28px minmax(0, 1fr); align-items: start; gap: 4px; }
.app-settings-section-head .app-card-ref { padding-top: 3px; }
.app-settings-section-head h2, .app-lanes-section h2, .app-traffic-section h2 {
  margin: 0; font: 550 20px/1.18 var(--kp-font-display); letter-spacing: -0.015em; color: var(--kp-text);
}
.app-settings-section-head p, .app-lanes-section header p, .app-traffic-section header p {
  margin: 5px 0 0; font-size: 11.5px; line-height: 1.5; color: var(--kp-text-dim);
}
.app-settings-section.danger { border-top-color: color-mix(in srgb, var(--kp-danger) 45%, var(--kp-border)); }
.app-settings-section.danger h2 { color: var(--kp-danger); }
.app-settings-stack { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.app-setting-block {
  padding: 16px; border: 1px solid var(--kp-border); border-radius: 3px;
  background: color-mix(in srgb, var(--kp-surface) 75%, transparent);
}
.app-setting-block h3, .app-danger-row h3 {
  margin: 0 0 11px; font-size: 12.5px; font-weight: 650; color: var(--kp-text);
}
.app-setting-block p, .app-danger-row p { margin: 3px 0 0; font-size: 11.5px; line-height: 1.5; color: var(--kp-text-dim); }
.app-setting-row, .app-danger-row { display: flex; align-items: center; justify-content: space-between; gap: 20px; }
.app-danger-row { min-width: 0; }
.app-danger-row h3 { margin-bottom: 2px; color: var(--kp-danger); }

.app-form-grid { display: grid; gap: 13px; }
.app-inline-form { display: flex; align-items: flex-end; gap: 10px; }
.app-inline-form > .app-form-field { flex: 1; }
.app-form-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.app-form-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.app-form-label, .app-check-group legend {
  font: 9.5px/1.2 var(--kp-font-mono); color: var(--kp-text-muted);
  text-transform: uppercase; letter-spacing: 0.055em;
}
.app-form-note { font-size: 10.5px; line-height: 1.45; color: var(--kp-text-dim); }
.app-settings-input, .app-settings-select {
  width: 100%; min-height: 34px; padding: 7px 9px;
  border: 1px solid var(--kp-border); border-radius: 3px;
  background: var(--kp-surface); color: var(--kp-text);
  font: 11.5px/1.3 var(--kp-font-mono); box-sizing: border-box;
}
.app-settings-select { appearance: auto; }
.app-settings-input:focus, .app-settings-select:focus { outline: 1px solid var(--kp-accent); border-color: var(--kp-accent); }
.app-settings-action { min-height: 31px; flex: none; }
.app-settings-action.primary {
  color: var(--kp-bg); background: var(--kp-accent); border-color: var(--kp-accent);
}
.app-settings-action.primary:hover, .app-settings-action.primary:focus-visible { color: var(--kp-bg); background: var(--kp-accent-hi); }
.app-settings-action.danger { color: var(--kp-danger); border-color: color-mix(in srgb, var(--kp-danger) 48%, var(--kp-border)); }
.app-check { display: flex; align-items: flex-start; gap: 8px; font-size: 11.5px; line-height: 1.45; color: var(--kp-text); }
.app-check input { margin-top: 2px; accent-color: var(--kp-accent); }
.app-check small { display: block; margin-top: 2px; color: var(--kp-text-dim); }
.app-check-panel { padding: 11px; border: 1px solid var(--kp-border); border-radius: 3px; }
.app-check-group { display: grid; gap: 8px; padding: 0; border: 0; }
.app-check-group legend { margin-bottom: 7px; }
.app-inline-warning, .app-inline-error {
  margin: 0; padding: 9px 11px; border-left: 2px solid var(--kp-warn);
  background: var(--kp-warn-bg); color: var(--kp-warn); font-size: 11px; line-height: 1.5;
}
.app-inline-error { border-color: var(--kp-danger); background: var(--kp-danger-bg); color: var(--kp-danger); }
.app-section-intro { margin: 0; font-size: 11.5px; line-height: 1.55; color: var(--kp-text-dim); }
.app-section-intro code { color: var(--kp-accent); font-family: var(--kp-font-mono); overflow-wrap: anywhere; }
.app-settings-empty {
  margin: 0; padding: 24px 16px; border: 1px dashed var(--kp-border); border-radius: 3px;
  text-align: center; font-size: 11.5px; color: var(--kp-text-dim);
}

.app-env-list, .app-domain-list { display: grid; gap: 6px; }
.app-env-row {
  display: grid; grid-template-columns: minmax(120px, 0.6fr) minmax(120px, 1fr) auto; gap: 10px; align-items: center;
  min-height: 42px; padding: 6px 8px; border-top: 1px solid var(--kp-border-subtle);
}
.app-env-row:first-child { border-top: 0; }
.app-env-key { font: 600 10.5px/1.3 var(--kp-font-mono); color: var(--kp-text); overflow-wrap: anywhere; }
.app-env-value { min-width: 0; display: flex; align-items: center; gap: 6px; overflow: hidden; }
.app-secret-value {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font: 10.5px/1.3 var(--kp-font-mono); letter-spacing: 0.08em; color: var(--kp-text-dim);
}
.app-secret-value[data-masked="false"] { white-space: normal; overflow-wrap: anywhere; letter-spacing: 0; color: var(--kp-text); }
.app-reveal { padding: 3px 7px; font-size: 9px; }
.app-mini-badge {
  display: inline-flex; padding: 2px 6px; border: 1px solid var(--kp-border); border-radius: 2px;
  font: 8.5px/1.2 var(--kp-font-mono); color: var(--kp-text-dim); text-transform: lowercase;
}
.app-mini-badge.warn { color: var(--kp-warn); }
.app-env-form { margin-top: 2px; }

.app-domain-row { padding: 13px 2px; border-top: 1px solid var(--kp-border-subtle); }
.app-domain-row:first-child { border-top: 0; }
.app-domain-title { display: flex; align-items: center; gap: 8px; min-width: 0; }
.app-domain-title > code { min-width: 0; overflow-wrap: anywhere; font: 600 11px/1.3 var(--kp-font-mono); color: var(--kp-text); }
.app-row-actions { display: flex; align-items: center; gap: 6px; margin-left: auto; flex-wrap: wrap; justify-content: flex-end; }
.app-dns-records { margin-top: 10px; padding: 11px; border: 1px solid var(--kp-border); border-radius: 3px; background: var(--kp-surface); }
.app-dns-records > p { margin: 0 0 7px; font-size: 10.5px; color: var(--kp-text-dim); }
.app-dns-row { display: grid; grid-template-columns: 70px minmax(0, 1fr); gap: 9px; padding: 4px 0; }
.app-dns-row span { font: 9px/1.4 var(--kp-font-mono); color: var(--kp-text-dim); text-transform: uppercase; }
.app-dns-row code { font: 10px/1.4 var(--kp-font-mono); color: var(--kp-text); overflow-wrap: anywhere; }
.app-repo-info { display: grid; gap: 9px; min-width: 0; }
.app-repo-link { color: var(--kp-accent); font-size: 12.5px; text-decoration: none; }
.app-repo-info > code, .app-clone-command code { font: 10.5px/1.5 var(--kp-font-mono); color: var(--kp-text-dim); overflow-wrap: anywhere; }
.app-clone-command { display: grid; grid-template-columns: 52px minmax(0, 1fr); gap: 8px; padding: 10px; border: 1px solid var(--kp-border); background: var(--kp-surface); }
.app-clone-command span { font: 9px/1.4 var(--kp-font-mono); color: var(--kp-text-dim); text-transform: uppercase; }

.app-modal-backdrop {
  position: fixed; inset: 0; z-index: 4000; display: grid; place-items: center; padding: 20px;
  background: rgba(5, 8, 15, 0.62); backdrop-filter: blur(4px);
}
.app-modal {
  width: min(430px, 100%); padding: 24px; border: 1px solid var(--kp-border); border-top: 3px solid var(--kp-danger);
  border-radius: 3px; background: var(--kp-surface); box-shadow: var(--kp-shadow-lg); color: var(--kp-text);
}
.app-modal > .app-card-ref { margin: 0 0 7px; color: var(--kp-danger); }
.app-modal h2 { margin: 0 0 8px; font: 550 21px/1.2 var(--kp-font-display); }
.app-modal > p:not(.app-card-ref) { margin: 0 0 14px; font-size: 12px; line-height: 1.55; color: var(--kp-text-dim); }
.app-confirm-instruction code { color: var(--kp-text); font-weight: 650; }
.app-modal > .app-settings-input { margin-bottom: 12px; }
.app-keep-repo { margin: 2px 0 16px; }
.app-modal-actions { display: flex; justify-content: flex-end; gap: 7px; }

/* ── app icon: the org picture an owner gives an app ────────────────────
   The mark in the detail header IS the control that changes it, so the
   thing being edited and the thing being clicked are the same object. */
.app-detail-glyph { position: relative; overflow: hidden; padding: 0; }
.app-icon-letter { line-height: 1; }
.app-icon-picture {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; opacity: 0; transition: opacity 0.18s;
}
/* Uncovered only once the browser reports a decoded picture, so a missing
   key leaves the letter showing instead of a blank square. */
.app-icon-picture.is-loaded { opacity: 1; }
button.app-icon-edit { cursor: pointer; appearance: none; font: inherit; color: var(--app-hue, var(--kp-accent)); }
button.app-icon-edit:hover, button.app-icon-edit:focus-visible { border-color: var(--kp-accent); }
button.app-icon-edit:focus-visible { outline: 2px solid var(--kp-accent); outline-offset: 2px; }
.app-icon-edit-badge {
  position: absolute; right: 0; bottom: 0; z-index: 2;
  display: grid; place-items: center; width: 15px; height: 15px;
  color: var(--kp-surface); background: var(--kp-accent);
  border-top-left-radius: 2px;
}
.app-icon-edit-badge svg { width: 9px; height: 9px; stroke-linecap: round; stroke-linejoin: round; }
/* Hover tints the whole mark, so the badge reads as a handle on the picture
   rather than a decoration sitting beside it. */
button.app-icon-edit::after {
  content: ""; position: absolute; inset: 0;
  background: var(--kp-accent); opacity: 0; transition: opacity 0.15s;
}
button.app-icon-edit:hover::after, button.app-icon-edit:focus-visible::after { opacity: 0.18; }

/* The picker is not a destructive dialog, so it takes the accent rule the
   rest of this page uses rather than .app-modal's danger rule. */
.app-icon-modal { width: min(560px, 100%); border-top-color: var(--kp-accent); }
.app-icon-modal > .app-card-ref { color: var(--kp-accent); }
.app-icon-modal.is-busy { cursor: progress; }
/* `.app-modal > p:not(.app-card-ref)` sets colour and size for every paragraph
   in a modal and outranks a two-class selector, so these are scoped through
   .app-modal to win. Without that the refusal renders in the same dim grey as
   "Saving…", which is the difference between a warning and a status line. */
.app-modal > .app-icon-status { margin: 0 0 12px; font: 11px/1.5 var(--kp-font-mono); color: var(--kp-text-dim); min-height: 17px; }
.app-modal > .app-icon-status.err { color: var(--kp-danger); }
.app-modal > .app-icon-warn { margin: 0 0 12px; padding: 9px 11px; border: 1px solid var(--kp-danger); background: var(--kp-danger-bg); color: var(--kp-danger); font-size: 12px; line-height: 1.5; }
.app-modal .app-icon-note { margin: 12px 0 0; font-size: 11.5px; line-height: 1.55; color: var(--kp-text-dim); }
.app-icon-body { margin-bottom: 18px; }

/* ── describe it instead of finding it ─────────────────────────────────── */
.app-icon-generate { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; margin-bottom: 12px; }
.app-modal .app-icon-or {
  margin: 0 0 12px; font: 10px/1 var(--kp-font-mono); letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--kp-text-dim); text-align: center;
  display: grid; grid-template-columns: 1fr auto 1fr; gap: 10px; align-items: center;
}
.app-modal .app-icon-or::before, .app-modal .app-icon-or::after {
  content: ""; height: 1px; background: var(--kp-border);
}

/* A candidate nobody has accepted. Shown at the two sizes it will really live
   at — a large preview of a small icon is a lie about what you are choosing. */
.app-icon-candidate { display: grid; gap: 14px; justify-items: center; }
.app-icon-candidate-big {
  width: 168px; height: 168px; object-fit: cover;
  border: 1px solid var(--kp-border); border-radius: 12px; background: var(--kp-bg);
}
.app-icon-candidate-sizes { display: flex; gap: 22px; align-items: flex-end; }
.app-icon-candidate-size { display: grid; gap: 6px; justify-items: center; }
.app-icon-candidate-size small { font: 10px/1.3 var(--kp-font-mono); color: var(--kp-text-dim); }
/* The desktop tile, at its real 46px, on the real plate. */
.app-icon-candidate-tile { position: relative; width: 46px; height: 46px; border-radius: 10px; overflow: hidden; }
.app-icon-candidate-mark { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
/* And the favicon, at the size a browser tab actually draws it. */
.app-icon-candidate-fav { width: 16px; height: 16px; object-fit: cover; border-radius: 3px; }

.app-icon-grid {
  display: grid; gap: 9px; align-items: start;
  grid-template-columns: repeat(auto-fill, minmax(118px, 1fr));
  max-height: 46vh; overflow-y: auto;
}
.app-icon-card {
  display: flex; flex-direction: column; gap: 7px; align-items: center;
  padding: 11px 9px; border: 1px solid var(--kp-border); border-radius: 2px;
  background: var(--kp-surface); color: var(--kp-text); text-align: center;
  cursor: pointer; transition: border-color 0.15s, background 0.15s;
}
.app-icon-card:hover, .app-icon-card:focus-within, .app-icon-card:focus-visible {
  border-color: var(--kp-accent); background: var(--kp-accent-bg);
}
.app-icon-card:focus-visible { outline: 2px solid var(--kp-accent); outline-offset: -2px; }
.app-icon-card:disabled { cursor: default; opacity: 0.55; }
.app-icon-choice.is-current { border-color: var(--kp-accent); border-width: 2px; padding: 10px 8px; }
.app-icon-thumb {
  width: 56px; height: 56px; border: 1px solid var(--kp-border); border-radius: 2px;
  background-color: var(--kp-bg); background-size: cover; background-position: center;
}
.app-icon-key {
  font: 10px/1.4 var(--kp-font-mono); color: var(--kp-text-dim);
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.app-icon-upload { border-style: dashed; }
.app-icon-upload.is-over { border-color: var(--kp-accent); border-style: solid; background: var(--kp-accent-bg); }
.app-icon-upload-mark {
  display: grid; place-items: center; width: 56px; height: 56px;
  border: 1px solid var(--kp-border); border-radius: 2px; color: var(--kp-accent);
}
.app-icon-upload-mark svg { width: 24px; height: 24px; stroke-linecap: round; stroke-linejoin: round; }
.app-icon-upload-copy { display: grid; gap: 3px; }
.app-icon-upload-copy strong { font-size: 12px; font-weight: 600; }
.app-icon-upload-copy small { font-size: 10.5px; line-height: 1.45; color: var(--kp-text-dim); }

/* Day one: no organization has pictures yet, so the empty state is the
   ordinary path. One large target, and no grid left standing empty. */
.app-icon-empty .app-icon-upload.is-large {
  flex-direction: row; gap: 15px; align-items: center; text-align: left; padding: 22px 20px;
}
.app-icon-empty .app-icon-upload.is-large .app-icon-upload-mark { width: 64px; height: 64px; flex-shrink: 0; }
.app-icon-empty .app-icon-upload.is-large .app-icon-upload-copy strong { font-size: 15px; }
@media (max-width: 560px) {
  .app-icon-grid { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }
  .app-icon-empty .app-icon-upload.is-large { flex-direction: column; text-align: center; }
}
.app-toast-host { position: fixed; left: 0; right: 0; bottom: 26px; z-index: 5000; display: flex; flex-direction: column; align-items: center; gap: 8px; pointer-events: none; }
.app-toast { max-width: min(620px, 90vw); padding: 10px 15px; border: 1px solid var(--kp-border); border-radius: 3px; background: var(--kp-surface); box-shadow: var(--kp-shadow-lg); color: var(--kp-text); font: 11px/1.45 var(--kp-font-mono); pointer-events: auto; }
.app-toast.err { border-color: var(--kp-danger); background: var(--kp-danger-bg); color: var(--kp-danger); }

.app-lanes-section, .app-traffic-section { padding: 24px 2px 30px; border-bottom: 1px solid var(--kp-border); }
.app-lanes-section > header, .app-traffic-section > header { display: grid; grid-template-columns: 30px minmax(0, 1fr); align-items: start; margin-bottom: 18px; }
.app-lane-create { max-width: 560px; margin-bottom: 16px; padding: 14px; border: 1px solid var(--kp-border); background: color-mix(in srgb, var(--kp-surface) 72%, transparent); }
.app-lane-list { border-top: 1px solid var(--kp-border); }
.app-lane-row {
  display: grid; grid-template-columns: minmax(0, 1fr) 78px auto; gap: 18px; align-items: center;
  min-height: 72px; padding: 12px 3px; border-bottom: 1px solid var(--kp-border-subtle);
}
.app-lane-identity { display: grid; grid-template-columns: auto auto 1fr; align-items: center; gap: 9px; min-width: 0; }
.app-lane-identity > code { font: 600 13px/1.3 var(--kp-font-mono); color: var(--kp-text); }
.app-lane-identity > span:last-child { grid-column: 1 / -1; font: 9.5px/1.4 var(--kp-font-mono); color: var(--kp-text-dim); }
.app-lane-status { display: inline-flex; align-items: center; gap: 5px; color: var(--kp-text-dim); font: 9px/1.2 var(--kp-font-mono); }
.app-lane-status.live { color: var(--kp-success); }
.app-lane-status.busy { color: var(--kp-accent); }
.app-lane-status.err { color: var(--kp-danger); }
.app-lane-weight { text-align: center; }
.app-lane-weight strong { display: block; font: 550 21px/1.1 var(--kp-font-display); color: var(--kp-text); font-variant-numeric: tabular-nums; }
.app-lane-weight span { font: 8.5px/1.2 var(--kp-font-mono); color: var(--kp-text-dim); text-transform: uppercase; }
.app-traffic-bar { display: flex; height: 28px; margin: 0 0 20px; overflow: hidden; border: 1px solid var(--kp-border); border-radius: 3px; background: var(--kp-surface); }
.app-traffic-bar span { display: grid; place-items: center; overflow: hidden; min-width: 2px; color: #fff; font: 9px/1 var(--kp-font-mono); transition: width 0.15s; }
.app-traffic-bar .tone-0 { background: var(--kp-success); }
.app-traffic-bar .tone-1 { background: var(--kp-accent); }
.app-traffic-bar .tone-2 { background: var(--kp-info); }
.app-traffic-bar .tone-3 { background: var(--kp-icon-violet); }
.app-traffic-sliders { display: grid; gap: 11px; }
.app-traffic-row { display: grid; grid-template-columns: 95px minmax(0, 1fr) 48px; gap: 12px; align-items: center; }
.app-traffic-row code { font: 10.5px/1.3 var(--kp-font-mono); color: var(--kp-text); }
.app-traffic-row input { width: 100%; accent-color: var(--kp-accent); }
.app-traffic-row output { text-align: right; font: 10.5px/1.3 var(--kp-font-mono); color: var(--kp-text); font-variant-numeric: tabular-nums; }
.app-traffic-actions { display: flex; align-items: center; gap: 12px; margin-top: 18px; }
.app-traffic-warning { font: 10px/1.4 var(--kp-font-mono); color: var(--kp-success); }
.app-traffic-warning.err { color: var(--kp-danger); }

@media (max-width: 760px) {
  .app-manage-title { align-items: flex-start; flex-direction: column; }
  .app-manage-title h1 { font-size: 31px; }
  .app-manage-links { justify-content: flex-start; }
  .app-settings-nav { top: 0; }
  .app-settings-section { grid-template-columns: minmax(0, 1fr); gap: 18px; padding-top: 24px; }
  .app-settings-section-head { grid-template-columns: 28px minmax(0, 1fr); }
  .app-inline-form, .app-setting-row, .app-danger-row { align-items: stretch; flex-direction: column; }
  .app-form-pair { grid-template-columns: minmax(0, 1fr); }
  .app-env-row { grid-template-columns: minmax(100px, 0.7fr) minmax(0, 1fr); }
  .app-env-row > .app-settings-action { grid-column: 2; justify-self: start; }
  .app-domain-title { align-items: flex-start; flex-wrap: wrap; }
  .app-domain-title .app-row-actions { width: 100%; justify-content: flex-start; margin-left: 15px; }
  .app-lane-row { grid-template-columns: minmax(0, 1fr) auto; }
  .app-lane-row > .app-row-actions { grid-column: 1 / -1; justify-content: flex-start; margin-left: 0; }
  .app-lane-identity { grid-template-columns: auto 1fr; }
  .app-traffic-row { grid-template-columns: 74px minmax(0, 1fr) 40px; gap: 8px; }
}
/* ── /todos — a todo list ─────────────────────────────────────────────────
   Inputs, receipts, detail forms and the stable type scale are shared by the
   ticket rail below. The physical ticket treatment follows the legacy
   grid-safe primitives so detail dependency rows can keep using them.

   Three rules hold the layout still, because the complaint that started this
   rewrite was that the app "janks when I click on stuff":

   1. The column is `min(720px, 100%)` and NOTHING inside it may change that.
   2. Every grid track on a row is fixed except the title. A track sized `auto`
      re-measures when its content changes, so one row's longer chip used to
      move the title column on every row around it.
   3. Buttons reserve the width of their WIDEST label, so a label swap
      ("Claim" → "Claiming…") cannot reflow the row under the pointer.

   Type is a fixed rem scale — never `clamp()`, never px — so a reader who has
   set a larger browser font gets one. Four steps, ratio ≈1.15, plus the one
   deliberate exception: title 13px over meta 12px (1.083) is the row pairing
   the design calls for, and a wider gap there makes rows taller for nothing. */
.td-page {
  /* 12 / 13 / 15 / 17 */
  --td-f-meta: 0.75rem;
  --td-f-body: 0.8125rem;
  --td-f-sec: 0.9375rem;
  --td-f-title: 1.0625rem;
  --td-row-h: 2.25rem;
  --td-gap: 0.5rem;
  /* Slots that must not resize when their contents change. */
  --td-w-check: 1rem;
  --td-w-id: 4rem;
  --td-w-blocks: 4.5rem;
  --td-w-date: 4rem;
  --td-w-lease: 2rem;
  --td-w-own: 1.25rem;
}
.td {
  width: min(720px, 100%);
  margin-inline: auto;
  font-size: var(--td-f-body);
  line-height: 1.45;
}
.td-page a { color: inherit; text-decoration: none; }
.td-page a:hover { text-decoration: underline; text-underline-offset: 2px; }
.td-page :focus-visible {
  outline: 2px solid var(--kp-accent);
  outline-offset: 2px;
  border-radius: 2px;
}
/* Numbers are the machine voice: mono, tabular, and in a reserved slot so a
   count going 9 → 10 cannot nudge the tab beside it. */
.td-n {
  display: inline-block;
  /* Left-aligned in a reserved slot: 9 and 10 start at the same x, so a
     changing count cannot nudge the next tab — and the digit still sits beside
     its label instead of drifting a slot-width away from it. */
  min-width: 1.5rem;
  text-align: left;
  font-family: var(--kp-font-mono);
  font-size: var(--td-f-meta);
  font-variant-numeric: tabular-nums;
  color: var(--kp-text-dim);
}
.td-n-over { color: var(--kp-danger); min-width: 1.75rem; margin-left: -0.5rem; }
.td-vh {
  position: absolute; width: 1px; height: 1px; padding: 0;
  margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* ── toolbar ─────────────────────────────────────────────────────────────── */
.td-bar {
  display: flex; align-items: stretch; justify-content: space-between;
  gap: var(--td-gap); flex-wrap: wrap;
  border-bottom: 1px solid var(--kp-border);
}
/* `min-width: 0` is not decoration. As a flex item the tab strip's automatic
   minimum size is its min-content width; without this it refuses to shrink,
   drags its parent past the viewport, and the whole page scrolls sideways on a
   phone (measured 508px of content in a 390px viewport). */
.td-tabs {
  display: flex; list-style: none; gap: 0.125rem; margin: 0;
  min-width: 0; overflow-x: auto; scrollbar-width: thin;
  /* `overflow-x: auto` ALONE puts a vertical scrollbar in the tab strip. Per
     CSS Overflow, a non-`visible` value on one axis computes the other axis
     from `visible` to `auto` — so asking for horizontal tab scrolling silently
     opts the strip into vertical scrolling too. The active-tab marker below is
     deliberately `bottom: -1px` so its 2px accent COVERS the bar's 1px rule
     rather than floating above it, and that 1px overhang is exactly enough to
     trip it: content 41px in a 40px box. The operator saw the scrollbar; no
     gate did, because the layout checks measured document-level HORIZONTAL
     overflow and never an inner container's vertical.
     `overflow-y: hidden` alone would clip the marker to 1px. The padding gives
     the overhang somewhere legal to live and the negative margin puts the strip
     back where it was, so the rule and the accent do not move — verified in the
     browser: scrollsY false, marker displacement 0px. */
  overflow-y: hidden;
  padding: 0 0 1px;
  margin-bottom: -1px;
}
.td-tab {
  display: flex; align-items: center; gap: 0.375rem;
  /* 40px tall — the row of primary navigation is also the primary touch
     target, and WCAG 2.5.8 wants ≥24px. The active marker is drawn with a
     pseudo-element so the hit area can be tall while the ink stays quiet. */
  min-height: 2.5rem;
  padding: 0 0.5rem;
  position: relative;
  color: var(--kp-text-dim);
  white-space: nowrap;
}
.td-tab:hover { color: var(--kp-text); text-decoration: none; }
.td-tab.is-on { color: var(--kp-text); }
.td-tab.is-on::after {
  content: ""; position: absolute; inset-inline: 0.375rem; bottom: -1px;
  height: 2px; background: var(--kp-accent);
}
.td-tab.is-on .td-n { color: var(--kp-text); }
.td-bar-r { display: flex; align-items: center; gap: var(--td-gap); }
.td-scope { display: inline-flex; border: 1px solid var(--kp-border); border-radius: var(--kp-radius); overflow: hidden; }
.td-seg {
  display: flex; align-items: center; min-height: 1.75rem; padding: 0 0.5rem;
  font-size: var(--td-f-meta); color: var(--kp-text-dim); background: transparent;
}
.td-seg:hover { color: var(--kp-text); background: var(--kp-surface-hi); text-decoration: none; }
.td-seg.is-on { color: var(--kp-text); background: var(--kp-surface-hi); }
.td-seg + .td-seg { border-left: 1px solid var(--kp-border); }

/* ── inputs ──────────────────────────────────────────────────────────────── */
.td-input {
  font: inherit; font-size: var(--td-f-body);
  color: var(--kp-text); background: var(--kp-surface);
  border: 1px solid var(--kp-border); border-radius: var(--kp-radius);
  padding: 0.3125rem 0.5rem; min-height: 1.75rem;
}
.td-input::placeholder { color: var(--kp-text-muted); }
.td-input:hover { border-color: var(--kp-border-strong); }
.td-input:focus-visible { border-color: var(--kp-accent); }
.td-input:disabled { color: var(--kp-text-disabled); background: var(--kp-bg); cursor: not-allowed; }
.td-input-q { width: 9rem; }
.td-input-new { flex: 1 1 auto; min-width: 0; }

.td-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 1.75rem; min-width: 4rem; padding: 0 0.625rem;
  font: inherit; font-size: var(--td-f-meta);
  color: var(--kp-text); background: var(--kp-surface);
  border: 1px solid var(--kp-border); border-radius: var(--kp-radius);
  cursor: pointer;
}
.td-btn:hover { background: var(--kp-surface-hi); border-color: var(--kp-border-strong); text-decoration: none; }
.td-btn:active { background: var(--kp-bg); }
/* A disabled control is the one place --kp-text-disabled is legitimate:
   WCAG 1.4.3 exempts inactive components. Everywhere else it measures
   2.5–2.8:1 and is a contrast failure, not a shade of grey.

   `aria-busy` used to be in this selector while todos.js never set `disabled`
   — measured 2.96:1 dark and 2.94:1 light on a button that was, by its own
   `disabled === false`, entirely live. A busy control cannot borrow the
   exemption, so it keeps full contrast and says it is busy with the cursor. */
.td-btn:disabled { color: var(--kp-text-disabled); cursor: default; border-color: var(--kp-border-subtle); }
.td-btn[aria-busy="true"], .td-check[aria-busy="true"], .td-own[aria-busy="true"] { cursor: progress; }
.td-btn-p { color: var(--kp-on-accent); background: var(--kp-accent); border-color: var(--kp-accent); }
.td-btn-p:hover { background: var(--kp-accent-hi); border-color: var(--kp-accent-hi); }
.td-btn-q { min-width: 0; border-color: transparent; background: transparent; color: var(--kp-text-dim); }
.td-btn-q:hover { color: var(--kp-text); background: var(--kp-surface-hi); border-color: var(--kp-border); }

/* ── create ──────────────────────────────────────────────────────────────── */
.td-create {
  display: flex; align-items: center; gap: var(--td-gap);
  padding: 0.625rem 0; border-bottom: 1px solid var(--kp-border);
}
.td-parsed {
  font-family: var(--kp-font-mono); font-size: var(--td-f-meta);
  color: var(--kp-accent); white-space: nowrap;
}
.td-parsed[hidden] { display: none; }

/* ── receipts, notices, the honest failure panel ─────────────────────────── */
.td-status, .td-receipt, .td-note, .td-notice, .td-alert {
  margin: 0.625rem 0 0; font-size: var(--td-f-meta);
}
.td-status { color: var(--kp-text-muted); }
.td-receipt { color: var(--kp-text-dim); }
.td-receipt a { color: var(--kp-accent); text-decoration: underline; text-underline-offset: 2px; }
.td-notice { color: var(--kp-success); }
.td-alert { color: var(--kp-danger); }
.td-chip {
  display: inline-flex; align-items: center; min-height: 1.5rem; padding: 0 0.5rem;
  font-size: var(--td-f-meta); color: var(--kp-warn);
  border: 1px solid var(--kp-border); border-radius: var(--kp-radius);
}
.td-chip:hover { background: var(--kp-warn-bg); text-decoration: none; }
.td-down { margin: 1.5rem 0; padding: 1rem; border: 1px solid var(--kp-danger); border-radius: var(--kp-radius); }
/* An h1 on the refusal page and an h2 in the list's outage block — the size and
   weight are set here so promoting it out of a <p> could not change how it
   draws, only how it is announced. */
.td-down-h { margin: 0; font-size: var(--td-f-sec); font-weight: 600; color: var(--kp-danger); }
.td-down-b { margin: 0.375rem 0 0.75rem; color: var(--kp-text-dim); }
.td-down-a { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0; }

/* ── sections ────────────────────────────────────────────────────────────── */
.td-section { margin-top: 1.5rem; }
/* Sentence case, no tracking. The tiny uppercase tracked eyebrow is a banned
   ornament — it is the single most recognisable tell of generated interface
   chrome, and it shouts a word ("OVERDUE", "DUE") that is not the point of the
   line. Size, weight and colour carry the hierarchy instead. */
.td-sec {
  display: flex; align-items: baseline; gap: 0.375rem;
  margin: 0 0 0.25rem;
  font-size: var(--td-f-body); font-weight: 600;
  color: var(--kp-text-dim);
}
.td-sec-note { margin: 0 0 0.375rem; font-size: var(--td-f-meta); color: var(--kp-text-muted); }
.td-empty { margin: 0.5rem 0; color: var(--kp-text-dim); }
.td-more { margin: 0.5rem 0 0; font-size: var(--td-f-meta); }
.td-more a { color: var(--kp-accent); }
.td-list { list-style: none; margin: 0; padding: 0; }

/* ── row ─────────────────────────────────────────────────────────────────── */
.td-row {
  display: grid;
  /* Seven fixed tracks and one flexible title. The lease slot is ALWAYS
     present, even while empty: a countdown that appears at the fifteen-minute
     mark must not push the row's columns sideways at the moment it appears. */
  grid-template-columns:
    var(--td-w-check) minmax(0, 1fr) var(--td-w-id)
    var(--td-w-blocks) var(--td-w-date) var(--td-w-lease) var(--td-w-own);
  align-items: center;
  column-gap: var(--td-gap);
  min-height: var(--td-row-h);
  padding: 0 0.25rem;
  /* A transparent border, never a coloured side stripe: blocked rows must line
     up with every other row, and a 2px accent edge is a banned ornament. */
  border-left: 1px solid transparent;
  border-bottom: 1px solid var(--kp-rule);
}
/* Deliberately NOT `.td-row > * { grid-row: 1 }`: the checkbox and the owner
   button reach the grid through a `display: contents` form, so a child
   combinator does not see them. Pinning only their siblings left those two as
   the sole auto-placed items and threw them to the end of the row — every
   column was then one slot off. Let row 1 auto-place in DOM order, and pin only
   the second line. */
.td-row:hover { background: var(--kp-surface); }
.td-row:focus-visible { background: var(--kp-surface); outline-offset: -2px; }
.td-c { display: contents; }

.td-check {
  width: 1rem; height: 1rem; padding: 0; cursor: pointer;
  background: transparent;
  border: 1px solid var(--kp-border-strong); border-radius: 3px;
}
.td-check:hover { border-color: var(--kp-accent); }
/* The slot a blocked row keeps instead of a Complete button: the grid must not
   shift between a row that can be finished and one that cannot. */
.td-check-off {
  border-style: dashed; border-color: var(--kp-border); cursor: default;
}
.td-check[aria-pressed="true"] { background: var(--kp-accent); border-color: var(--kp-accent); }
.td-check[aria-pressed="true"] > span::after {
  content: ""; display: block; width: 0.25rem; height: 0.5rem;
  margin: -0.0625rem auto 0; transform: rotate(45deg);
  border: solid var(--kp-on-accent); border-width: 0 1.5px 1.5px 0;
}
/* The short id follows the title and stays quiet: it is a handle you reach for
   once you have found a row, not the first thing on the line. Leading every row
   with a monospaced synthetic key is what made the list read as a table dump. */
.td-id {
  font-family: var(--kp-font-mono); font-size: var(--td-f-meta);
  font-variant-numeric: tabular-nums;
  color: var(--kp-text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.td-id:hover { color: var(--kp-text-dim); }
.td-title {
  font-size: var(--td-f-body); font-weight: 500; color: var(--kp-text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  /* The clip is the layout guarantee; the break is the guarantee for a title
     with no spaces in it at all, which `text-overflow` alone cannot shorten. */
  overflow-wrap: anywhere;
}
.td-row.is-done .td-title { color: var(--kp-text-muted); text-decoration: line-through; }
.td-blocks {
  justify-self: end;
  font-size: var(--td-f-meta); font-variant-numeric: tabular-nums;
  color: var(--kp-warn);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* date slot — a details/summary popover, so it works with JS switched off and
   OVERLAYS rather than pushing the list down when it opens. */
.td-date { position: relative; justify-self: end; }
.td-date-s {
  display: flex; align-items: center; justify-content: flex-end;
  width: var(--td-w-date); min-height: 1.5rem;
  font-size: var(--td-f-meta); font-variant-numeric: tabular-nums;
  color: var(--kp-text-dim); cursor: pointer; list-style: none;
}
.td-date-s::-webkit-details-marker { display: none; }
.td-date-s:hover { color: var(--kp-text); }
.td-date-s.td-d-now { color: var(--kp-accent); }
.td-date-s.td-d-over { color: var(--kp-danger); }
.td-date-s.td-d-none::after { content: "–"; color: var(--kp-text-muted); opacity: 0; }
.td-row:hover .td-d-none::after, .td-date[open] .td-d-none::after,
.td-date-s:focus-visible.td-d-none::after { opacity: 1; }
.td-pop {
  position: absolute; right: 0; top: calc(100% + 0.25rem); z-index: 30;
  min-width: 12rem; padding: 0.5rem;
  background: var(--kp-surface); border: 1px solid var(--kp-border);
  border-radius: var(--kp-radius); box-shadow: var(--kp-shadow);
  text-align: left;
}
/* Same rule as .td-sec: sentence case, no tracking. */
.td-pop-h {
  margin: 0 0 0.375rem; font-size: var(--td-f-meta); font-weight: 600;
  color: var(--kp-text-dim);
}
.td-pop-b, .td-pop-row {
  display: flex; align-items: center; gap: 0.5rem; width: 100%;
  min-height: 1.75rem; padding: 0 0.375rem; margin: 0;
  font: inherit; font-size: var(--td-f-body); text-align: left;
  color: var(--kp-text); background: transparent; border: 0; border-radius: var(--kp-radius);
  cursor: pointer;
}
.td-pop-b:hover { background: var(--kp-surface-hi); }
.td-key {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1rem; font-family: var(--kp-font-mono); font-size: var(--td-f-meta);
  color: var(--kp-text-muted);
}
.td-pop-pick { display: flex; gap: 0.375rem; margin-top: 0.25rem; }
.td-pop-pick .td-input { flex: 1 1 auto; min-width: 0; }
.td-pop-note { margin: 0.375rem 0 0; font-size: var(--td-f-meta); color: var(--kp-text-dim); }
.td-date-new .td-date-s { width: 1.75rem; justify-content: center; }

/* owner slot — human and agent are told apart by SHAPE, not colour, so the
   distinction survives colour blindness and both themes. Absence is the
   design: an unclaimed todo has an EMPTY slot, not an "available" badge. */
.td-own {
  display: flex; align-items: center; justify-content: center;
  width: 1.25rem; height: 1.25rem; padding: 0;
  font-family: var(--kp-font-mono); font-size: 0.625rem;
  color: var(--kp-text-dim); background: var(--kp-surface-hi);
  border: 1px solid var(--kp-border); cursor: default;
}
.td-own.is-disc { border-radius: 50%; }
.td-own.is-sq { border-radius: 5px; }
.td-own.is-mine { cursor: pointer; border-color: var(--kp-border-strong); color: var(--kp-text); }
.td-own.is-mine:hover { border-color: var(--kp-accent); color: var(--kp-accent); }
/* Blocked work has no claim affordance; the slot is held so the grid is stable. */
.td-own-off {
  border-style: dashed; border-radius: 50%;
  background: transparent; color: var(--kp-text-muted); cursor: default;
}
.td-own-free {
  border: 1px dashed var(--kp-border); border-radius: 50%;
  background: transparent; color: var(--kp-text-muted);
  opacity: 0; cursor: pointer;
}
.td-row:hover .td-own-free, .td-own-free:focus-visible { opacity: 1; }
.td-own-free:hover { color: var(--kp-accent); border-color: var(--kp-accent); }
.td-lease {
  justify-self: end;
  font-family: var(--kp-font-mono); font-size: var(--td-f-meta);
  font-variant-numeric: tabular-nums; color: var(--kp-warn);
}

/* one indented second line, only on blocked rows */
/* Two lines at most. One was the brief, but a single clamped line dropped the
   "(blocked)" marker off the end of the last prerequisite — and that marker is
   the difference between "go do that one" and "that one is stuck too". */
.td-wait {
  grid-row: 2; grid-column: 3 / -1;
  margin: 0 0 0.25rem;
  font-size: var(--td-f-meta); color: var(--kp-text-muted);
  overflow: hidden;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
}
.td-wait a { color: var(--kp-text-dim); }
.td-wait .td-id { font-size: var(--td-f-meta); }
.td-wait.is-err { color: var(--kp-danger); }
.td-row.is-blocked .td-title { color: var(--kp-text-dim); }

/* ── detail ──────────────────────────────────────────────────────────────── */
.td-crumb { margin: 0 0 1rem; font-size: var(--td-f-meta); color: var(--kp-text-dim); }
.td-head { margin-bottom: 0.75rem; }
.td-copy { cursor: pointer; }
.td-copied { font-size: var(--td-f-meta); color: var(--kp-success); }
.td-copied[hidden] { display: none; }
/* `overflow-wrap: anywhere` on both, and it is load-bearing rather than
   defensive: a 500-character title is VALID input (it is the create field's own
   maxlength) and a pasted URL is one unbreakable word. Without it the detail
   page measured documentElement.scrollWidth 8484 at a 320px viewport — the
   whole page scrolled sideways, at every viewport, for one long word. */
.td-h1 {
  margin: 0.25rem 0 0; font-size: var(--td-f-title); font-weight: 600;
  overflow-wrap: anywhere; word-break: break-word; min-width: 0;
}
.td-h1.is-done { color: var(--kp-text-muted); text-decoration: line-through; }
.td-state { margin: 0.375rem 0 0; font-size: var(--td-f-body); color: var(--kp-text-dim); overflow-wrap: anywhere; }
.td-acts { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 1rem; }
.td-acts .td-c { display: contents; }
.td-blocked-note {
  margin: 0 0 1rem; font-size: var(--td-f-meta); color: var(--kp-text-dim);
  overflow-wrap: anywhere;
}
.td-when { display: flex; gap: 0.375rem; flex-wrap: wrap; align-items: center; margin: 0 0 0.5rem; }
.td-inline-form { display: flex; gap: 0.375rem; flex-wrap: wrap; align-items: center; }
.td-meta { margin: 0.5rem 0 0; font-size: var(--td-f-meta); color: var(--kp-text-dim); overflow-wrap: anywhere; }
.td-dim { color: var(--kp-text-muted); }
.td-body {
  margin: 0.5rem 0 0; color: var(--kp-text-dim); white-space: pre-wrap;
  overflow-wrap: anywhere; word-break: break-word; min-width: 0;
}
.td-row-dep { grid-template-columns: minmax(0, 1fr) var(--td-w-id) 4rem 5rem; }
.td-dep-state { font-size: var(--td-f-meta); color: var(--kp-text-dim); }
.td-record { list-style: none; margin: 0; padding: 0; }
.td-record li { display: flex; gap: 0.75rem; padding: 0.1875rem 0; font-size: var(--td-f-meta); min-width: 0; }
.td-rec-k { flex: 0 0 auto; min-width: 5rem; color: var(--kp-text-muted); }
/* The full uuid lives here. It must wrap rather than widen the page. */
.td-rec-v {
  color: var(--kp-text-dim); font-variant-numeric: tabular-nums;
  min-width: 0; overflow-wrap: anywhere;
}

/* ── footer + keys ───────────────────────────────────────────────────────── */
.td-foot {
  display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  margin: 2rem 0 0; padding-top: 0.75rem;
  border-top: 1px solid var(--kp-border);
  font-size: var(--td-f-meta); color: var(--kp-text-muted);
}
.td-page kbd {
  font-family: var(--kp-font-mono); font-size: var(--td-f-meta);
  padding: 0 0.25rem; border: 1px solid var(--kp-border); border-radius: 3px;
}
.td-help {
  position: fixed; inset: auto 1rem 4.5rem auto; z-index: 60;
  max-width: 15rem; padding: 0.75rem 1rem;
  background: var(--kp-surface); border: 1px solid var(--kp-border);
  border-radius: var(--kp-radius); box-shadow: var(--kp-shadow-lg);
}
.td-help[hidden] { display: none; }
.td-help-l { list-style: none; margin: 0.5rem 0 0; padding: 0; font-size: var(--td-f-meta); color: var(--kp-text-dim); }
.td-help-l li { padding: 0.125rem 0; }

/* Completion collapses in place; siblings do not jump. */
.td-row.is-going {
  animation: td-collapse 0.15s ease-in forwards;
  overflow: hidden;
}
@keyframes td-collapse {
  to { opacity: 0; min-height: 0; height: 0; padding: 0; border-width: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .td-row.is-going { animation: none; opacity: 0.4; }
}

/* Coarse pointers get real targets without inflating the desk layout. */
@media (pointer: coarse) {
  .td-page { --td-row-h: 2.75rem; }
  .td-seg, .td-btn, .td-date-s { min-height: 2.75rem; }
  .td-own, .td-own-free { width: 1.75rem; height: 1.75rem; }
  .td-own-free { opacity: 1; }
  .td-d-none::after { opacity: 1; }
}

@media (max-width: 34rem) {
  /* `flex-wrap: nowrap` is the load-bearing half. A WRAPPING column flex
     container stretches its items to the flex LINE's cross size, not the
     container's — so the un-shrinkable tab strip set the line width and both
     children grew to 484px inside a 347px column, scrolling the whole phone
     page sideways. With one line, stretch uses the container and the strip
     scrolls inside itself. */
  .td-bar { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
  .td-bar-r { padding-bottom: 0.5rem; min-width: 0; }
  .td-input-q { width: 100%; }
  .td-create { flex-wrap: wrap; }
  /* Four tracks, not seven. On a 390px screen the title is the only thing
     worth the width; the short id and the lease countdown are dropped rather
     than shrunk to illegibility, and both remain on the detail page. The
     column list must change with them — hiding a cell without removing its
     track leaves every later cell one slot to the left. */
  .td-row {
    grid-template-columns:
      var(--td-w-check) minmax(0, 1fr) var(--td-w-date) var(--td-w-own);
  }
  .td-id, .td-lease, .td-blocks, .td-blocks-none { display: none; }
  .td-wait { grid-column: 2 / -1; }
  .td-row-dep { grid-template-columns: minmax(0, 1fr) 4rem 5rem; }
  .td-when, .td-inline-form { width: 100%; }
}

/* ── Page head — the register's masthead, full width ──────────────────────
   Dateline (org · platform register | local date), display greeting, brand
   summary, optional lede (only when apps need a steward — a quiet page gets
   no empty proclamation), mono readout, full-width activity band, and the
   jump-anywhere rule. Labels keep the platform's quiet-mono grammar
   (lowercase, 0.02em) — no uppercase eyebrows. */
/* IMP-2590 v2: vertical rhythm tightened — with the platform-directory
   section gone (nav lives in the footer dock now), the remaining sections
   (greeting, readout, activity, jump-anywhere, your-apps) sit closer, like
   one instrument instead of a longer scroll sized for the old page. */
.page-head { margin-bottom: 26px; }
.page-dateline {
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--kp-border);
  font-family: var(--kp-font-mono); font-size: 10px; letter-spacing: 0.02em;
  text-transform: lowercase; color: var(--kp-text-dim);
}
/* Right half of the dateline: the date, then the discreet surface switch.
   Grouped so .page-dateline keeps exactly two flex children and its
   space-between spacing is unchanged. */
.dateline-right { display: inline-flex; align-items: baseline; gap: 14px; }
.surface-switch {
  font: inherit; letter-spacing: inherit; text-transform: inherit;
  color: var(--kp-text-dim); background: none; border: 0; padding: 0;
  border-bottom: 1px solid var(--kp-border-strong); cursor: pointer;
}
.surface-switch:hover { color: var(--kp-accent); border-bottom-color: var(--kp-accent); }
.surface-switch:focus-visible { outline: 2px solid var(--kp-accent); outline-offset: 3px; }
.surface-switch[disabled] { opacity: 0.5; cursor: progress; }
.page-head h1 {
  margin: 20px 0 0;
  font-family: var(--kp-font-display);
  font-optical-sizing: auto;
  /* IMP-2590 lane treatment: masthead register nudge — the ratified
     artifact's spec was written against `.masthead h1` (~line 91), which is
     dead CSS on this page (no `.masthead`-classed ancestor is rendered; the
     live greeting is `.page-head h1`). Applied here so the treatment is
     actually visible; `.masthead h1` above is mirrored too for hygiene. */
  font-size: 35px; font-weight: 550;
  letter-spacing: -0.02em; line-height: 1.08;
  color: var(--kp-text);
}
.page-head .atlas-summary { margin-top: 8px; max-width: 62ch; }
.page-lede {
  margin: 10px 0 0; max-width: 64ch;
  font-family: var(--kp-font-display);
  font-optical-sizing: auto;
  font-size: 17px; line-height: 1.5;
  color: var(--kp-text-dim);
}
.page-head .masthead-readout { margin-top: 10px; }
.page-head .atlas-command { margin-top: 18px; }

/* The activity band — the page's one graphic at full measure: accent stroke,
   5% fill, lowercase day ticks, totals in the caption. Uniform scaling keeps
   stroke + ticks honest at any width. */
.activity-band { margin: 18px 0 0; }
.activity-band-cap {
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  padding-bottom: 8px;
  font-family: var(--kp-font-mono); font-size: 10px; letter-spacing: 0.02em;
  text-transform: lowercase; color: var(--kp-text-dim);
}
.activity-band-total { font-variant-numeric: tabular-nums; }
.activity-band svg { display: block; width: 100%; height: auto; }
.activity-band-tick {
  font-family: var(--kp-font-mono); font-size: 9px; letter-spacing: 0.02em;
  fill: var(--kp-text-dim);
}

/* ── Metric readouts (masthead) ──────────────────────────────────────────
   One ruled line per metric, same register as .activity-band-cap: mono
   lowercase label, figures right, an inline trace between them. A readout,
   not a card — no border, no fill, no shadow. Costs ~20px of height, which
   is why it can sit in the masthead without crowding the lede. */
.metric-band {
  display: flex; align-items: center; gap: 10px;
  margin-top: 10px; padding-bottom: 7px;
  border-bottom: 1px solid var(--kp-rule);
  font-family: var(--kp-font-mono); font-size: 10px; letter-spacing: 0.02em;
  text-transform: lowercase; color: var(--kp-text-dim);
  text-decoration: none;
}
a.metric-band:hover { color: var(--kp-text); border-bottom-color: var(--kp-border-strong); }
a.metric-band:focus-visible {
  outline: 2px solid var(--kp-accent); outline-offset: 3px; border-radius: var(--kp-radius-sm);
}
/* The label pushes; the trace + figures stay grouped hard right. Pushing
   from the label (rather than margin-left:auto on the trace) keeps that
   group intact in the states where the trace is absent — an outage or a
   flat-zero day — instead of stranding the figure mid-row. */
.metric-band-label { flex-shrink: 0; margin-right: auto; }
/* The trace sits immediately left of the figures it describes — trace then
   number is the reading order; parked next to the label it just orphans. */
.metric-band-spark {
  flex-shrink: 0; width: 120px; height: 18px; display: block; opacity: 0.85;
}
/* Tabular so the number doesn't jitter between refreshes. */
.metric-band-figure { font-variant-numeric: tabular-nums; }
/* No semantic colour on the delta: green already means `live` in this
   palette, and "traffic up" is not a health verdict. The glyph carries
   direction; the figure carries weight. */
.metric-band-delta { flex-shrink: 0; font-variant-numeric: tabular-nums; }
.metric-band-delta.up { color: var(--kp-text); }
.metric-band-delta.down,
.metric-band-delta.flat { color: var(--kp-text-muted); }
/* Unreachable analytics: the row stays, the figure is an em-dash. */
.metric-band-dim .metric-band-figure { color: var(--kp-text-muted); }
/* Overdue obligations are the one figure in this band that IS a verdict —
   traffic direction deliberately carries no colour, but "you are late" does. */
.metric-band-figure-alert { color: var(--kp-danger); }

@media (max-width: 760px) {
  /* The trace is the first thing to go — label + figure still carry it. */
  .metric-band-spark { display: none; }
}

/* ── Needs attention — triage briefs between masthead and directory ──────
   Severity word + app + full reason + corrective action. Ruled rows, no
   container: the content is the alarm, not the chrome. */
.attention-section { margin-bottom: 38px; }
.attention-section .section-heading { margin-top: 0; }
.attention-items { border-top: 1px solid var(--kp-border); }
.attention-item {
  display: grid; grid-template-columns: 30px 1fr; gap: 14px;
  padding: 12px 0;
  border-top: 1px solid var(--kp-border-subtle);
}
.attention-item:first-child { border-top: 0; }
.attention-idx {
  padding-top: 2px;
  font-family: var(--kp-font-mono); font-size: 10.5px;
  font-variant-numeric: tabular-nums; color: var(--kp-text-dim);
}
.attention-t { font-size: 13.5px; font-weight: 600; color: var(--kp-text); }
/* Fixed-width severity column: "failed" (6ch) and "degraded" (8ch) would
   otherwise push app names to different x-positions row over row — the
   status word is metadata, the names are what must align. 8ch at 10px mono
   ≈ 48px + 9px gap. */
.attention-sev {
  display: inline-block; width: 57px; flex-shrink: 0;
  font-family: var(--kp-font-mono); font-size: 10px; font-weight: 500;
  letter-spacing: 0.02em; text-transform: lowercase;
}
.attention-sev.err { color: var(--kp-danger); }
.attention-sev.warn { color: var(--kp-warn); }
.attention-why {
  margin-top: 4px; max-width: 62ch;
  font-size: 12.5px; line-height: 1.55; color: var(--kp-text-dim);
}
.attention-fix {
  display: inline-block; margin-top: 6px;
  font-family: var(--kp-font-mono); font-size: 11px;
  color: var(--kp-accent); text-decoration: none;
}
.attention-fix:hover, .attention-fix:focus-visible { text-decoration: underline; }
.attention-more {
  padding: 10px 0 0 44px;
  border-top: 1px solid var(--kp-border-subtle);
  font-family: var(--kp-font-mono); font-size: 11px; color: var(--kp-text-dim);
}
.attention-more a { color: var(--kp-accent); text-decoration: none; }
.attention-more a:hover, .attention-more a:focus-visible { text-decoration: underline; }

@media (max-width: 720px) {
  .page-head h1 { font-size: 30px; }
  .page-lede { font-size: 15.5px; }
  .activity-band-tick { display: none; }
  .attention-item { grid-template-columns: 24px 1fr; }
  .attention-more { padding-left: 38px; }
}

/* ── Mobile ── */
@media (max-width: 900px) {
  .atlas-layout { grid-template-columns: 1fr; gap: 40px; }
  .atlas-intro { position: static; }
  .atlas-main::before { display: none; }
  .atlas-intro h1 { max-width: 12ch; font-size: 44px; }
  .atlas-summary { max-width: 56ch; }
  .atlas-intro .masthead-spark { margin-top: 24px; }
  .atlas-command { max-width: 420px; }
}
@media (max-width: 720px) {
  .app-index { grid-template-columns: 1fr; }
  .dock { grid-template-columns: 1fr; gap: 16px; }
  main#app { padding: 24px 16px; }
  .org-picker { margin-top: 32px; }
  .masthead h1 { font-size: 25px; }
  .masthead-rule { margin: 14px 0 26px; }
  .setup-rail { flex-wrap: wrap; }
  .setup-next { flex-basis: 100%; order: 5; white-space: normal; }
}
@media (max-width: 600px) {
  .masthead-spark { display: none; }
  .atlas-layout { gap: 32px; }
  .atlas-intro { padding-top: 14px; }
  .atlas-intro h1 { max-width: 9ch; margin-top: 17px; font-size: 38px; }
  .atlas-summary { margin-top: 16px; }
  .atlas-intro .masthead-spark {
    display: flex;
    max-width: 100%;
    margin-top: 22px;
  }
  .atlas-command { margin-top: 22px; }
  .atlas-directory-head { display: none; }
  .atlas-directory-row {
    grid-template-columns: 32px minmax(0, 1fr);
    min-height: 50px;
  }
  .atlas-purpose { display: none; }
  .atlas-tool { font-size: 17px; }
  .atlas-group { display: none; }
  .atlas-ghost-row { grid-template-columns: 32px minmax(0, 1fr) auto; }
  .atlas-empty-action { justify-self: end; }
  .atlas-main > .activity-section { margin-top: 34px; }
  .atlas-main .setup-rail {
    display: grid;
    grid-template-columns: auto auto 1fr auto;
    gap: 10px;
  }
  .atlas-main .setup-segs { grid-column: 1; grid-row: 1; }
  .atlas-main .setup-count { grid-column: 2; grid-row: 1; }
  .atlas-main .onboarding-dismiss {
    grid-column: 4;
    grid-row: 1;
    margin: -6px -6px -6px 0;
  }
  .atlas-main .setup-next {
    grid-column: 1 / -1;
    grid-row: 2;
    order: initial;
    width: 100%;
  }
  .atlas-main .setup-go { grid-column: 1 / 3; grid-row: 3; justify-self: start; }
  .atlas-main .setup-all {
    grid-column: 3 / 5;
    grid-row: 3;
    justify-self: start;
    margin-left: 0 !important;
  }
  .kpc-fab {
    position: absolute !important;
    top: 105px !important;
    right: 16px !important;
    bottom: auto !important;
    width: 44px !important;
    height: 44px !important;
  }
}

/* ── Drops (/drops, IMP-2432) — the dead drop ─────────────────────────────
   Zero-knowledge burn-after-read handoff, rendered as the physical act it
   is: a sealed envelope, a garnet wax seal stamped at the moment of
   encryption, a tear-off claim ticket, and a burn ledger. Two registers
   throughout — human words in --kp-font, machine facts (ids, sizes, TTLs,
   mime types, the key) in --kp-font-mono. Every colour is a vendored token;
   the accent does double duty as the wax. */

.dd-stage { margin-bottom: 38px; }

/* ── the envelope ─────────────────────────────────────────────────────────
   One panel. The flap is two hairlines meeting under the seal; the whole
   surface is the drop target. */
.dd-envelope {
  position: relative;
  background: var(--kp-surface);
  border: 1px solid var(--kp-border);
  border-radius: 3px;
  padding: 72px 24px 22px;
  transition: border-color 180ms ease, box-shadow 180ms ease;
}
.dd-envelope.is-loaded { border-color: var(--kp-border-strong); }
.dd-envelope.is-dragging { border-color: var(--kp-accent); box-shadow: var(--kp-shadow); }

/* The fold. At --kp-border it was invisible against --kp-surface in both
   themes, so the seal read as a lone dot with nothing to seal; -strong is
   still a whisper hairline but the envelope actually reads as one. */
.dd-flap {
  position: absolute; top: 0; left: 0; right: 0; height: 46px;
  color: var(--kp-border-strong); pointer-events: none;
}
.dd-flap svg { display: block; width: 100%; height: 100%; }

/* ── the wax seal ─────────────────────────────────────────────────────────
   Ink and dashed while the envelope is open; garnet and solid the moment it
   is sealed. Not the brand mark — BRAND.md reserves that for identity. */
.dd-seal {
  /* Seated ON the point of the fold, which is where wax goes. */
  position: absolute; top: 42px; left: 50%;
  width: 40px; height: 40px;
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.dd-seal svg { display: block; width: 100%; height: 100%; overflow: visible; }
.dd-seal-rim {
  fill: var(--kp-surface);
  stroke: var(--kp-border-strong); stroke-width: 1; stroke-dasharray: 3 3;
}
.dd-seal-ring, .dd-seal-ticks path {
  fill: none; stroke: var(--kp-border-strong); stroke-width: 1;
}
.dd-seal-core { fill: var(--kp-border-strong); }
.dd-envelope.is-loaded .dd-seal-rim,
.dd-envelope.is-loaded .dd-seal-ring,
.dd-envelope.is-loaded .dd-seal-ticks path { stroke: var(--kp-text-muted); }
.dd-envelope.is-loaded .dd-seal-core { fill: var(--kp-text-muted); }

/* Sealed: the accent IS the wax. */
.dd-envelope.is-sealing .dd-seal-rim,
.dd-seal-stamped .dd-seal-rim {
  fill: var(--kp-accent-bg); stroke: var(--kp-accent); stroke-dasharray: none;
}
.dd-envelope.is-sealing .dd-seal-ring,
.dd-envelope.is-sealing .dd-seal-ticks path,
.dd-seal-stamped .dd-seal-ring,
.dd-seal-stamped .dd-seal-ticks path { stroke: var(--kp-accent); }
.dd-envelope.is-sealing .dd-seal-core,
.dd-seal-stamped .dd-seal-core { fill: var(--kp-accent); }

/* The stamp. 220ms, one press, nothing floaty. Under reduced motion the
   global guard in kapable-theme.css collapses it to the end state — which is
   exactly the intended plain swap; the local guard below states it anyway. */
.dd-seal.is-stamping { animation: dd-stamp 220ms cubic-bezier(0.2, 0.7, 0.2, 1) both; }
@keyframes dd-stamp {
  from { transform: translate(-50%, -50%) scale(1.5); opacity: 0; }
  to   { transform: translate(-50%, -50%) scale(1);   opacity: 1; }
}
/* On the ticket the seal is in normal flow, so it needs its own keyframes —
   reusing the absolute one would fling it across the card. */
.dd-seal-stamped { position: static; transform: none; flex: none; }
.dd-seal-stamped.is-stamping { animation: dd-stamp-flat 220ms cubic-bezier(0.2, 0.7, 0.2, 1) both; }
@keyframes dd-stamp-flat {
  from { transform: scale(1.5); opacity: 0; }
  to   { transform: none;       opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .dd-seal.is-stamping, .dd-seal-stamped.is-stamping { animation: none; }
  .dd-envelope { transition: none; }
}

.dd-envelope-body { position: relative; }

/* ── mode tabs — text and file, both visible, neither hidden in a menu ──── */
.dd-tabs {
  display: flex; gap: 2px;
  border-bottom: 1px solid var(--kp-border-subtle);
  margin-bottom: 16px;
}
.dd-tab {
  appearance: none; background: none; border: none;
  font: inherit; font-size: 13px; line-height: 1;
  padding: 10px 14px; min-height: 34px;
  color: var(--kp-text-muted); cursor: pointer;
  border-radius: 3px 3px 0 0;
}
.dd-tab:hover { color: var(--kp-text); }
.dd-tab.is-on { color: var(--kp-text); box-shadow: inset 0 -2px 0 var(--kp-accent); }

.dd-panel { min-width: 0; }
.dd-text {
  width: 100%;
  font-family: var(--kp-font-mono);
  font-size: 13px;
  min-height: 118px;
  resize: vertical;
}

/* ── the drop zone ──────────────────────────────────────────────────────── */
.dd-drop {
  border: 1px dashed var(--kp-border);
  border-radius: 3px;
  padding: 30px 20px;
  display: flex; flex-direction: column; align-items: center; gap: 9px;
  text-align: center;
}
.dd-drop-line { font-size: 14px; color: var(--kp-text); margin: 0; }
.dd-drop-sub { font-size: 12px; line-height: 1.55; color: var(--kp-text-dim); margin: 0; max-width: 48ch; }
.dd-pick { margin-top: 4px; }

/* The contents slip — what you picked, read back to you, entirely locally. */
.dd-slip {
  display: flex; align-items: center; gap: 14px;
  border: 1px solid var(--kp-border);
  border-radius: 3px;
  background: var(--kp-surface-hi);
  padding: 12px 14px;
}
.dd-slip-thumb {
  width: 44px; height: 44px; flex: none;
  border: 1px solid var(--kp-border); border-radius: 2px;
  background: var(--kp-bg); color: var(--kp-text-muted);
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.dd-slip-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.dd-slip-thumb-glyph svg { width: 20px; height: 20px; }
.dd-slip-facts { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.dd-slip-name {
  font-size: 13px; font-weight: 500; color: var(--kp-text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dd-slip-machine { font-family: var(--kp-font-mono); font-size: 11px; color: var(--kp-text-muted); }
.dd-slip-clear {
  background: none; border: none; cursor: pointer;
  color: var(--kp-text-muted); font-size: 17px; line-height: 1;
  padding: 6px 9px; border-radius: 3px; flex: none;
}
.dd-slip-clear:hover { color: var(--kp-danger); background: var(--kp-danger-bg); }

/* ── label + notes ─────────────────────────────────────────────────────── */
.dd-field { display: flex; flex-direction: column; gap: 6px; margin-top: 20px; min-width: 0; }
.dd-field-label {
  font-family: var(--kp-font-mono); font-size: 11px; font-weight: 500;
  letter-spacing: 0.02em; text-transform: lowercase; color: var(--kp-text-muted);
}
.dd-note { font-size: 12px; line-height: 1.55; color: var(--kp-text-dim); margin: 8px 0 0; }
.dd-panel .dd-note { margin-top: 10px; }

/* ── the dials — TTL and claims as detents, not floating number inputs ─── */
.dd-dials {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 20px;
  margin-top: 22px;
}
.dd-dial { min-width: 0; }
.dd-dial-legend {
  display: block;
  font-family: var(--kp-font-mono); font-size: 11px; font-weight: 500;
  letter-spacing: 0.02em; text-transform: lowercase; color: var(--kp-text-muted);
}
.dd-dial-track {
  position: relative;
  display: flex; width: fit-content; max-width: 100%;
  margin-top: 7px;
  border: 1px solid var(--kp-border); border-radius: 3px;
  overflow: hidden;
}
.dd-dial-input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.dd-dial-stop {
  font-family: var(--kp-font-mono); font-size: 12px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  min-width: 46px; min-height: 38px; padding: 0 12px;
  color: var(--kp-text-muted); cursor: pointer;
  border-left: 1px solid var(--kp-border);
  user-select: none;
}
.dd-dial-stop:first-of-type { border-left: none; }
.dd-dial-stop:hover { color: var(--kp-text); }
.dd-dial-input:checked + .dd-dial-stop {
  color: var(--kp-text);
  background: var(--kp-accent-bg);
  box-shadow: inset 0 -2px 0 var(--kp-accent);
}
.dd-dial-input:focus-visible + .dd-dial-stop { outline: 2px solid var(--kp-accent); outline-offset: -2px; }
.dd-dial-sub { font-size: 12px; line-height: 1.55; color: var(--kp-text-dim); margin: 8px 0 0; }

/* ── the seal row ──────────────────────────────────────────────────────── */
.dd-seal-row {
  display: flex; align-items: center; gap: 16px;
  margin-top: 24px; padding-top: 16px;
  border-top: 1px solid var(--kp-border-subtle);
}
.dd-seal-readout {
  flex: 1; min-width: 0; margin: 0;
  font-family: var(--kp-font-mono); font-size: 11px; color: var(--kp-text-muted);
}
.dd-seal-btn { min-height: 36px; padding-left: 18px; padding-right: 18px; }

/* Drag veil — the whole envelope is the target, so the whole envelope says so. */
.dd-veil {
  position: absolute; inset: 0;
  display: none; align-items: center; justify-content: center;
  border: 1px dashed var(--kp-accent); border-radius: 3px;
  background: color-mix(in oklch, var(--kp-surface) 86%, transparent);
}
.dd-envelope.is-dragging .dd-veil { display: flex; }
.dd-veil-line {
  font-family: var(--kp-font-mono); font-size: 12px; letter-spacing: 0.02em;
  color: var(--kp-accent);
}

/* ── the tear-off claim ticket ────────────────────────────────────────────
   The one physical artifact of the transaction. The fragment key is set
   apart because it is the half that never left this tab. */
.dd-ticket {
  position: relative;
  background: var(--kp-surface);
  border: 1px solid var(--kp-border);
  border-radius: 3px;
  padding: 30px 24px 22px;
}
.dd-perf {
  position: absolute; top: 13px; left: 0; right: 0; height: 1px;
  background-image: repeating-linear-gradient(90deg, var(--kp-border) 0 5px, transparent 5px 11px);
}
.dd-perf::before, .dd-perf::after {
  content: ""; position: absolute; top: -5px;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--kp-bg); border: 1px solid var(--kp-border);
}
.dd-perf::before { left: -6px; }
.dd-perf::after { right: -6px; }

.dd-ticket-head { display: flex; align-items: center; gap: 14px; margin-top: 8px; }
.dd-ticket-title { min-width: 0; }
.dd-ticket-kicker {
  margin: 0;
  font-family: var(--kp-font-mono); font-size: 11px; font-weight: 500;
  letter-spacing: 0.04em; text-transform: lowercase; color: var(--kp-text-muted);
}
.dd-ticket-id {
  margin: 3px 0 0;
  font-family: var(--kp-font-mono); font-size: 12px; color: var(--kp-text-dim);
  overflow-wrap: anywhere;
}
.dd-ticket-link {
  margin-top: 18px;
  border: 1px solid var(--kp-border); border-radius: 3px;
  background: var(--kp-bg);
  padding: 13px 14px;
  font-family: var(--kp-font-mono); font-size: 12.5px; line-height: 1.75;
  overflow-wrap: anywhere;
}
.dd-link-body { color: var(--kp-text-dim); }
.dd-link-key {
  color: var(--kp-accent); background: var(--kp-accent-bg);
  font-weight: 600;
  border-radius: 2px; padding: 1px 3px;
  -webkit-box-decoration-break: clone; box-decoration-break: clone;
}
.dd-key-note {
  margin: 11px 0 0;
  font-size: 12.5px; line-height: 1.6; color: var(--kp-text-dim);
  max-width: 70ch;
}
.dd-key-note strong { color: var(--kp-text); font-weight: 600; }
.dd-ticket-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; }
.dd-ticket-copy { min-height: 36px; }
.dd-facts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 14px 20px;
  margin-top: 22px; padding-top: 16px;
  border-top: 1px solid var(--kp-border-subtle);
}
.dd-fact dt {
  font-family: var(--kp-font-mono); font-size: 11px;
  letter-spacing: 0.02em; text-transform: lowercase; color: var(--kp-text-muted);
}
.dd-fact dd { margin: 4px 0 0; font-family: var(--kp-font-mono); font-size: 12px; color: var(--kp-text); }
.dd-ticket-foot {
  margin: 18px 0 0;
  font-size: 12px; line-height: 1.6; color: var(--kp-text-muted);
  max-width: 74ch;
}

/* ── the burn ledger ──────────────────────────────────────────────────────
   Not a table: a ledger of things that are still sealed, have been opened,
   have burned, or have gone to ash. */
.dd-section-label {
  font-family: var(--kp-font-mono); font-size: 11px; font-weight: 500;
  letter-spacing: 0.02em; text-transform: lowercase; color: var(--kp-text-muted);
  margin: 0 0 4px;
}
.dd-section-sub { font-size: 12px; color: var(--kp-text-dim); margin: 0 0 12px; }
.dd-intro-note { font-size: 13px; line-height: 1.6; color: var(--kp-text-dim); margin: 12px 0 0; }

.dd-rows { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.dd-row {
  position: relative;
  display: flex; align-items: baseline; gap: 14px;
  padding: 12px 4px 12px 12px;
  border-top: 1px solid var(--kp-border-subtle);
  font-size: 13px;
}
.dd-row:last-child { border-bottom: 1px solid var(--kp-border-subtle); }
.dd-row-mark {
  flex: none; align-self: center;
  width: 8px; height: 8px; border-radius: 50%;
  border: 1px solid var(--kp-border-strong); background: transparent;
}
.dd-row-name {
  color: var(--kp-text); font-weight: 500;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dd-row-id { font-family: var(--kp-font-mono); font-size: 11px; color: var(--kp-text-muted); flex: none; }
.dd-row-state {
  font-family: var(--kp-font-mono); font-size: 11px; letter-spacing: 0.02em;
  color: var(--kp-text-muted); min-width: 66px; flex: none;
}
.dd-row-facts {
  font-family: var(--kp-font-mono); font-size: 11px; color: var(--kp-text-muted);
  margin-left: auto; text-align: right; min-width: 0;
}
.dd-row-remove {
  background: none; border: none; cursor: pointer;
  color: var(--kp-text-muted); font-size: 15px; line-height: 1;
  padding: 3px 7px; border-radius: 3px; flex: none;
}
.dd-row-remove:hover { color: var(--kp-danger); background: var(--kp-danger-bg); }

/* sealed — the wax is still whole */
.dd-row.is-sealed .dd-row-mark { background: var(--kp-accent); border-color: var(--kp-accent); }
.dd-row.is-sealed .dd-row-state { color: var(--kp-accent); }
/* opened — an ember: read at least once, not spent */
.dd-row.is-opened .dd-row-mark { background: var(--kp-warn); border-color: var(--kp-warn); }
.dd-row.is-opened .dd-row-state { color: var(--kp-warn); }
.dd-row.is-opened::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: var(--kp-warn); opacity: 0.5;
}
/* burned — a charred edge, and the faintest scorch into the row */
.dd-row.is-burned { background: linear-gradient(90deg, var(--kp-danger-bg), transparent 34%); }
.dd-row.is-burned .dd-row-mark { background: var(--kp-danger); border-color: var(--kp-danger); }
.dd-row.is-burned .dd-row-state { color: var(--kp-danger); }
.dd-row.is-burned::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: var(--kp-danger); opacity: 0.6;
}
/* ash — expired or swept: outline only, nothing left to read */
.dd-row.is-ash .dd-row-mark { background: transparent; border-style: dashed; border-color: var(--kp-text-disabled); }
.dd-row.is-ash .dd-row-name { color: var(--kp-text-muted); font-weight: 400; }
.dd-row.is-ash::before {
  content: ""; position: absolute; left: 0; top: 8px; bottom: 8px;
  border-left: 1px dashed var(--kp-border-strong);
}

.dd-empty {
  font-size: 13px; line-height: 1.6; color: var(--kp-text-dim);
  border: 1px dashed var(--kp-border); border-radius: 3px;
  padding: 18px 20px; margin: 0;
}

@media (max-width: 720px) {
  .dd-envelope { padding: 70px 16px 18px; }
  .dd-ticket { padding: 30px 16px 20px; }
  .dd-seal-row { flex-direction: column; align-items: stretch; gap: 12px; }
  .dd-seal-btn { width: 100%; }
  .dd-dials { gap: 18px; }
  .dd-dial-track { width: 100%; }
  .dd-dial-stop { flex: 1; min-width: 0; padding: 0 4px; }
  .dd-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dd-row { flex-wrap: wrap; row-gap: 6px; padding-right: 0; }
  .dd-row-facts { margin-left: 0; width: 100%; text-align: left; }
  .dd-row-remove { margin-left: auto; }
  .dd-ticket-actions .kp-btn { flex: 1; }
}

/* ── framed by the KapableOS desktop (/appify) ────────────────────────────
   Org hosts serve `Content-Security-Policy: frame-ancestors 'self'`, so being
   framed implies our own origin — each app document's inline head script sets
   html.kx-embedded on that signal, before the first stylesheet, so no chrome
   ever paints. Here the site hides the chrome its sibling surfaces actually
   render (the fleet header, footer dock and its body-mounted panels, the
   assistant launcher/panel, and the wordmark footer)
   and gives back the space each of them reserved. App-owned: never edit the
   vendored kapable-*.css, which vendor sync overwrites. */
html.kx-embedded #kapable-header,
html.kx-embedded .kp-header,
html.kx-embedded #kapable-dock,
html.kx-embedded .lp-dock,
html.kx-embedded .lp-dock-pop,
html.kx-embedded .lp-accent-panel,
html.kx-embedded .kp-chat-container,
html.kx-embedded [data-kpc-launcher],
html.kx-embedded .kpc-panel,
html.kx-embedded .kp-footer { display: none !important; }
/* kapable-dock.css reserves its height on :root and pads the body with it. */
html.kx-embedded { --fleet-header-h: 0px; --lp-dock-h: 0px; }
/* Apps review C02 (2026-09-06): inside a KapableOS window the frame already names the
   organization, so the Apps page's "<org> · platform register · <date>" dateline is
   repeated identity; the title, summary, readouts and toolbar are content and stay. */
html.kx-embedded .page-head .page-dateline { display: none; }
html.kx-embedded .page-head { margin-top: 4px; }
html.kx-embedded body.has-lp-dock { padding-bottom: 0 !important; }
/* The window supplies its own frame, so the page loses the outer breathing room. */
html.kx-embedded main#app { padding-top: 24px; }

/* ── Agent Mail (/agent-mail) — the agent mailbox surface ──────────────────
   Rides the /todos page shell (.td-page / .td), so the type scale, the
   toolbar, the receipts and the refusal blocks are already right. Only the two
   ROW shapes are new: a /todos row is a seven-track grid built around a
   checkbox and a date, and neither exists here.

   Everything below is fixed rem for the same reason /todos is: a reader who has
   raised their browser font size must get a bigger page, not a rescaled one. */

/* ── the inbox row: an address, who answers it, and when it last moved ──── */
.am-row {
  display: grid;
  /* The address takes the slack; the agent name and the time hold their own
     tracks so a long address cannot push the timestamp off the line. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 10rem) 4.5rem;
  align-items: baseline;
  column-gap: var(--td-gap);
  padding: 0.4375rem 0.25rem;
  border-bottom: 1px solid var(--kp-rule);
}
.am-row:hover { background: var(--kp-surface); }
.am-addr {
  grid-column: 1;
  font-size: var(--td-f-body); font-weight: 500; color: var(--kp-text);
  min-width: 0; overflow-wrap: anywhere;
}
.am-agent {
  grid-column: 2;
  font-size: var(--td-f-meta); color: var(--kp-text-dim);
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Times are the machine voice on this page too: mono and tabular, so a column
   of them lines up and a value changing from 9m to 10m moves nothing. */
.am-when {
  grid-column: 3;
  font-family: var(--kp-font-mono); font-size: var(--td-f-meta);
  font-variant-numeric: tabular-nums;
  color: var(--kp-text-muted); text-align: right; white-space: nowrap;
}
/* The subject is the second line of the row, under the address, spanning the
   full width: it is the thing a reader scans after the address, and giving it
   its own track would have squeezed both. */
.am-sub {
  grid-column: 1 / -1;
  margin: 0.125rem 0 0;
  font-size: var(--td-f-meta); color: var(--kp-text-dim);
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.am-desc {
  grid-column: 1 / -1;
  margin: 0.0625rem 0 0;
  font-size: var(--td-f-meta); color: var(--kp-text-muted);
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ── the message row ───────────────────────────────────────────────────── */
.am-mrow {
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr) minmax(0, 12rem) 4.5rem 4.5rem;
  align-items: baseline;
  column-gap: var(--td-gap);
  min-height: var(--td-row-h);
  padding: 0.375rem 0.25rem;
  border-bottom: 1px solid var(--kp-rule);
}
.am-mrow:hover { background: var(--kp-surface); }
/* Direction is a WORD, not an arrow glyph. "received" and "sent" survive a
   screen reader, a low-resolution screen and a font that has no arrows. */
.am-dir { font-size: var(--td-f-meta); color: var(--kp-text-muted); white-space: nowrap; }
.am-dir-out { color: var(--kp-text-dim); }
.am-msub {
  font-size: var(--td-f-body); font-weight: 500; color: var(--kp-text);
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  overflow-wrap: anywhere;
}
.am-sender {
  font-size: var(--td-f-meta); color: var(--kp-text-dim);
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.am-status { font-size: var(--td-f-meta); color: var(--kp-text-muted); white-space: nowrap; }

/* ── the body ──────────────────────────────────────────────────────────────
   A `pre` because the content is TEXT and must stay text: it is mail written by
   whoever emailed the agent. `pre-wrap` keeps the sender's line breaks without
   giving the page a horizontal scrollbar, and `anywhere` handles the tracking
   URL with no spaces in it that would otherwise widen the whole document. */
.am-body {
  margin: 0.5rem 0 0;
  padding: 0.75rem;
  font-family: var(--kp-font-mono);
  font-size: var(--td-f-body);
  line-height: 1.55;
  color: var(--kp-text);
  background: var(--kp-surface);
  border: 1px solid var(--kp-border);
  border-radius: 3px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  word-break: break-word;
  min-width: 0;
  max-height: 40rem;
  overflow-y: auto;
}
/* The sender's HTML, shown as source. Dimmer than the text body, because it is
   evidence rather than the message. */
.am-body-html { color: var(--kp-text-dim); }

/* ── the reply box ─────────────────────────────────────────────────────── */
.am-reply { margin-top: 0.5rem; }
.am-reply-body {
  display: block; width: 100%; min-height: 8rem;
  font-family: var(--kp-font);
  line-height: 1.55;
  resize: vertical;
}

/* ── Agent Mail management ────────────────────────────────────────────────
   Same quiet rule-and-type grammar as the reading side. Management adds
   forms, compact cards, and one table; it does not introduce a second shell. */
.am-manage-nav {
  display: flex; align-items: center; gap: 1rem;
  padding: 0.75rem 0; border-bottom: 1px solid var(--kp-border);
  font-size: var(--td-f-meta);
}
.am-manage-nav a { color: var(--kp-text-dim); }
.am-manage-nav a:hover, .am-manage-nav a.is-on { color: var(--kp-text); text-decoration: none; }
.am-manage-nav a.is-on { font-weight: 600; }
.am-title-row, .am-section-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem;
}
.am-title-row { margin-top: 1.5rem; }
.am-section-head { align-items: center; margin-bottom: 0.375rem; }
.am-section-head .td-sec { margin: 0; }
.am-card-list { border-top: 1px solid var(--kp-rule); }
.am-manage-card {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  min-width: 0; padding: 0.75rem 0.25rem; border-bottom: 1px solid var(--kp-rule);
}
.am-manage-card:hover { background: var(--kp-surface); }
.am-manage-card.is-revoked { opacity: 0.62; }
.am-card-main { min-width: 0; }
.am-card-title { display: block; font-size: var(--td-f-body); font-weight: 600; color: var(--kp-text); overflow-wrap: anywhere; }
.am-card-meta, .am-card-note { margin: 0.1875rem 0 0; font-size: var(--td-f-meta); color: var(--kp-text-muted); overflow-wrap: anywhere; }
.am-card-note { color: var(--kp-text-dim); }
.am-card-actions { display: flex; align-items: center; gap: 0.5rem; flex: 0 0 auto; }
.am-mono { font-family: var(--kp-font-mono); font-variant-numeric: tabular-nums; }
.am-empty-panel { padding: 1rem 0; border-top: 1px solid var(--kp-rule); border-bottom: 1px solid var(--kp-rule); color: var(--kp-text-dim); }
.am-empty-panel p { margin: 0 0 0.375rem; }
.am-empty-panel .td-btn { margin-top: 0.375rem; }
.am-danger { color: var(--kp-danger); border-color: var(--kp-danger); background: transparent; }
.am-danger:hover { color: var(--kp-danger); border-color: var(--kp-danger); background: var(--kp-danger-bg); }

.am-form { max-width: 42rem; margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid var(--kp-border-strong); }
.am-field { display: grid; gap: 0.375rem; margin-bottom: 1rem; }
.am-field > label, .am-fieldset legend { font-size: var(--td-f-meta); font-weight: 600; color: var(--kp-text-dim); }
.am-field > p { margin: 0; font-size: var(--td-f-meta); color: var(--kp-text-muted); }
.am-field textarea { resize: vertical; line-height: 1.5; }
.am-fieldset { display: grid; gap: 0.625rem; margin: 0 0 1rem; padding: 0.75rem; border: 1px solid var(--kp-border); border-radius: var(--kp-radius); }
.am-check, .am-radio { display: flex; align-items: flex-start; gap: 0.5rem; font-size: var(--td-f-body); color: var(--kp-text); }
.am-radio small { display: block; margin-top: 0.125rem; color: var(--kp-text-muted); }
.am-permissions { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: 0.5rem; padding-top: 0.5rem; border-top: 1px solid var(--kp-rule); }
.am-form-actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 1.25rem; }
.am-key-summary { border-top: 1px solid var(--kp-rule); }
.am-key-summary li { display: grid; grid-template-columns: minmax(8rem, 1fr) minmax(10rem, 2fr) auto; gap: 1rem; padding: 0.5rem 0.25rem; border-bottom: 1px solid var(--kp-rule); font-size: var(--td-f-meta); color: var(--kp-text-muted); }
.am-key-summary .is-revoked { opacity: 0.62; }
.am-key-label { color: var(--kp-text); }

.am-dialog { width: min(32rem, calc(100vw - 2rem)); padding: 1.25rem; color: var(--kp-text); background: var(--kp-bg); border: 1px solid var(--kp-border-strong); border-radius: var(--kp-radius); }
.am-dialog::backdrop { background: rgba(0, 0, 0, 0.55); }
.am-dialog form { margin: 0; }
.am-dialog .am-field { margin-top: 1rem; }
.am-secret-panel { max-width: 48rem; padding: 1rem; border: 1px solid var(--kp-border-strong); background: var(--kp-surface); }
.am-secret-copy { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0.5rem; align-items: stretch; }
.am-secret-copy code { padding: 0.75rem; overflow-wrap: anywhere; user-select: all; font-family: var(--kp-font-mono); font-size: var(--td-f-body); color: var(--kp-success); background: var(--kp-bg); border: 1px solid var(--kp-border); }

.am-anomaly { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-top: 1rem; padding: 0.75rem; color: var(--kp-danger); border: 1px solid var(--kp-danger); background: var(--kp-danger-bg); }
.am-anomaly[hidden] { display: none; }
.am-anomaly p { margin: 0.1875rem 0 0; font-size: var(--td-f-meta); color: var(--kp-text-dim); }
.am-audit-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.75rem; margin-top: 1.25rem; }
.am-audit-stats > div { padding: 0.75rem; border-top: 1px solid var(--kp-border-strong); border-bottom: 1px solid var(--kp-rule); }
.am-audit-stats strong { display: block; font-family: var(--kp-font-mono); font-size: 1.25rem; }
.am-audit-stats span { font-size: var(--td-f-meta); color: var(--kp-text-muted); }
.am-audit-filters { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; margin-top: 1rem; }
.am-audit-filters > div { display: flex; gap: 0.375rem; flex-wrap: wrap; }
.am-audit-filters .td-btn.is-on { color: var(--kp-on-accent); background: var(--kp-accent); border-color: var(--kp-accent); }
.am-audit-filters [data-audit-search] { margin-left: auto; width: min(18rem, 100%); }
.am-table-wrap { overflow-x: auto; border-top: 1px solid var(--kp-border-strong); }
.am-audit-table { width: 100%; border-collapse: collapse; font-size: var(--td-f-meta); }
.am-audit-table th, .am-audit-table td { padding: 0.625rem 0.5rem; text-align: left; border-bottom: 1px solid var(--kp-rule); vertical-align: top; }
.am-audit-table th { color: var(--kp-text-muted); font-weight: 600; }
.am-audit-table td { color: var(--kp-text-dim); max-width: 16rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.am-status-pill { display: inline-flex; padding: 0.125rem 0.375rem; border: 1px solid var(--kp-border); border-radius: 99px; color: var(--kp-text-dim); }
.am-status-pill.is-ok { color: var(--kp-success); border-color: var(--kp-success); }
.am-status-pill.is-danger { color: var(--kp-danger); border-color: var(--kp-danger); }
.am-status-pill.is-pending { color: var(--kp-warn); border-color: var(--kp-warn); }

@media (max-width: 720px) {
  /* Below this the five-track message row cannot hold five things. The sender
     and the status move to their own line rather than being truncated to
     nothing — a sender clipped to three characters is not a sender. */
  .am-row { grid-template-columns: minmax(0, 1fr) 4.5rem; }
  .am-agent { grid-column: 1 / -1; grid-row: 2; white-space: normal; }
  .am-when { grid-column: 2; grid-row: 1; }
  .am-mrow { grid-template-columns: minmax(0, 1fr) 4.5rem; }
  .am-msub { grid-column: 1; grid-row: 1; }
  .am-dir, .am-sender, .am-status { grid-column: auto; grid-row: 3; }
  .am-title-row, .am-manage-card { align-items: stretch; flex-direction: column; }
  .am-card-actions { flex-wrap: wrap; }
  .am-form-actions { justify-content: stretch; }
  .am-form-actions .td-btn { flex: 1 1 auto; }
  .am-key-summary li { grid-template-columns: minmax(0, 1fr); gap: 0.25rem; }
  .am-audit-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .am-audit-filters [data-audit-search] { margin-left: 0; }
  .am-audit-table th:nth-child(4), .am-audit-table td:nth-child(4),
  .am-audit-table th:nth-child(5), .am-audit-table td:nth-child(5) { display: none; }
}

/* ── /inbox — human attention over kapable-notify ─────────────────────────
   The page shares /todos' measured shell and fixed rem type scale. Groups are
   render-time runs, not stored rollups (tracker-D15): their stronger left rule
   is the only extra hierarchy needed to make an agent-speed burst read as one
   unit. The `.td` shell above owns width and type tokens for both surfaces. */
.ib-local {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.5rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--kp-rule);
}
.ib-local-home {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--kp-text);
  font-weight: 650;
  text-decoration: none;
}
.ib-badge {
  display: inline-flex;
  min-width: 1.65rem;
  min-height: 1.35rem;
  align-items: center;
  justify-content: center;
  padding: 0.0625rem 0.4rem;
  border-radius: 999px;
  background: var(--kp-accent);
  color: var(--kp-on-accent);
  font: 600 var(--td-f-meta)/1 var(--kp-font-mono);
  font-variant-numeric: tabular-nums;
}
.ib-badge.is-zero {
  min-width: 1.5rem;
  min-height: 0;
  padding: 0;
  border-radius: 0;
  background: transparent;
  color: var(--kp-text-dim);
  font-weight: 400;
}
.ib-badge.is-unknown { background: var(--kp-warn-bg); color: var(--kp-warn); }
.ib-nav { display: flex; align-items: center; gap: 0.25rem; }
.ib-nav a {
  padding: 0.4rem 0.55rem;
  color: var(--kp-text-muted);
  border-radius: var(--kp-radius-sm);
  font-size: var(--td-f-body);
  text-decoration: none;
}
.ib-nav a:hover, .ib-nav a:focus-visible { color: var(--kp-text); background: var(--kp-surface); }
.ib-nav a[aria-current="page"] { color: var(--kp-text); background: var(--kp-surface-hi); }
.ib-title-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
}
.ib-title-row h1 { margin: 0; font-size: var(--td-f-title); line-height: 1.25; }
.ib-summary { margin: 0.35rem 0 0; color: var(--kp-text-muted); font-size: var(--td-f-body); line-height: 1.5; }
.ib-stream { margin-top: 1.25rem; }
.ib-history { margin-top: 2rem; }
.ib-section-title { margin: 0; color: var(--kp-text-muted); font-size: var(--td-f-sec); font-weight: 600; }
.ib-group { margin-top: 1rem; border: 1px solid var(--kp-border); border-radius: var(--kp-radius-sm); overflow: clip; }
.ib-group.is-run { border-left: 3px solid var(--kp-accent); }
.ib-group-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.65rem 0.8rem;
  background: var(--kp-surface);
  border-bottom: 1px solid var(--kp-rule);
}
.ib-group-head h2 { margin: 0; font-size: var(--td-f-sec); font-weight: 650; }
.ib-group-head span { color: var(--kp-text-muted); font: var(--td-f-meta)/1.2 var(--kp-font-mono); }
.ib-list, .ib-receipts { list-style: none; margin: 0; padding: 0; }
.ib-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.8rem;
  padding: 0.8rem;
  border-bottom: 1px solid var(--kp-rule);
  background: var(--kp-bg);
  min-width: 0;
}
.ib-row:last-child { border-bottom: 0; }
.ib-row:hover, .ib-row:focus { background: var(--kp-surface); outline: none; }
.ib-row:focus-visible { box-shadow: inset 3px 0 var(--kp-accent); }
.ib-row.is-read { opacity: 0.68; }
.ib-row-main { min-width: 0; }
.ib-row-title { display: flex; align-items: baseline; gap: 0.45rem; min-width: 0; }
.ib-row-title a, .ib-row-title span:first-child {
  color: var(--kp-text);
  font-size: var(--td-f-body);
  line-height: 1.35;
  overflow-wrap: anywhere;
}
.ib-row:not(.is-read) .ib-row-title a,
.ib-row:not(.is-read) .ib-row-title span:first-child { font-weight: 650; }
.ib-row.is-read .ib-row-title a,
.ib-row.is-read .ib-row-title span:first-child { font-weight: 500; }
.ib-unread { width: 0.45rem; height: 0.45rem; flex: 0 0 auto; border-radius: 50%; background: var(--kp-accent); }
.ib-body { margin: 0.35rem 0 0; color: var(--kp-text-muted); font-size: var(--td-f-body); line-height: 1.5; overflow-wrap: anywhere; }
.ib-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem 0.65rem; margin-top: 0.55rem; color: var(--kp-text-dim); font-size: var(--td-f-meta); }
.ib-chip {
  display: inline-flex;
  max-width: 100%;
  padding: 0.12rem 0.4rem;
  border: 1px solid var(--kp-border-strong);
  border-radius: 999px;
  color: var(--kp-text-muted);
  font-family: var(--kp-font-mono);
  text-decoration: none;
  overflow-wrap: anywhere;
}
.ib-chip:hover, .ib-chip:focus-visible { color: var(--kp-text); border-color: var(--kp-accent); }
.ib-chip.is-unmapped { border-color: var(--kp-warn); color: var(--kp-warn); }
.ib-row-receipt { margin: 0.5rem 0 0; color: var(--kp-warn); font-size: var(--td-f-meta); line-height: 1.45; }
.ib-actions { display: flex; align-items: center; justify-content: flex-end; gap: 0.4rem; align-self: center; }
.ib-read-label { color: var(--kp-text-dim); font-size: var(--td-f-meta); padding: 0 0.35rem; }
.ib-clear, .ib-empty { margin-top: 1rem; padding: 1rem; border: 1px solid var(--kp-border); background: var(--kp-surface); }
.ib-clear h2 { margin: 0 0 0.35rem; font-size: var(--td-f-sec); }
.ib-clear p, .ib-empty { color: var(--kp-text-muted); font-size: var(--td-f-body); line-height: 1.5; }
.ib-empty { display: grid; gap: 0.25rem; }
.ib-empty strong { color: var(--kp-text); }
.ib-empty span { color: var(--kp-text-muted); font-size: var(--td-f-meta); }
.ib-receipts { display: grid; gap: 0.65rem; }
.ib-receipt { padding: 0.8rem; border: 1px solid var(--kp-border); border-left: 3px solid var(--kp-warn); background: var(--kp-surface); min-width: 0; }
.ib-receipt.is-dropped { border-left-color: var(--kp-danger); }
.ib-receipt-head { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: baseline; gap: 0.65rem; }
.ib-receipt-head strong { color: var(--kp-text); font-size: var(--td-f-body); }
.ib-receipt-head span { min-width: 0; color: var(--kp-text-muted); font: var(--td-f-meta)/1.3 var(--kp-font-mono); overflow-wrap: anywhere; }
.ib-receipt-head time { color: var(--kp-text-dim); font-size: var(--td-f-meta); }
.ib-receipt > p { margin: 0.45rem 0 0; color: var(--kp-text-muted); font-size: var(--td-f-body); line-height: 1.45; overflow-wrap: anywhere; }
.ib-receipt .ib-receipt-foot { color: var(--kp-text-dim); font-size: var(--td-f-meta); }
.ib-prefs { border: 1px solid var(--kp-border); border-radius: var(--kp-radius-sm); overflow: clip; }
.ib-pref { display: grid; grid-template-columns: minmax(9rem, 1fr) 6rem 10rem; gap: 0.75rem; align-items: baseline; padding: 0.7rem 0.8rem; border-bottom: 1px solid var(--kp-rule); font-size: var(--td-f-body); }
.ib-pref:last-child { border-bottom: 0; }
.ib-pref-head { color: var(--kp-text-dim); background: var(--kp-surface); font-size: var(--td-f-meta); font-weight: 600; }
.ib-pref-name { color: var(--kp-text); font-weight: 600; }
.ib-pref > span:not(.ib-pref-name) { color: var(--kp-text-muted); }
.ib-pref strong { font-size: var(--td-f-body); }
.ib-pref .is-healthy { color: var(--kp-success); }
.ib-pref .is-repair { color: var(--kp-danger); }
.ib-external { margin-top: 1.5rem; }
.ib-external h2 { margin: 0 0 0.65rem; font-size: var(--td-f-sec); }
.ib-channel-list { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.6rem; }
.ib-channel { display: flex; flex-direction: column; gap: 0.25rem; padding: 0.75rem; border: 1px solid var(--kp-border); background: var(--kp-surface); }
.ib-channel strong { font-size: var(--td-f-body); }
.ib-channel span { color: var(--kp-text-muted); font-size: var(--td-f-meta); line-height: 1.4; }

/* Launchpad-local Inbox tile. The fleet dock badge remains a separately
   owned ui-assets change; this tile keeps the front door visible here. */
.inbox-readout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.2rem 0.8rem;
  align-items: center;
  margin-top: 0.75rem;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--kp-border);
  border-left: 3px solid var(--kp-accent);
  color: var(--kp-text);
  background: var(--kp-surface);
  text-decoration: none;
}
.inbox-readout:hover, .inbox-readout:focus-visible { border-color: var(--kp-accent); outline: none; }
.inbox-readout-label { font-weight: 650; }
.inbox-readout-note { grid-column: 1; color: var(--kp-text-muted); font-size: var(--td-f-body); }
.inbox-readout .ib-badge { grid-column: 2; grid-row: 1 / span 2; }

@media (max-width: 34rem) {
  .ib-local { align-items: flex-start; flex-direction: column; }
  .ib-nav { width: 100%; overflow-x: auto; padding-bottom: 0.1rem; }
  .ib-title-row { align-items: stretch; flex-direction: column; }
  .ib-title-row form, .ib-title-row .td-btn { width: 100%; }
  .ib-row { grid-template-columns: minmax(0, 1fr); }
  .ib-actions { justify-content: flex-start; flex-wrap: wrap; }
  .ib-receipt-head { grid-template-columns: minmax(0, 1fr) auto; }
  .ib-receipt-head strong { grid-column: 1; }
  .ib-receipt-head span { grid-column: 1 / -1; grid-row: 2; }
  .ib-receipt-head time { grid-column: 2; grid-row: 1; }
  .ib-pref { grid-template-columns: minmax(0, 1fr) auto; }
  .ib-pref strong { grid-column: 1 / -1; }
  .ib-channel-list { grid-template-columns: minmax(0, 1fr); }
}

/* ── /todos — the ticket rail ───────────────────────────────────────────────────────────────
   Dispatch board, not a checkbox list. Human words remain in --kp-font;
   identifiers, dates, lease times and counts are the machine register in
   --kp-font-mono. Every colour is a vendored theme token. */
.td-page {
  --td-f-meta: 0.6875rem;
  --td-f-body: 0.8125rem;
  --td-f-sec: 0.9375rem;
  --td-f-title: 1.0625rem;
  --td-gap: 0.625rem;
}
.td { width: min(900px, 100%); }

/* Lanes are stops on one rail. Labels stay human; only counts switch
   register. Garnet is reserved for a ticket actively held by the viewer. */
.td-bar { align-items: flex-end; border-bottom-color: var(--kp-border-strong); }
.td-tabs { gap: 0; }
.td-tab {
  gap: 0.45rem;
  min-height: 2.75rem;
  padding: 0 0.75rem;
  font-family: var(--kp-font);
  border-left: 1px solid var(--kp-border-subtle);
  border-top: 1px solid transparent;
  transition: color 180ms ease, background 180ms ease, border-color 180ms ease;
}
.td-tabs > li:last-child .td-tab { border-right: 1px solid var(--kp-border-subtle); }
.td-tab.is-on { background: var(--kp-surface); border-top-color: var(--kp-border-strong); }
.td-tab.is-on::after { height: 1px; background: var(--kp-text-dim); inset-inline: 0.75rem; }
.td-tab .td-n { font-family: var(--kp-font-mono); }
.td-bar-r { padding-bottom: 0.45rem; }
.td-scope, .td-input { background: var(--kp-surface); }
.td-seg { font-family: var(--kp-font); }

.td-create {
  margin-top: 0.75rem;
  padding: 0.75rem;
  background: var(--kp-surface);
  border: 1px solid var(--kp-border);
  border-radius: var(--kp-radius);
}
.td-create .td-btn-p { color: var(--kp-text); background: transparent; border-color: var(--kp-border-strong); }
.td-create .td-btn-p:hover { color: var(--kp-text); background: var(--kp-surface-hi); border-color: var(--kp-text-dim); }

.td-section { margin-top: 1.75rem; }
.td-sec {
  margin-bottom: 0.5rem;
  font-family: var(--kp-font);
  font-size: var(--td-f-sec);
  font-weight: 600;
  color: var(--kp-text);
}
.td-sec .td-n { font-family: var(--kp-font-mono); font-weight: 400; }
.td-sec-note { margin-top: -0.25rem; margin-bottom: 0.625rem; }

.td-list {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  padding: 0.375rem 0 0.375rem 1rem;
}
.td-list::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  border-left: 1px solid var(--kp-border-strong);
}
.td-row[data-row] {
  position: relative;
  display: block;
  min-height: 0;
  padding: 0;
  border: 0;
  background: transparent;
  transition: opacity 180ms ease, transform 180ms ease;
}
.td-row[data-row]::before {
  content: "";
  position: absolute;
  left: -1rem;
  top: 1.35rem;
  width: 1rem;
  border-top: 1px solid var(--kp-border-strong);
}
.td-row[data-row]:hover { background: transparent; }
.td-row[data-row]:focus-visible { background: transparent; outline: 0; }
.td-row[data-row]:focus-visible .td-ticket { outline: 2px solid var(--kp-accent); outline-offset: 2px; }
.td-ticket {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(11rem, 0.65fr) auto;
  grid-template-areas: "copy hand actions";
  gap: 0.875rem;
  align-items: center;
  min-width: 0;
  padding: 0.875rem 1rem;
  background: var(--kp-surface);
  border: 1px solid var(--kp-border);
  border-radius: var(--kp-radius);
  transition: background 180ms ease, border-color 180ms ease, box-shadow 180ms ease;
}
.td-row[data-row]:hover .td-ticket { background: var(--kp-surface-hi); border-color: var(--kp-border-strong); }
.td-ticket-copy { grid-area: copy; min-width: 0; }
.td-ticket-facts {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  min-width: 0;
  margin: 0 0 0.25rem;
  font-family: var(--kp-font-mono);
  font-size: var(--td-f-meta);
  font-variant-numeric: tabular-nums;
  color: var(--kp-text-muted);
}
.td-ticket-facts > * + * { position: relative; }
.td-ticket-facts > * + *::before { content: "/"; margin-right: 0.625rem; color: var(--kp-border-strong); }
.td-ticket-facts .td-id { display: inline; flex: 0 1 auto; font-size: inherit; }
.td-ticket-date { white-space: nowrap; }
.td-ticket-date.td-d-now { color: var(--kp-text-dim); }
.td-ticket-date.td-d-over { color: var(--kp-danger); font-weight: 600; }
.td-blocks { display: inline; justify-self: auto; font-family: var(--kp-font); font-size: inherit; color: var(--kp-warn); }
.td-title {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  white-space: normal;
  text-overflow: clip;
  font-family: var(--kp-font);
  font-size: var(--td-f-body);
  font-weight: 600;
  line-height: 1.35;
  color: var(--kp-text);
}
.td-title:hover { color: var(--kp-text); }

/* Who has the ticket is a real person/agent label, not a status badge. Shape
   carries the human/agent distinction; only the viewer's own live hand uses
   the garnet accent. */
.td-ticket-hand { grid-area: hand; display: flex; flex-direction: column; gap: 0.4rem; min-width: 0; }
.td-owner-line { display: flex; align-items: center; gap: 0.5rem; min-width: 0; }
.td-own {
  display: inline-flex;
  flex: 0 0 auto;
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  font-family: var(--kp-font-mono);
  font-size: 0.625rem;
  color: var(--kp-text-dim);
  background: var(--kp-bg);
  border: 1px solid var(--kp-border-strong);
  cursor: default;
  opacity: 1;
}
.td-own.is-disc { border-radius: 50%; }
.td-own.is-sq { border-radius: 3px; }
.td-own.is-mine { color: var(--kp-accent); background: var(--kp-accent-bg); border-color: var(--kp-accent); cursor: default; }
.td-owner-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--kp-font);
  font-size: var(--td-f-meta);
  color: var(--kp-text-dim);
}
.td-ticket.is-held-mine { box-shadow: inset 2px 0 0 var(--kp-accent); }
.td-ticket.is-held-mine .td-owner-label { color: var(--kp-accent); }
.td-lease {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  width: min(11rem, 100%);
  font-family: var(--kp-font);
  font-size: var(--td-f-meta);
  color: var(--kp-text-muted);
}
.td-lease-line { display: flex; justify-content: space-between; gap: 0.5rem; }
.td-lease-line time { font-family: var(--kp-font-mono); font-variant-numeric: tabular-nums; color: var(--kp-text-dim); white-space: nowrap; }
.td-lease-track { display: block; width: 100%; height: 2px; overflow: hidden; background: var(--kp-border); }
.td-lease-fill {
  display: block;
  width: var(--td-lease-pct, 0%);
  height: 100%;
  background: var(--kp-border-strong);
  transform-origin: left;
  transition: width 200ms linear;
}
.td-ticket.is-held-mine .td-lease-fill { background: var(--kp-accent); }
.td-ticket.is-held-mine .td-lease-line time { color: var(--kp-accent); }

/* Two visible words, not icon buttons. Release, date, assignment and reopen
   live on the detail page; blocked and spiked tickets expose neither verb. */
.td-ticket-actions { grid-area: actions; display: flex; align-items: center; gap: 0.75rem; justify-content: flex-end; white-space: nowrap; }
.td-ticket-action,
.td-check,
.td-own-free {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  height: auto;
  min-width: 0;
  min-height: 1.875rem;
  padding: 0.25rem 0;
  font-family: var(--kp-font);
  font-size: var(--td-f-meta);
  font-weight: 600;
  color: var(--kp-text-dim);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--kp-border-strong);
  border-radius: 0;
  opacity: 1;
  cursor: pointer;
  transition: color 180ms ease, border-color 180ms ease, background 180ms ease;
}
.td-ticket-action:hover,
.td-check:hover,
.td-own-free:hover { color: var(--kp-text); background: transparent; border-color: var(--kp-text-dim); }
.td-check { color: var(--kp-text); }

/* Dependency queue: the prerequisite strip sits one layer ahead, while the
   blocked ticket itself is indented and stacked behind it. This is the state;
   there is deliberately no "blocked" badge and no inert action placeholder. */
.td-queue {
  position: relative;
  z-index: 0;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.35rem 0.5rem;
  margin: 0 1.25rem -1px 0.75rem;
  padding: 0.5rem 0.75rem 0.625rem;
  font-family: var(--kp-font-mono);
  font-size: var(--td-f-meta);
  line-height: 1.45;
  color: var(--kp-text-dim);
  background: var(--kp-surface-hi);
  border: 1px solid var(--kp-border);
  border-bottom: 0;
  border-radius: var(--kp-radius) var(--kp-radius) 0 0;
}
.td-queue-label { font-family: var(--kp-font); color: var(--kp-text-muted); }
.td-prereq { display: inline-flex; align-items: baseline; gap: 0.3rem; min-width: 0; font-family: var(--kp-font-mono); color: var(--kp-text-dim); }
.td-prereq-title { max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--kp-font); }
.td-prereq .td-id { display: inline; flex: 0 0 auto; font-size: inherit; color: var(--kp-text-dim); }
.td-prereq-nested { color: var(--kp-text-dim); }
.td-chain { color: var(--kp-text-dim); }
.td-wait-progress { margin-left: auto; font-family: var(--kp-font-mono); font-variant-numeric: tabular-nums; color: var(--kp-text-dim); }
.td-queue.is-err { color: var(--kp-danger); }
.td-row.is-blocked .td-ticket {
  width: calc(100% - 1.5rem);
  margin-left: 1.5rem;
  background: var(--kp-bg);
  box-shadow: -5px -5px 0 -1px var(--kp-bg), -5px -5px 0 var(--kp-border-subtle);
}
.td-row.is-blocked .td-title { color: var(--kp-text-dim); }

/* Done is spiked: a neutral pinhole and charred/ash edge, never a success
   badge or a bright celebratory colour. */
.td-row.is-done .td-ticket {
  background: var(--kp-bg);
  border-color: var(--kp-border-subtle);
  border-top: 1px dashed var(--kp-border-strong);
  background-image: linear-gradient(90deg, var(--kp-surface-hi), transparent 58%);
}
.td-row.is-done .td-ticket::after {
  content: "";
  position: absolute;
  top: -0.3rem;
  left: 50%;
  width: 0.5rem;
  height: 0.5rem;
  margin-left: -0.25rem;
  border-radius: 50%;
  background: var(--kp-bg);
  border: 1px solid var(--kp-border-strong);
}
.td-row.is-done .td-title { color: var(--kp-text-muted); font-weight: 500; text-decoration: line-through; text-decoration-thickness: 1px; }
.td-row.is-done .td-ticket-facts { color: var(--kp-text-muted); }

/* Detail reads as the opened ticket: human title/section words, machine state
   and record facts. */
.td-head { padding: 1rem 0; border-top: 1px solid var(--kp-border-strong); border-bottom: 1px solid var(--kp-border); }
.td-state { font-family: var(--kp-font-mono); font-size: var(--td-f-meta); }
.td-acts { margin-top: 0.75rem; }
.td-acts .td-btn-p {
  color: var(--kp-text);
  background: var(--kp-surface);
  border-color: var(--kp-border-strong);
}
.td-acts .td-btn-p:hover {
  color: var(--kp-text);
  background: var(--kp-surface-hi);
  border-color: var(--kp-text-dim);
}
.td-when { padding: 0.75rem 0; border-top: 1px solid var(--kp-border-subtle); border-bottom: 1px solid var(--kp-border-subtle); }
.td-when .td-input, .td-record .td-rec-v, .td-dep-state { font-family: var(--kp-font-mono); }
.td-row-dep { padding: 0.625rem 0.25rem; background: transparent; border-bottom: 1px solid var(--kp-rule); }
.td-row-dep .td-title { display: block; white-space: normal; }
.td-record li { padding-block: 0.3rem; border-bottom: 1px solid var(--kp-border-subtle); }
.td-rec-v { font-family: var(--kp-font-mono); }

@media (max-width: 46rem) {
  .td-ticket { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "copy actions" "hand hand"; }
  .td-ticket-hand { max-width: 18rem; }
}

@media (max-width: 34rem) {
  .td-tabs { flex: 1 1 100%; width: 100%; max-width: 100%; }
  .td-bar-r { align-items: stretch; }
  .td-find { flex: 1 1 auto; min-width: 0; }
  .td-create { padding: 0.625rem; }
  .td-ticket { grid-template-columns: minmax(0, 1fr); grid-template-areas: "copy" "hand" "actions"; gap: 0.625rem; padding: 0.75rem; }
  .td-ticket-actions { justify-content: flex-start; }
  .td-ticket-hand, .td-lease { display: flex; width: 100%; max-width: none; }
  .td-row.is-blocked .td-ticket { width: calc(100% - 0.75rem); margin-left: 0.75rem; }
  .td-queue { margin-left: 0.25rem; margin-right: 0.75rem; }
  .td-prereq-title { max-width: 15ch; }
  .td-wait-progress { width: 100%; margin-left: 0; }
  .td-row-dep { grid-template-columns: minmax(0, 1fr) 4rem; }
  .td-row-dep .td-dep-state { display: none; }
}

@media (pointer: coarse) {
  .td-ticket-action, .td-check, .td-own-free { min-height: 2.75rem; padding-inline: 0.25rem; }
  .td-own { width: 1.75rem; height: 1.75rem; }
}

@media (prefers-reduced-motion: reduce) {
  .td-tab, .td-row[data-row], .td-ticket, .td-ticket-action,
  .td-check, .td-own-free, .td-lease-fill { transition: none; }
}

/* /todos is the desktop window's instrument face: unlike /drops, whose
   envelope keeps 24px of breathing room, the rail begins at y=0. */
html.kx-embedded main#app.td-page { padding-top: 0; }

/* ── org event catalogue ({org}.kapable.ai/events) ───────────────────────────
   The first cut of this page shipped a <table> with class names that only
   LOOKED like this system — td-table, td-sub, td-num, td-mono were never
   defined, so five of nine classes rendered as raw unstyled HTML. That was the
   "cramped" the operator saw. This follows the surface's actual list idiom:
   .td-list plus a grid row, the same shape .td-row uses, because there is no
   other table anywhere on this surface.

   Type and rhythm come from .td-page's own scale (--td-f-*), so this page reads
   at the same size as todos rather than inventing a second scale. */
.ev-head { margin-bottom: 1.25rem; }
.ev-lede {
  max-width: 60ch;
  margin: 0.35rem 0 0;
  font-size: var(--td-f-body);
  color: var(--kp-text-muted);
}

.ev-list { margin-top: 0.5rem; }

.ev-row {
  display: grid;
  /* The event name takes the slack; every other track is sized to its content
     so the columns do not shift between rows. `minmax(0, …)` on the two
     flexible tracks is load-bearing — without it a long dotted event name
     refuses to shrink and pushes the row into horizontal overflow. */
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) 5rem 6.5rem 9rem;
  align-items: baseline;
  column-gap: 1rem;
  min-height: 2.25rem;
  padding: 0.45rem 0.25rem;
  border-bottom: 1px solid var(--kp-rule);
}
.ev-row:hover { background: var(--kp-surface); }

.ev-row-h {
  font-size: var(--td-f-meta);
  color: var(--kp-text-dim);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--kp-border-strong);
}

/* Event names and sources are identifiers, so they get the mono face — and
   `overflow-wrap: anywhere` because a dotted name is one unbreakable word and
   would otherwise be the thing that overflows the row. */
.ev-type {
  font-family: var(--kp-font-mono);
  font-size: var(--td-f-body);
  color: var(--kp-text);
  overflow-wrap: anywhere;
}
.ev-src {
  font-family: var(--kp-font-mono);
  font-size: var(--td-f-meta);
  color: var(--kp-text-muted);
  overflow-wrap: anywhere;
}
/* Tabular figures so counts of different magnitudes line up on the decimal —
   a column of 1722 / 241 / 6 reads as a column, not as ragged text. */
.ev-n {
  font-family: var(--kp-font-mono);
  font-size: var(--td-f-meta);
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: var(--kp-text-muted);
}
.ev-when {
  font-family: var(--kp-font-mono);
  font-size: var(--td-f-meta);
  color: var(--kp-text-dim);
  white-space: nowrap;
}

.ev-note {
  max-width: 60ch;
  margin-top: 1.75rem;
  padding-top: 1rem;
  font-size: var(--td-f-meta);
  color: var(--kp-text-muted);
  border-top: 1px solid var(--kp-border-subtle);
}
.ev-note p { margin: 0 0 0.5rem; }
.ev-note code { font-family: var(--kp-font-mono); color: var(--kp-text); }

/* Narrow: five columns cannot survive a phone, so the row becomes two lines —
   identity on the first, the numbers on the second. The header row is hidden
   rather than reflowed, because a column header floating above a stacked card
   labels nothing. */
@media (max-width: 46rem) {
  .ev-row {
    grid-template-columns: minmax(0, 1fr) auto;
    row-gap: 0.15rem;
    padding-block: 0.6rem;
  }
  .ev-row-h { display: none; }
  .ev-type { grid-column: 1; }
  .ev-n { grid-column: 2; grid-row: 1; }
  .ev-src { grid-column: 1; }
  /* Both dates share the second line's right cell; the first-seen date is the
     one a reader can lose, so it keeps its own slot rather than being dropped. */
  .ev-when { grid-column: 2; text-align: right; }
}

/* ── Apps create wizard + provisioning register (IMP-3054 slice 3) ──────── */
.app-create-page { max-width: 68rem; }
.app-create-head { margin-bottom: 1.5rem; }
.app-create-back,
.app-create-leave {
  display: inline-flex;
  color: var(--kp-text-muted);
  font: 600 0.72rem/1 var(--kp-font-mono);
  letter-spacing: 0.035em;
  text-decoration: none;
}
.app-create-back { margin-bottom: 1.4rem; }
.app-create-back:hover,
.app-create-leave:hover { color: var(--kp-accent); }

.app-create-form {
  display: grid;
  gap: 1rem;
  padding-top: 0.25rem;
}
.app-create-name-block,
.app-create-repository {
  display: grid;
  grid-template-columns: 2.3rem minmax(0, 1fr);
  gap: 0.8rem;
  align-items: start;
  padding: 1rem 0;
  border-top: 1px solid var(--kp-border-strong);
  border-bottom: 1px solid var(--kp-rule);
}
.app-create-section-ref {
  padding-top: 0.2rem;
  color: var(--kp-text-dim);
  font: 600 0.68rem/1 var(--kp-font-mono);
  letter-spacing: 0.08em;
}
.app-create-field { display: grid; gap: 0.45rem; max-width: 35rem; }
.app-create-field label {
  color: var(--kp-text);
  font-size: 0.82rem;
  font-weight: 700;
}
.app-create-name { min-height: 2.8rem; font-family: var(--kp-font-mono); font-size: 0.9rem; }
.app-create-hint,
.app-create-submit-note,
.app-create-org-note {
  color: var(--kp-text-dim);
  font: 0.68rem/1.55 var(--kp-font-mono);
}
.app-create-field-error {
  margin: 0;
  color: var(--kp-danger);
  font: 600 0.72rem/1.4 var(--kp-font-mono);
}
.app-create-field-error[hidden],
.app-create-form-error[hidden] { display: none; }

.app-create-choices { display: grid; gap: 1.4rem; }
.app-create-section {
  padding: 0.9rem 0 1.15rem;
  border-top: 1px solid var(--kp-border-strong);
  border-bottom: 1px solid var(--kp-rule);
}
.app-create-section-head {
  display: grid;
  grid-template-columns: 2.3rem minmax(0, 1fr);
  gap: 0.8rem;
  margin-bottom: 0.9rem;
}
.app-create-section-head h2 {
  margin: 0;
  color: var(--kp-text);
  font: 700 0.9rem/1.2 var(--kp-font);
}
.app-create-section-head p {
  max-width: 62ch;
  margin: 0.25rem 0 0;
  color: var(--kp-text-muted);
  font-size: 0.75rem;
  line-height: 1.5;
}
.app-create-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.65rem;
  padding-left: 3.1rem;
}
.app-create-choice {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-rows: auto auto 1fr auto;
  column-gap: 0.65rem;
  min-height: 10.5rem;
  padding: 0.9rem;
  overflow: hidden;
  cursor: pointer;
  border: 1px solid var(--kp-border);
  border-radius: 3px;
  background: color-mix(in srgb, var(--kp-surface) 72%, transparent);
  transition: border-color 140ms ease, background 140ms ease, transform 140ms ease;
}
.app-create-choice:hover {
  border-color: var(--kp-border-strong);
  background: var(--kp-surface-hi);
  transform: translateY(-1px);
}
.app-create-choice.selected {
  border-color: var(--kp-accent);
  box-shadow: inset 0 0 0 1px var(--kp-accent);
  background: color-mix(in srgb, var(--kp-accent) 7%, var(--kp-surface));
}
.app-create-choice:focus-within { outline: 2px solid var(--kp-accent); outline-offset: 2px; }
.app-create-choice input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}
.app-create-choice-mark {
  position: absolute;
  top: 0.65rem;
  right: 0.65rem;
  display: grid;
  place-items: center;
  width: 1.2rem;
  height: 1.2rem;
  opacity: 0;
  color: var(--kp-surface);
  font-size: 0.7rem;
  border-radius: 50%;
  background: var(--kp-accent);
}
.app-create-choice.selected .app-create-choice-mark { opacity: 1; }
.app-create-choice-icon {
  grid-row: 1 / span 2;
  display: grid;
  place-items: center;
  width: 2.2rem;
  height: 2.2rem;
  color: var(--kp-text);
  font-size: 1.1rem;
  border: 1px solid var(--kp-border);
  border-radius: 2px;
  background: var(--kp-surface-hi);
}
.app-create-choice-name {
  align-self: end;
  padding-right: 1.2rem;
  color: var(--kp-text);
  font-size: 0.78rem;
  font-weight: 700;
}
.app-create-choice-stack {
  align-self: start;
  color: var(--kp-text-dim);
  font: 0.62rem/1.4 var(--kp-font-mono);
}
.app-create-choice-copy {
  grid-column: 1 / -1;
  margin-top: 0.8rem;
  color: var(--kp-text-muted);
  font-size: 0.7rem;
  line-height: 1.5;
}
.app-create-tags {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  align-self: end;
  margin-top: 0.8rem;
}
.app-create-tag,
.app-create-fixed {
  padding: 0.16rem 0.36rem;
  color: var(--kp-text-dim);
  font: 0.58rem/1.2 var(--kp-font-mono);
  border: 1px solid var(--kp-border);
  border-radius: 2px;
  background: var(--kp-surface);
}

.app-create-repository {
  grid-template-columns: 2.3rem auto minmax(0, 1fr) auto;
  align-items: center;
}
.app-create-repo-mark {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  color: var(--kp-accent);
  font: 700 0.62rem/1 var(--kp-font-mono);
  border: 1px solid var(--kp-border-strong);
  border-radius: 50%;
}
.app-create-repository strong { display: block; color: var(--kp-text); font-size: 0.78rem; }
.app-create-repository small { display: block; margin-top: 0.2rem; color: var(--kp-text-muted); font-size: 0.7rem; line-height: 1.4; }
.app-create-form-error {
  padding: 0.7rem 0.85rem;
  color: var(--kp-danger);
  font: 600 0.74rem/1.45 var(--kp-font-mono);
  border-left: 2px solid var(--kp-danger);
  background: var(--kp-danger-bg);
}
.app-create-submit-row { display: flex; align-items: center; gap: 0.8rem; }
.app-create-submit { min-height: 2.7rem; padding-inline: 1.1rem; }
.app-create-submit:disabled { opacity: 0.55; cursor: wait; }
.app-create-org-note { margin: 1.2rem 0 0 3.1rem; }
.app-create-loading { padding-left: 3.1rem; }

.app-create-progress,
.app-create-terminal {
  max-width: 43rem;
  padding: 1.35rem;
  border: 1px solid var(--kp-border-strong);
  border-radius: 3px;
  background: color-mix(in srgb, var(--kp-surface) 82%, transparent);
  box-shadow: var(--kp-shadow);
}
.app-create-progress-top { display: flex; align-items: center; gap: 0.9rem; }
.app-create-progress-top h2,
.app-create-terminal h2 { margin: 0; color: var(--kp-text); font-size: 1rem; }
.app-create-progress-top p { margin: 0.25rem 0 0; color: var(--kp-text-muted); font: 0.68rem/1.4 var(--kp-font-mono); }
.app-create-spinner {
  width: 2.3rem;
  height: 2.3rem;
  flex: 0 0 auto;
  border: 2px solid var(--kp-border-strong);
  border-top-color: var(--kp-accent);
  border-radius: 50%;
  animation: app-create-spin 900ms linear infinite;
}
@keyframes app-create-spin { to { transform: rotate(360deg); } }
.app-create-progress-track {
  display: block;
  height: 3px;
  margin: 1.25rem 0;
  overflow: hidden;
  background: var(--kp-border);
}
.app-create-progress-fill {
  display: block;
  width: 12%;
  height: 100%;
  background: var(--kp-accent);
  transition: width 700ms ease;
}
.app-create-steps { display: grid; gap: 0.35rem; }
.app-create-step {
  display: grid;
  grid-template-columns: 1.3rem minmax(0, 1fr);
  gap: 0.55rem;
  align-items: center;
  min-height: 3.4rem;
  padding: 0.55rem 0.65rem;
  color: var(--kp-text-dim);
  border-left: 1px solid var(--kp-rule);
}
.app-create-step.active { color: var(--kp-text); border-color: var(--kp-accent); background: var(--kp-surface-hi); }
.app-create-step.done { color: var(--kp-text-muted); }
.app-create-step-dot { color: var(--kp-accent); font: 700 1rem/1 var(--kp-font-mono); text-align: center; }
.app-create-step strong { display: block; font-size: 0.74rem; }
.app-create-step small { display: block; margin-top: 0.12rem; color: var(--kp-text-dim); font-size: 0.66rem; }
.app-create-progress-foot {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1rem;
  padding-top: 0.7rem;
  color: var(--kp-text-dim);
  font: 0.64rem/1.4 var(--kp-font-mono);
  border-top: 1px solid var(--kp-rule);
}
.app-create-poll-receipt { margin: 0; }
.app-create-leave { margin-top: 1rem; }

.app-create-terminal { display: grid; justify-items: start; gap: 0.8rem; }
.app-create-terminal-icon {
  display: grid;
  place-items: center;
  width: 2.8rem;
  height: 2.8rem;
  color: var(--kp-success);
  font-size: 1.35rem;
  border: 1px solid currentColor;
  border-radius: 50%;
  background: color-mix(in srgb, var(--kp-success) 8%, transparent);
}
.app-create-terminal.failed .app-create-terminal-icon { color: var(--kp-danger); background: var(--kp-danger-bg); }
.app-create-terminal-copy { margin: 0; color: var(--kp-text-muted); font-size: 0.78rem; line-height: 1.55; }
.app-create-server-message {
  width: 100%;
  padding: 0.75rem 0.85rem;
  color: var(--kp-text);
  font: 0.72rem/1.5 var(--kp-font-mono);
  border-left: 2px solid var(--kp-danger);
  background: var(--kp-danger-bg);
  overflow-wrap: anywhere;
}
.app-create-terminal-actions { display: flex; flex-wrap: wrap; gap: 0.55rem; margin-top: 0.25rem; }

@media (max-width: 52rem) {
  .app-create-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 38rem) {
  .app-create-grid { grid-template-columns: 1fr; padding-left: 0; }
  .app-create-section-head,
  .app-create-name-block { grid-template-columns: 1.8rem minmax(0, 1fr); }
  .app-create-repository { grid-template-columns: 1.8rem auto minmax(0, 1fr); }
  .app-create-repository .app-create-fixed { grid-column: 3; justify-self: start; }
  .app-create-submit-row,
  .app-create-progress-foot { align-items: flex-start; flex-direction: column; }
  .app-create-submit { width: 100%; }
  .app-create-org-note { margin-left: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .app-create-choice,
  .app-create-progress-fill { transition: none; }
  .app-create-spinner { animation-duration: 2s; }
}

/* ── Colleagues ───────────────────────────────────────────────────────────
   The registry reuses the quiet Agent Mail/Todos shell. These rules add only
   the directory facts and policy-form layout; all colour comes from the fleet
   theme tokens above. */
.co-title-row { margin-bottom: 0.25rem; }
.co-person-grid,
.co-runner-list,
.co-route-list,
.co-trigger-list,
.co-run-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.co-person-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  border-top: 1px solid var(--kp-rule);
}
.co-person {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  min-width: 0;
  padding: 0.75rem 0.25rem;
  border-bottom: 1px solid var(--kp-rule);
}
.co-person-avatar {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  flex: 0 0 auto;
  color: var(--kp-accent);
  border: 1px solid var(--kp-border);
  border-radius: 50%;
}
.co-person strong,
.co-person small { display: block; overflow-wrap: anywhere; }
.co-person small { margin-top: 0.125rem; color: var(--kp-text-muted); font-size: var(--td-f-meta); }
.co-colleague-card { justify-content: flex-start; }
.co-colleague-card .am-card-main { flex: 1 1 auto; }
/* Apps review C08 (2026-09-06): the title is the card's only link, so on a phone it is the
   full-height target of its row rather than a 19 px line. */
@media (max-width: 600px), (pointer: coarse) {
  .co-colleague-card .am-card-title { display: flex; align-items: center; min-height: 44px; }
  .co-colleague-card .am-card-meta { margin-top: -0.25rem; }
}
.co-agent-emoji { width: 2rem; flex: 0 0 auto; font-size: 1.4rem; text-align: center; }
.co-tags { display: flex; align-items: center; flex-wrap: wrap; gap: 0.375rem; }
.co-tag {
  display: inline-flex;
  align-items: center;
  min-height: 1.4rem;
  padding: 0 0.4rem;
  color: var(--kp-text-dim);
  font: var(--td-f-meta)/1 var(--kp-font-mono);
  border: 1px solid var(--kp-border);
  border-radius: 99px;
}
.co-tag-warn { color: var(--kp-warn); border-color: var(--kp-warn); }
.co-conductor-empty { margin-bottom: 0.75rem; }
.co-runner-list { border-top: 1px solid var(--kp-rule); }
.co-runner { position: relative; padding: 0.875rem 0.25rem; border-bottom: 1px solid var(--kp-rule); }
.co-runner-head { display: flex; align-items: center; gap: 0.5rem; padding-right: 5rem; }
.co-runner-facts { display: grid; grid-template-columns: repeat(4, minmax(7rem, 1fr)); gap: 0.75rem; margin: 0.625rem 0; }
.co-runner-facts div { min-width: 0; }
.co-runner-facts dt { color: var(--kp-text-muted); font-size: var(--td-f-meta); }
.co-runner-facts dd { margin: 0.125rem 0 0; color: var(--kp-text-dim); font-size: var(--td-f-body); overflow-wrap: anywhere; }
.co-health-dot { display: inline-block; width: 0.5rem; height: 0.5rem; margin-right: 0.375rem; border-radius: 50%; background: var(--kp-text-muted); }
.co-health-dot.is-up { background: var(--kp-success); }
.co-health-dot.is-stale { background: var(--kp-warn); }
.co-health-dot.is-down { background: var(--kp-danger); }
.co-delete-form { position: absolute; top: 0.75rem; right: 0; }
.co-add-runner { padding-top: 0.25rem; border-top: 1px solid var(--kp-border-strong); }
.co-form { display: grid; gap: 1rem; max-width: 52rem; margin-top: 0.75rem; }
.co-form > label,
.co-route-grid > label { display: grid; gap: 0.375rem; color: var(--kp-text-dim); font-size: var(--td-f-meta); font-weight: 600; }
.co-form small { color: var(--kp-text-muted); font-weight: 400; }
.co-form input:not([type="checkbox"]):not([type="radio"]),
.co-form select,
.co-form textarea {
  width: 100%;
  min-height: 2rem;
  padding: 0.4rem 0.5rem;
  color: var(--kp-text);
  background: var(--kp-surface);
  border: 1px solid var(--kp-border);
  border-radius: var(--kp-radius);
  font: inherit;
}
.co-form textarea { resize: vertical; line-height: 1.55; }
.co-form input:focus-visible,
.co-form select:focus-visible,
.co-form textarea:focus-visible { border-color: var(--kp-accent); }
.co-form input:disabled,
.co-form select:disabled,
.co-form textarea:disabled { color: var(--kp-text-disabled); background: var(--kp-bg); cursor: not-allowed; }
.co-form fieldset { margin: 0; padding: 0.75rem; border: 1px solid var(--kp-border); border-radius: var(--kp-radius); }
.co-form legend { padding: 0 0.25rem; color: var(--kp-text-dim); font-size: var(--td-f-meta); font-weight: 600; }
.co-runner-form { grid-template-columns: repeat(4, minmax(0, 1fr)); align-items: end; }
.co-runner-form .td-btn { justify-self: start; }
.co-profile-head { display: flex; align-items: center; gap: 0.875rem; margin-top: 1rem; }
.co-profile-head > div:nth-child(2) { min-width: 0; flex: 1 1 auto; }
.co-profile-head .td-h1,
.co-profile-head .td-state { margin: 0; }
.co-profile-emoji { width: 2.75rem; flex: 0 0 auto; font-size: 2rem; text-align: center; }
.co-tabbar { margin-top: 1rem; }
#transcript-turns { scroll-margin-top: calc(var(--fleet-header-h, 44px) + 1rem); }
.co-readonly-caption { padding-left: 0.625rem; border-left: 2px solid var(--kp-border-strong); }
.co-charter-readonly {
  min-height: 5rem;
  margin-top: 0.5rem;
  padding: 0.75rem;
  color: var(--kp-text);
  background: var(--kp-surface);
  border: 1px solid var(--kp-border);
  border-radius: var(--kp-radius);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.co-wake-form { margin-top: 0.75rem; }
.co-trigger-list,
.co-run-list { border-top: 1px solid var(--kp-rule); }
.co-trigger { padding: 0.875rem 0.25rem; border-bottom: 1px solid var(--kp-rule); color: var(--kp-text-dim); }
.co-trigger strong { color: var(--kp-text); }
.co-run { padding: 1rem 0.25rem; border-bottom: 1px solid var(--kp-rule); }
.co-run-head { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }
.co-run-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 0.75rem; }
.co-stop-form { margin: 0; }
.co-run-status {
  display: inline-flex;
  align-items: center;
  min-height: 1.4rem;
  padding: 0 0.45rem;
  color: var(--kp-text-dim);
  background: var(--kp-surface);
  border: 1px solid var(--kp-border);
  border-radius: 99px;
  font: var(--td-f-meta)/1 var(--kp-font-mono);
}
.co-run-status.is-offered,
.co-run-status.is-claimed,
.co-run-status.is-running { color: var(--kp-accent); border-color: var(--kp-accent); background: var(--kp-accent-bg); }
.co-run-status.is-awaiting-approval { color: var(--kp-warn); border-color: var(--kp-warn); background: var(--kp-warn-bg); }
.co-run-status.is-done { color: var(--kp-success); border-color: var(--kp-success); background: var(--kp-success-bg); }
.co-run-status.is-failed,
.co-run-status.is-stopped,
.co-run-status.is-unrunnable { color: var(--kp-danger); border-color: var(--kp-danger); background: var(--kp-danger-bg); }
.co-run-status.is-fallback { color: var(--kp-warn); border-color: var(--kp-warn); background: var(--kp-warn-bg); }
.co-run-status.is-skipped,
.co-run-status.is-unknown { color: var(--kp-text-muted); border-color: var(--kp-border); }
.co-run-route { margin: 0.4rem 0 0; color: var(--kp-text-dim); font: var(--td-f-meta)/1.45 var(--kp-font-mono); overflow-wrap: anywhere; }
.co-run-facts { display: grid; grid-template-columns: repeat(4, minmax(7rem, 1fr)); gap: 0.75rem; margin: 0.75rem 0; }
.co-run-facts div { min-width: 0; }
.co-run-facts dt { color: var(--kp-text-muted); font-size: var(--td-f-meta); }
.co-run-facts dd { margin: 0.125rem 0 0; color: var(--kp-text-dim); overflow-wrap: anywhere; }
.co-run-reason { margin: 0.75rem 0 0; color: var(--kp-text); overflow-wrap: anywhere; }
.co-run-approval { display: grid; gap: 0.2rem; margin-top: 0.625rem; color: var(--kp-text-dim); font-size: var(--td-f-meta); }
.co-run-approval p { margin: 0; overflow-wrap: anywhere; }
.co-run-stopped { display: grid; gap: 0.2rem; margin-top: 0.625rem; color: var(--kp-text-dim); font-size: var(--td-f-meta); }
.co-run-stopped p { margin: 0; overflow-wrap: anywhere; }
.co-run-approval-decision { color: var(--kp-text); font-weight: 600; }
.co-run-session { margin: 0.625rem 0 0; color: var(--kp-text-dim); }
.co-run-history { margin-top: 0.75rem; color: var(--kp-text-dim); }
.co-run-history summary { width: fit-content; cursor: pointer; color: var(--kp-accent); }
.co-run-history ol { display: grid; gap: 0.5rem; margin: 0.625rem 0 0; padding-left: 1.5rem; }
.co-run-history li { padding-left: 0.25rem; overflow-wrap: anywhere; }
.co-run-history li span { display: block; margin-top: 0.125rem; color: var(--kp-text-muted); }
.co-check-grid { display: flex; flex-wrap: wrap; gap: 0.625rem 1rem; }
.co-check { display: inline-flex; align-items: center; gap: 0.375rem; color: var(--kp-text); font-size: var(--td-f-body); font-weight: 400; }
.co-radio-row { display: flex; flex-wrap: wrap; gap: 1rem; }
.co-autonomy-list { display: grid; gap: 0.625rem; }
.co-subhead { margin: 0; color: var(--kp-text-dim); font-size: var(--td-f-body); }
.co-route-list { display: grid; gap: 0.75rem; }
.co-route { padding: 0.875rem; border: 1px solid var(--kp-border); border-radius: var(--kp-radius); background: var(--kp-surface); }
.co-route-head { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; margin-bottom: 0.75rem; }
.co-route-actions { display: flex; flex-wrap: wrap; gap: 0.25rem; }
.co-route-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem; }
.co-form-message { padding: 0.625rem 0.75rem; border-left: 2px solid var(--kp-danger); background: var(--kp-danger-bg); overflow-wrap: anywhere; }

@media (max-width: 720px) {
  .co-runner-facts,
  .co-run-facts,
  .co-runner-form,
  .co-route-grid { grid-template-columns: 1fr; }
  .co-profile-head { align-items: flex-start; flex-wrap: wrap; }
  .co-profile-head .co-tags { width: 100%; padding-left: 3.625rem; }
  .co-route-head { align-items: flex-start; flex-direction: column; }
}
