/*
 * Component layer — one block per component, BEM-style class names matching the
 * mockup vocabulary. Styles only; behaviour lives in the TS components. Every
 * value references a token from tokens.css.
 */

/* --- Button --- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 30px;
  padding: 0 var(--space-3);
  border: var(--border) solid var(--ink);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
  font-size: var(--type-ui-compact);
  font-weight: 500;
  white-space: nowrap; /* a button label never wraps/clips (Atomo Issue 26) */
}
.btn:hover { background: var(--surface-3); }
.btn--solid { background: var(--ink); color: var(--on-ink); }
.btn--solid:hover { background: var(--ink-hover); }
.btn--ghost { border-color: transparent; background: transparent; }
.btn--ghost:hover { background: var(--surface-3); }
.btn--danger { border-color: var(--accent-red); color: var(--accent-red); background: transparent; }
.btn--danger:hover { background: var(--accent-red); color: var(--on-ink); }

/* --- Toasts --- */
.toasts { position: fixed; bottom: 20px; right: 20px; display: flex; flex-direction: column; gap: var(--space-2); z-index: 200; }
.toast { min-width: 220px; max-width: 360px; padding: 11px 14px; border-radius: var(--radius); background: var(--ink); color: var(--on-ink); font-size: var(--type-ui-compact); box-shadow: var(--shadow-toast); opacity: 0; transform: translateY(8px); transition: opacity .2s, transform .2s; }
.toast--in { opacity: 1; transform: translateY(0); }
.toast--success { background: var(--accent-green); }
.toast--error { background: var(--accent-red); }
.toast--info { background: var(--ink); }
.toast__action { margin-left: var(--space-3); background: none; border: 0; color: inherit; font: inherit; font-weight: 600; text-decoration: underline; cursor: pointer; padding: 0; flex-shrink: 0; }
.toast { display: flex; align-items: center; }
/* Ato's "sorry" pose on error toasts: a white chip keeps the ink sprite ink-on-white
   over the red background (spec: documents/ato-mascot.md — 3px cells, pixelated).
   Uses --on-image (the genuinely theme-stable light token, never per-theme overridden)
   rather than --on-ink, which flips near-black on Ink and would swallow the dark sprite. */
.toast__sprite { flex-shrink: 0; display: grid; place-items: center; width: 38px; height: 38px; margin-right: var(--space-3); background: var(--on-image); border-radius: var(--radius); }
.toast__sprite img { width: 30px; height: 27px; image-rendering: pixelated; display: block; }

/* Agent activity pill (bottom-left, opposite the toasts): one calm signal that coalesces
   an agent's burst of changes instead of strobing the workspace with simultaneous highlights. */
.agent-activity { position: fixed; left: 20px; bottom: 20px; z-index: 150; max-width: 280px;
  background: var(--surface); color: var(--ink); border: var(--border) solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow-modal); padding: 10px 12px;
  font-size: var(--type-ui-compact); animation: a-pop .18s ease; }
.agent-activity__head { display: flex; align-items: center; gap: var(--space-2); }
.agent-activity__spark { color: var(--ink); flex-shrink: 0; }
.agent-activity__text { flex: 1; min-width: 0; color: var(--ink-soft); }
.agent-activity__text strong { color: var(--ink); font-weight: 600; }
.agent-activity__x { flex-shrink: 0; border: 0; background: none; color: var(--muted); cursor: pointer; font-size: 12px; line-height: 1; padding: 0 2px; }
.agent-activity__x:hover { color: var(--ink); }
.agent-activity__dots { flex-shrink: 0; width: 6px; height: 6px; border-radius: 50%; background: var(--ink); opacity: .45; animation: aa-pulse 1.2s ease-in-out infinite; }
@keyframes aa-pulse { 0%, 100% { opacity: .2; } 50% { opacity: .7; } }
@media (prefers-reduced-motion: reduce) { .agent-activity__dots { animation: none; } }
.agent-activity__review { margin-top: var(--space-2); width: 100%; text-align: left; border: 0; background: var(--surface-3);
  color: var(--ink); cursor: pointer; font-size: var(--type-ui-compact); padding: 5px 8px; border-radius: 4px; }
.agent-activity__review:hover { background: var(--line-soft); }

/* --- Modal dialogs --- */
/* Entrance fades the DIM (background-color), not `opacity` — the .dialog is a child,
   so an opacity fade on the overlay made it see-through mid-open (fix-cluster E).
   Close removes the node outright, so no exit transition is lost. */
.dialog-overlay { position: fixed; inset: 0; background: transparent; display: flex; align-items: center; justify-content: center; z-index: 210; transition: background-color .16s; }
.dialog-overlay--in { background: var(--overlay-modal); }
.dialog { background: var(--surface); border: var(--border) solid var(--line); border-radius: var(--radius); padding: var(--space-5); width: 400px; max-width: calc(100vw - 32px); box-shadow: var(--shadow-modal); }
.dialog__title { margin: 0 0 8px; font-size: var(--type-heading-sm); letter-spacing: -0.01em; }
.dialog__msg { margin: 0 0 var(--space-4); color: var(--ink-soft); font-size: var(--type-body); line-height: 1.5; }
.dialog__actions { display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-4); }

/* --- Image lightbox (Issues 1 + 7): click an entry image to view it full size; several
   images become a gallery with ‹ › nav, a counter, and the caption riding below. --- */
.lightbox-overlay { position: fixed; inset: 0; background: transparent; display: flex; align-items: center; justify-content: center;
  padding: var(--space-6) 72px; z-index: 240; opacity: 0; transition: opacity .16s, background-color .16s; cursor: zoom-out; }
.lightbox-overlay--in { opacity: 1; background: var(--overlay-image); }
.lightbox__figure { margin: 0; max-width: 100%; display: flex; flex-direction: column; align-items: center; gap: var(--space-2); }
/* max-height budgets the viewport for the top/bottom chrome + caption, so the box always
   shrink-wraps the scaled image exactly (no letterboxed halo around the shadow/radius). */
.lightbox__img { max-width: 100%; max-height: calc(100vh - 120px); object-fit: contain; border-radius: var(--radius);
  box-shadow: var(--shadow-modal); cursor: default; opacity: 0; transition: opacity .14s ease; }
.lightbox__img--in { opacity: 1; }
.lightbox__caption { flex-shrink: 0; max-width: 60ch; text-align: center; font-style: italic; font-size: var(--type-ui-compact);
  color: var(--on-image); text-shadow: 0 1px 2px var(--on-image-shadow); cursor: default; }
.lightbox__caption[hidden] { display: none; }
.lightbox__count { position: fixed; top: var(--space-4); left: var(--space-4); padding: 4px 10px; font-family: var(--font-mono);
  font-size: var(--type-meta); color: var(--on-image); background: var(--lightbox-btn); border: 1px solid var(--lightbox-btn-line);
  border-radius: var(--radius); cursor: default; user-select: none; }
.lightbox__close { position: fixed; top: var(--space-4); right: var(--space-4); width: 36px; height: 36px; padding: 0;
  display: flex; align-items: center; justify-content: center; font-size: var(--text-lg); line-height: 1; cursor: pointer;
  color: var(--on-image); background: var(--lightbox-btn); border: 1px solid var(--lightbox-btn-line); border-radius: var(--radius); }
.lightbox__close:hover { background: var(--lightbox-btn-hover); }
.lightbox__close:focus-visible { outline: 2px solid var(--on-image); outline-offset: 2px; }
/* ‹ › — fixed at the sides, vertically centred; the clamped end's arrow is hidden. */
.lightbox__nav { position: fixed; top: 50%; transform: translateY(-50%); width: 44px; height: 56px; padding: 0 0 6px;
  display: flex; align-items: center; justify-content: center; font-size: 34px; line-height: 1; cursor: pointer;
  color: var(--on-image); background: var(--lightbox-btn); border: 1px solid var(--lightbox-btn-line); border-radius: var(--radius); }
.lightbox__nav:hover { background: var(--lightbox-btn-hover); }
.lightbox__nav:focus-visible { outline: 2px solid var(--on-image); outline-offset: 2px; }
.lightbox__nav[hidden] { display: none; }
.lightbox__nav--prev { left: var(--space-4); }
.lightbox__nav--next { right: var(--space-4); }
@media (prefers-reduced-motion: reduce) { .lightbox-overlay, .lightbox__img { transition: none; } .lightbox__img { opacity: 1; } }

/* --- Top progress bar --- */
.progress-bar { position: fixed; top: 0; left: 0; height: 2px; width: 0; background: var(--ink); z-index: 300; opacity: 0; }
.progress-bar--active { width: 85%; opacity: 1; transition: width 9s cubic-bezier(.1,.7,.6,1); }
.progress-bar--done { width: 100%; opacity: 0; transition: width .2s ease, opacity .3s ease .15s; }

/* ===== Motion & micro-interactions (018c) ===== */
@keyframes a-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes a-slide-in { from { transform: translateX(16px); } to { transform: translateX(0); } } /* pure transform — the panel surface stays opaque while entering (fix-cluster E) */
@keyframes a-pop { from { opacity: 0; transform: translateY(6px) scale(.99); } to { opacity: 1; transform: none; } }

/* Entrance animations (run on insertion — no JS needed; reduced-motion disables) */
.panel-backdrop, .version-overlay { animation: a-dim .16s ease; } /* a-dim, NOT a-fade: the surface is a child, so a parent opacity fade makes it see-through (fix-cluster E) */
.panel { animation: a-slide-in .22s cubic-bezier(.2, .8, .2, 1); }
.dialog, .version-modal, .palette, .settings, .toast { animation: a-pop .18s ease; }

/* Hover / focus / press transitions */
.btn { transition: background .15s ease, border-color .15s ease, color .15s ease, transform .06s ease; }
.btn:active { transform: translateY(1px); }
.input, .collection-bar__filter, .collection-bar__btn { transition: border-color .15s ease, background .15s ease; }
.space-card, .section-card, .entry-card, .template-card { transition: border-color .15s ease, box-shadow .15s ease, transform .12s ease; }
.space-card:hover, .section-card:hover, .entry-card:hover { transform: translateY(-1px); }
.nav-row, .palette__item, .admin__row,
.entry-row, .invoice-row, .account-menu__item, .view-toggle__btn, .block-picker__item { transition: background .12s ease, color .12s ease; }
.section-chip, .chip, .crumb, .top-bar__crumb { transition: background .12s ease, color .12s ease; }

/* ===== Responsive (018d) ===== */
@media (max-width: 1024px) {
  .editor-panel { height: auto; overflow: visible; }
  .editor-panel__body { flex-direction: column; }
  /* Stacked: main grows to its content so the whole page scrolls, not an inner pane. */
  .editor-panel__body .editor__main { flex: 0 0 auto; width: 100%; max-width: 100%; overflow-y: visible; }
  /* Scoped (higher specificity) so width/border win over the desktop `.editor__details`
     rule defined later in the file — otherwise it stays a 340px strip (issue-101). */
  .editor-panel__body .editor__details { flex: 0 0 auto; width: 100%; max-width: 100%; border-left: 0; border-top: var(--border) solid var(--line-soft); }
  /* Comments rail (082) stacks full-width like Details; the list flows with the page. */
  .editor-panel__body .editor__comments { flex: 0 0 auto; width: 100%; max-width: 100%; border-left: 0; border-top: var(--border) solid var(--line-soft); }
  .editor-panel__body .comment-list { overflow-y: visible; }
  .editor-cols { flex-direction: column; height: auto; }
  /* The sibling-entries panel is a full-width, self-contained collapsible block above the
     editor (fix-cluster V) — no fixed-width island, no inner scrollbar cutting rows, no dead
     void beside it. Collapsed by default; the __head is one row that toggles the list. See the
     fix-cluster V block at the file end for the collapse mechanics (kept there so the ≤720
     rail-strip variant reuses the same rules). */
  .entries-col { width: 100%; border-right: 0; border-bottom: var(--border) solid var(--line-soft); }
  .space-layout { flex-direction: column; }
}
.btn--mini { height: 24px; padding: 0 var(--space-2); font-size: var(--type-ui-compact); }

/* --- Label / mono metadata --- */
.label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: var(--mono-tracking-wide);
  color: var(--muted);
}
/* A label used as a real section heading (the inbox head carries h2 semantics
   for AT navigation) must not pick up UA heading bold/margins. */
h2.label { margin: 0; font-weight: 400; }

/* --- Section dot (the only place accent colours appear) --- */
.section-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--muted);
}

/* --- Card --- */
.card {
  border: var(--border) solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  padding: var(--space-5);
}

/* --- Top bar --- */
.top-bar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  height: 53px;
  padding: 0 var(--space-4);
  border-bottom: var(--border) solid var(--line-soft);
  background: var(--surface);
  /* Pin the bar like the sticky nav/rail (which sit at top:53px beneath it), so a
     long page scrolls the content while the top navigation stays put. */
  position: sticky;
  top: 0;
  z-index: 50;
}
/* issue-176: the Atomo mark as the top-left home link — quiet, square, mark-only. */
.top-bar__home { flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0; border: 0; background: none; border-radius: var(--radius); cursor: pointer; }
.top-bar__home:hover { background: var(--surface-2); }
.top-bar__home-mark { display: block; width: 22px; height: 22px; }
.top-bar__breadcrumb {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--type-ui-compact);
}
/* A real breadcrumb trail: plain-text links, not native buttons (the old "bordered pills").
   Ancestors must read as ways-back *at rest* — active dark text + a delicate hairline underline
   (the design's own thin-line language), deepening to ink on hover/focus. Kept distinct from the
   warmth highlight (a background halo, .is-warm below): bold = here · underline = a way back ·
   halo = a human touched this. */
.top-bar__crumb { color: var(--ink-soft); border: 0; background: none; padding: 0; margin: 0; font: inherit; line-height: inherit; }
button.top-bar__crumb { cursor: pointer; text-decoration: underline; text-decoration-color: var(--muted-2); text-decoration-thickness: 1px; text-underline-offset: 3px; transition: color .12s ease, text-decoration-color .12s ease; }
button.top-bar__crumb:hover, button.top-bar__crumb:focus-visible { color: var(--ink); text-decoration-color: var(--ink); }
.top-bar__crumb--current { color: var(--ink); font-weight: 600; text-decoration: none; } /* you are here — strongest, not a link */
.top-bar__sep { color: var(--muted-2); }
.top-bar__spacer { flex: 1; }

/* --- App shell --- */
.shell { display: flex; flex-direction: column; min-height: 100vh; }
.shell__body { display: flex; flex: 1; }
.shell__nav {
  width: 240px;
  border-right: var(--border) solid var(--line-soft);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: var(--space-4);
  /* A self-contained, viewport-height column (like the activity rail): the section
     list scrolls inside .shell__nav-top while the account zone stays pinned at the
     bottom — a long section list no longer page-scrolls the whole shell (issue-099). */
  position: sticky;
  top: 53px;
  align-self: flex-start;
  height: calc(100vh - 53px);
  box-sizing: border-box;
  overflow: hidden;
}
/* min-width:0 lets the main column shrink instead of being pushed past the
 *  viewport by wide content (e.g. a long unbroken line) — the flex-item default
 *  is min-width:auto, which overflows the page. */
.shell__main { flex: 1; min-width: 0; padding: var(--space-6); }
.shell__main:focus { outline: none; } /* programmatic post-nav focus landmark (041/053) — no ring */
.account-zone {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-top: var(--space-4);
  border-top: var(--border) solid var(--line-soft);
}
.account-zone__name { font-size: var(--type-ui-compact); font-weight: 500; }

/* --- Form field + input --- */
.field { display: flex; flex-direction: column; gap: 6px; }
/* A quiet helper line under a field (requirements, format hints). */
.field__hint { margin: 0; font-size: var(--type-ui-compact); color: var(--ink-soft); line-height: 1.4; }
.input {
  height: 34px;
  padding: 0 var(--space-3);
  border: var(--border) solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: var(--type-body);
}
/* Focus is visible but calm: ink border + a soft inset accent ring (design review). */
.input:focus { outline: none; border-color: var(--ink); box-shadow: var(--focus-ring-inset); }
/* Disabled controls read as inert everywhere, not just buttons (design review). */
.input:disabled, .input[disabled], select:disabled, textarea:disabled { opacity: var(--disabled-opacity); cursor: not-allowed; }

/* --- Space template chooser --- */
.template-chooser { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); }
.template-card { text-align: left; border: var(--border) solid var(--line); border-radius: var(--radius); background: var(--surface); padding: 11px 12px; cursor: pointer; }
.template-card:hover { border-color: var(--ink); }
.template-card.is-selected { border-color: var(--ink); background: var(--ink); color: var(--on-ink); }
.template-card__name { font-weight: 600; font-size: var(--type-ui-compact); margin-bottom: 2px; }
.template-card__desc { margin: 0; font-size: var(--type-meta); color: var(--ink-soft); line-height: 1.4; }
.template-card.is-selected .template-card__desc { color: var(--on-ink-soft); }
/* Section-name preview (mono = metadata, per the design system). */
.template-card__sections { margin: 4px 0 0; font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--mono-tracking); color: var(--ink-soft); line-height: 1.5; }
.template-card.is-selected .template-card__sections { color: var(--on-ink-faint); }
/* Seeded-content count ("21 entries included") — same metadata voice, one notch quieter. */
.template-card__count { margin: 3px 0 0; font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--mono-tracking); color: var(--ink-soft); line-height: 1.4; }
.template-card.is-selected .template-card__count { color: var(--on-ink-faint); }

/* --- Brand lockup (auth screens) --- */
.brand { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-4); }
/* The concentric pixel mark (brand/mark.svg): 18px = 3px cells, an integer
   scale of its 6×6 grid so the pixels stay crisp (ato-mascot.md rendering rule). */
.brand__mark { width: 18px; height: 18px; display: inline-block; }
.brand__name { font-family: var(--font-mono); font-weight: 700; font-size: 16px; letter-spacing: -0.03em; }

/* ===== Public landing page (story 019) ===== */
.lp { max-width: 1080px; margin: 0 auto; padding: 0 var(--space-5); }
/* Skip link: off-screen until focused, then slides in over the sticky nav. */
.skip-link {
  position: fixed; top: -60px; left: var(--space-4); z-index: 100;
  padding: 9px 16px; background: var(--ink); color: var(--on-ink);
  font-size: var(--type-ui-compact); text-decoration: none; border-radius: var(--radius);
  transition: top .14s ease;
}
.skip-link:focus { top: var(--space-3); }
/* Smooth-scroll anchor jumps only on the marketing page (not the in-app views),
   and keep anchored sections clear of the now-sticky nav. */
html:has(.lp) { scroll-behavior: smooth; }
.lp section[id] { scroll-margin-top: 80px; }
/* Sticky nav: on a page this long, sign-in and the section links must stay
   reachable while scrolling. White bg + hairline match the centered 1080 column. */
.lp-nav {
  display: flex; align-items: center; justify-content: space-between; height: 64px;
  position: sticky; top: 0; z-index: 20;
  background: var(--surface);
  border-bottom: var(--border) solid var(--line-soft);
}
.lp-nav .brand { margin-bottom: 0; }
.lp-nav__links { display: flex; align-items: center; gap: var(--space-5); }
.lp-nav__link { color: var(--ink-soft); font-size: var(--type-ui-compact); text-decoration: none; }
.lp-nav__link:hover { color: var(--ink); }
/* Divider between this page's anchors and links to other site pages (landing only). */
.lp-nav__sep { color: var(--line); font-size: var(--text-md); line-height: 1; user-select: none; }
/* A cross-page link (Blog, MCP docs): label + the ↗ "leaves this page" mark,
   set slightly apart so it doesn't read as a footnote reference. */
.lp-nav__link--cross { display: inline-flex; align-items: baseline; gap: 3px; }
.lp-nav__cross-mark { color: var(--muted-2); }
.lp-nav__link--cross:hover .lp-nav__cross-mark { color: var(--ink-soft); }

.lp-hero { text-align: center; padding: 72px 0 56px; }
.lp-hero__title { font-size: clamp(32px, 5vw, 52px); line-height: 1.05; letter-spacing: -0.03em; max-width: 880px; margin: 0 auto var(--space-4); }
.lp-hero__sub { font-size: var(--type-heading-sm); color: var(--ink-soft); max-width: 640px; margin: 0 auto var(--space-5); line-height: 1.5; }
.lp-hero__cta { display: flex; align-items: center; justify-content: center; gap: var(--space-4); flex-wrap: wrap; }

.lp-shot {
  margin: 0;
  border: var(--border) solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}
.lp-shot__img {
  display: block;
  width: 100%;
  height: 100%;
  /* Each frame carries its mockup's own aspect-ratio (see landing-view.ts), so
     contain shows the whole shot with no crop and no letterbox. object-fit:cover
     + a single forced ratio used to crop content — the portrait mobile capture
     lost its top and bottom entirely. */
  object-fit: contain;
}
.lp-shot__caption {
  display: block;
  padding: 9px var(--space-3);
  border-top: var(--border) solid var(--line-soft);
  background: var(--surface-2);
  text-align: left;
}

.lp-section { padding: 64px 0; border-top: var(--border) solid var(--line-soft); }
.lp-section--tight { text-align: center; }
.lp-section__title { font-size: clamp(24px, 3vw, 34px); letter-spacing: -0.02em; max-width: 760px; margin: 0 0 var(--space-5); line-height: 1.15; }
.lp-section__title--sm { font-size: clamp(22px, 2.4vw, 28px); margin-left: auto; margin-right: auto; }
.lp-section__lead { color: var(--ink-soft); max-width: 620px; margin: 0 auto var(--space-5); line-height: 1.6; }


.lp-highlight {
  display: grid;
  grid-template-columns: minmax(250px, 0.72fr) minmax(420px, 1.28fr);
  gap: var(--space-6);
  align-items: center;
  padding: 64px 0;
  border-top: var(--border) solid var(--line-soft);
}
.lp-highlight--flip { grid-template-columns: minmax(420px, 1.28fr) minmax(250px, 0.72fr); }
.lp-highlight--flip .lp-highlight__copy { order: 2; }
.lp-highlight--flip .lp-shot { order: 1; }
.lp-highlight__title {
  margin: var(--space-3) 0;
  max-width: 430px;
  font-size: clamp(22px, 2.6vw, 32px);
  line-height: 1.15;
}
.lp-highlight__body {
  max-width: 470px;
  margin: 0;
  color: var(--ink-soft);
  font-size: var(--type-body);
  line-height: 1.55;
}


.lp-connect { background: var(--ink); color: var(--on-ink); border-radius: var(--radius); padding: 64px var(--space-6); margin: 64px 0; }
.lp-connect__title { font-size: clamp(24px, 3vw, 32px); letter-spacing: -0.02em; max-width: 760px; margin: 0 0 var(--space-4); line-height: 1.15; }
.lp-connect__lead { color: var(--on-ink-soft); max-width: 640px; line-height: 1.6; margin: 0 0 var(--space-6); }
.lp-steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-5); }
.lp-step__n { color: var(--on-ink-dim); }
.lp-step__title { font-size: var(--type-body); margin: var(--space-2) 0; }
.lp-step__body { color: var(--on-ink-soft); line-height: 1.6; margin: 0; font-size: var(--type-body); }

.lp-plan-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4); }
.lp-plan-grid { grid-template-columns: 1fr 1fr; max-width: 720px; }
/* CSS-drawn glyphs of each layout (see landing-view.ts). Monochrome, quiet. */

.lp-plan { border: var(--border) solid var(--line); border-radius: var(--radius); padding: var(--space-5); }
.lp-plan--pro { border-color: var(--ink); border-width: 2px; }
/* Pro tier row: plan label on the left, a "Beta · soon" badge on the right. */
.lp-plan__tier { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.lp-plan__price { font-size: var(--text-xl); font-weight: 600; margin: var(--space-2) 0; letter-spacing: -0.01em; }
/* Story 129 (free during beta): the anchored former price, struck and quiet,
   beside the live "$0 during beta". */
.lp-plan__price-was { color: var(--ink-soft); font-weight: 400; margin-right: var(--space-1); }
.lp-plan__body { color: var(--ink-soft); margin: 0 0 var(--space-4); line-height: 1.5; }
/* Concrete limits: a thin spec table so Free and Pro are comparable at a glance.
   Label (dt) reads quiet; the count (dd) is mono, right-aligned, ink. */
.lp-plan__limits {
  margin: 0 0 var(--space-4);
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0;
}
.lp-plan__limit-k {
  font-size: var(--type-meta);
  color: var(--ink-soft);
  padding: 7px 0;
  border-top: var(--border) solid var(--line-soft);
}
.lp-plan__limit-v {
  margin: 0;
  text-align: right;
  align-self: center;
  color: var(--ink);
  padding: 7px 0;
  border-top: var(--border) solid var(--line-soft);
}

/* --- Landing film (story 135): the "What Atomo Is" short, self-hosted. ---
   aspect-ratio reserves the 16:9 box before any media loads (no layout shift —
   the landing-screenshot RATIO lesson applied to video); the video fills it.
   The overlay play button sits centred on the poster and is removed on first
   play; it's a real <button> so the keyboard path is free. */
/* Issues 68 + 71: the whole film column is centred — the --sm title block
   already centres itself, the title TEXT centres too (71), and intro + frame
   follow (auto margins, centred intro). */
.lp-film__title { text-align: center; }
.lp-film__intro { color: var(--ink-soft); line-height: 1.6; margin: 0 auto var(--space-4); text-align: center; }
.lp-film__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  max-width: 880px;
  margin-inline: auto;
  border: var(--border) solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  /* Theme-STABLE near-black while the poster paints — the frame holds a film
     still, not a themed surface (photo-overlay token family). */
  background: var(--overlay-image);
}
.lp-film__video { display: block; width: 100%; height: 100%; object-fit: contain; }
.lp-film__play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 76px;
  height: 76px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  padding: 0;
  background: none;
  cursor: pointer;
  transition: transform 120ms ease;
}
.lp-film__play svg { width: 76px; height: 76px; filter: drop-shadow(0 2px 10px var(--on-image-shadow)); }
.lp-film__play:hover { transform: scale(1.06); }
.lp-film__play:focus-visible { outline: 2px solid var(--on-image); outline-offset: 3px; }

/* Ato cameos in page sections (spec: deploy sparsely, integer scales, crisp).
   48×36 = 4px cells of the 12×9 grid. */

/* --- Landing aha blocks (story 094): the static frames around the living scenes.
   The animated scenes themselves live in landing-scenes.css (lps- prefix). --- */
.lp-hero__scene { max-width: 880px; margin: var(--space-6) auto 0; }
.lp-scene-caption { display: block; margin-top: var(--space-2); color: var(--muted); }

/* Before/after: the same night as evidence — two columns joined by one arrow. */
.lp-ba { display: grid; grid-template-columns: 1fr auto 1fr; gap: var(--space-4); align-items: start; max-width: 920px; margin: 0 auto; text-align: left; }
.lp-ba__col { border: var(--border) solid var(--line); border-radius: var(--radius); padding: var(--space-4); }
.lp-ba__col--after { border-color: var(--line-soft); background: var(--surface-2, #fafafa); }
.lp-ba__head { display: block; margin-bottom: var(--space-3); }
.lp-ba__arrow { align-self: center; color: var(--muted); font-size: var(--text-lg); }
.lp-ba__row { display: flex; gap: var(--space-3); padding: var(--space-2) 0; border-top: var(--border) solid var(--line-soft); }
.lp-ba__row:first-of-type { border-top: 0; }
.lp-ba__glyph { flex: none; width: 16px; text-align: center; }
.lp-ba__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.lp-ba__primary { font-size: var(--type-ui-compact); line-height: 1.45; overflow-wrap: anywhere; }
.lp-ba__meta { color: var(--muted); }
@media (max-width: 760px) {
  .lp-ba { grid-template-columns: 1fr; }
  .lp-ba__arrow { transform: rotate(90deg); justify-self: center; }
}

/* Vignettes: three mornings. */
.lp-vignettes { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4); text-align: left; }
.lp-vignette { border: var(--border) solid var(--line); border-radius: var(--radius); padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-2); }
.lp-vignette__who { margin: 0; font-size: var(--type-ui-compact); }
.lp-vignette__story { margin: 0; color: var(--ink-soft); line-height: 1.6; font-size: var(--type-body); flex: 1; }
.lp-vignette__feeling { color: var(--ink); }
@media (max-width: 760px) { .lp-vignettes { grid-template-columns: 1fr; } }

/* The dark Connect section gains its kicker (the old hero line) + an inset shot. */
.lp-connect__kicker { display: block; color: var(--on-ink-faint); margin-bottom: var(--space-3); }
.lp-connect__shot { max-width: 760px; margin: var(--space-6) auto 0; }
.lp-connect__shot .lp-shot { background: var(--surface); }

/* The gift: one small card, centred — delight with a limit. */
.lp-gift__card { max-width: 420px; margin: 0 auto; border: var(--border) solid var(--line); border-radius: var(--radius); padding: var(--space-4); text-align: left; display: flex; flex-direction: column; gap: var(--space-3); }
.lp-gift__text { margin: 0; white-space: pre-line; line-height: 1.7; font-size: var(--type-body); }
.lp-gift__sig { color: var(--muted); }

/* Demoted craft/phone pair — two quiet half-width items. */
.lp-duo { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-5); text-align: left; }
.lp-duo__title { margin: var(--space-3) 0 var(--space-1); font-size: var(--type-heading-sm); }
.lp-duo__body { margin: 0; color: var(--ink-soft); line-height: 1.6; }
@media (max-width: 760px) { .lp-duo { grid-template-columns: 1fr; } }

.lp-cta { text-align: center; padding: 80px 0; border-top: var(--border) solid var(--line-soft); }
/* Ato cameo above the closing CTA (12×9 sprite at 10px cells; spec: documents/ato-mascot.md). */
.lp-cta__ato { display: block; width: 120px; height: 90px; margin: 0 auto var(--space-4); image-rendering: pixelated; }
.lp-cta__title { font-size: clamp(26px, 3.5vw, 38px); letter-spacing: -0.02em; margin: 0 0 var(--space-3); }
.lp-cta__lead { color: var(--ink-soft); max-width: 560px; margin: 0 auto var(--space-5); line-height: 1.6; }
.lp-footer { padding: var(--space-5) 0 40px; border-top: var(--border) solid var(--line-soft); }
.lp-footer .brand { margin-bottom: 0; }
.lp-footer__main { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; }
.lp-footer__brand { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.lp-footer__links { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-4); }
.lp-footer__link { color: var(--ink-soft); font-size: var(--type-ui-compact); text-decoration: none; }
.lp-footer__link:hover { color: var(--ink); }
/* Legal bar — © line + Terms/Privacy, baked into the shared Footer so every
   public page carries it. Quieter than the main row: smaller, muted, hairline. */
.lp-footer__legal { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; margin-top: var(--space-4); padding-top: var(--space-3); border-top: var(--border) solid var(--line-soft); }
.lp-footer__copy { color: var(--muted); font-size: var(--type-meta); }
.lp-footer__legal .lp-footer__link { color: var(--muted); }
.lp-footer__legal .lp-footer__link:hover { color: var(--ink); }

/* --- Legal pages (/terms, /privacy) — a calm single prose column --- */
.lp-legal { max-width: 720px; margin: 0 auto; padding: 56px 0 72px; }
.lp-legal:focus { outline: none; }
.lp-legal__title { font-size: clamp(28px, 4vw, 40px); letter-spacing: -0.02em; margin: 0 0 var(--space-2); }
.lp-legal__updated { display: block; margin: 0 0 var(--space-5); }
.lp-legal__intro { font-size: 17px; color: var(--ink); }
.lp-legal__clause { margin-top: var(--space-6); }
.lp-legal__heading { font-size: var(--type-heading); letter-spacing: -0.01em; margin: 0 0 var(--space-3); }
.lp-legal__body { color: var(--ink-soft); line-height: 1.65; margin: 0 0 var(--space-3); }
.lp-legal__list { margin: 0 0 var(--space-3); padding-left: 22px; display: flex; flex-direction: column; gap: var(--space-2); }
.lp-legal__list .lp-legal__body { margin: 0; }

@media (max-width: 760px) {
  .lp { padding: 0 var(--space-4); }
  .lp-steps, .lp-plan-grid, .lp-highlight, .lp-highlight--flip { grid-template-columns: 1fr; }
  .lp-highlight--flip .lp-highlight__copy,
  .lp-highlight--flip .lp-shot { order: initial; }
  .lp-highlight { gap: var(--space-5); }
  .lp-nav__links { gap: var(--space-3); }
  .lp-nav__link { display: none; }
  .lp-nav__sep { display: none; }
  .lp-footer__main, .lp-footer__legal { flex-direction: column; align-items: flex-start; gap: var(--space-4); }
}

/* --- Password show/hide toggle --- */
.input-wrap { position: relative; display: flex; align-items: center; }
.input-wrap .input { flex: 1; padding-right: 52px; }
.input__toggle { position: absolute; right: 8px; border: 0; background: none; color: var(--muted); font-size: var(--type-ui-compact); cursor: pointer; }

/* --- Settings: photo, invoices, MCP guide --- */
.settings-photo { display: flex; align-items: center; gap: var(--space-3); }
.settings-photo__avatar { width: 48px; height: 48px; background: var(--ink); color: var(--on-ink); display: inline-flex; align-items: center; justify-content: center; font-weight: 600; overflow: hidden; flex-shrink: 0; }
.settings-photo__img { width: 100%; height: 100%; object-fit: cover; }
.settings-photo__actions { display: flex; gap: var(--space-2); }
.settings-email { display: flex; align-items: center; gap: 10px; }
.badge { display: inline-flex; align-items: center; color: var(--ink-soft); font-family: var(--font-mono); font-size: var(--text-xs); text-transform: uppercase; letter-spacing: var(--mono-tracking); padding: 2px 7px; border-radius: var(--radius); border: var(--border) solid currentColor; }
.badge--ok { color: var(--accent-green); }
.badge--warn { color: var(--accent-amber); }
.invoice-list { display: flex; flex-direction: column; }
.invoice-row { display: flex; align-items: center; gap: var(--space-3); padding: 8px 0; border-bottom: var(--border) solid var(--line-soft); }
.invoice-row__amount { margin-left: auto; font-family: var(--font-mono); font-size: var(--type-ui-compact); }
.mcp-guide { border-bottom: var(--border) solid var(--line-soft); }

/* --- Collapsible nav --- */
.shell__nav-top { display: flex; flex-direction: column; flex: 1; min-height: 0; overflow-y: auto; scrollbar-width: thin; }

/* --- Auth view --- */
.auth { display: grid; place-items: center; min-height: 100vh; }
.auth__card { width: 320px; }
.auth__title { margin: 0 0 var(--space-4); font-size: var(--type-heading); letter-spacing: -0.01em; }
.auth__lead { margin: 0 0 var(--space-5); font-size: var(--type-body); line-height: 1.6; color: var(--ink-soft); }
.icon-box {
  width: 46px; height: 46px;
  display: grid; place-items: center;
  border: var(--border) solid var(--ink);
  border-radius: var(--radius);
  margin-bottom: var(--space-4);
  color: var(--ink);
}
.auth__form { display: flex; flex-direction: column; gap: var(--space-4); }
.auth__form .btn { justify-content: center; height: 34px; }
.auth__error { margin: 0; min-height: 16px; font-size: var(--type-ui-compact); color: var(--accent-red); }
.auth__switch { margin-top: var(--space-4); text-align: center; }

/* --- View headings --- */
.view__title { margin: 0 0 4px; font-size: var(--type-heading); letter-spacing: -0.01em; }
/* The page-title heading is a programmatic focus target (tabindex=-1) for route-change a11y —
 * don't paint the blue :focus-visible ring on it; it's a heading, not a control (issue-076). */
.view__title:focus, .view__title:focus-visible { outline: none; }
.section-title { margin: 28px 0 12px; font-size: var(--type-heading-sm); letter-spacing: -0.01em; }

/* --- Collection bar (create · spacer · count) --- */
.collection-bar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  /* Clear space above, tight below: the toolbar groups with the grid/list it controls,
     not the content above it (no divider line, which read as belonging upward). */
  margin: var(--space-5) 0 var(--space-3);
}
.collection-bar__spacer { flex: 1; }
.btn[disabled] { opacity: var(--disabled-opacity); cursor: not-allowed; }

/* --- Space grid + card --- */
.space-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4); }
.space-card {
  position: relative; /* positions the sticky-pin control (issue-207) */
  border: var(--border) solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
}
.space-card:hover { border-color: var(--ink); }
/* The primary open target fills the card (issue-207 sibling-button split): an unstyled
   button carrying the card's content, so a keyboard user opens with Enter/Space and the
   sticky toggle stays a separate control. */
.space-card__open { all: unset; cursor: pointer; display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }
.space-card__open:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; border-radius: var(--radius); }
/* Sticky-pin toggle (issue-207): a quiet corner control — revealed on card hover/focus,
   always shown (accented) when stuck. Reserved top-right space never overlaps the title. */
.space-card__pin {
  position: absolute; top: var(--space-2); right: var(--space-2);
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0; border: 0; border-radius: var(--radius);
  background: none; color: var(--muted); cursor: pointer;
  opacity: 0; transition: opacity .12s ease, color .12s ease, background .12s ease;
}
.space-card:hover .space-card__pin, .space-card__pin:focus-visible { opacity: 1; }
.space-card__pin:hover { color: var(--ink); background: var(--surface-3); }
.space-card__pin.is-pinned { opacity: 1; color: var(--ink); } /* stuck = always visible */
.space-card__pin.is-pinned svg { fill: currentColor; } /* filled thumbtack when stuck */
.space-card__pin:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
/* A stuck card wears a subtle left accent so the sticky set reads as a group at the band front. */
.space-card--pinned { border-left: 2px solid var(--ink); }
.space-card__title { margin: 0 0 var(--space-2); font-size: var(--type-heading-sm); letter-spacing: -0.01em; display: flex; align-items: center; gap: 7px; }
.space-card__desc { margin: 0 0 var(--space-4); font-size: var(--type-ui-compact); color: var(--ink-soft); line-height: 1.5; min-height: 36px; }
/* Empty-state placeholder ("No description yet.") reads as an absence, not content: lighter + italic. */
.space-card__desc--empty, .section-card__desc--empty { color: var(--muted); font-style: italic; }
.space-card__meta {
  display: flex; gap: var(--space-4);
  margin-top: auto; /* pin the divider + meta to the card bottom regardless of description length */
  padding-top: var(--space-3);
  border-top: var(--border) solid var(--line-soft);
  font-family: var(--font-mono); font-size: var(--type-meta); color: var(--muted);
}
.space-card__time { margin-left: auto; }

/* --- Space / section dashboard layout --- */
/* Full-width content now that Activity is an on-demand slide-over and Settings a "⋯"
   panel (story-053). The negative margin breaks out of shell__main padding. */
.space-layout { display: flex; align-items: stretch; margin: calc(-1 * var(--space-6)); min-height: calc(100vh - 53px); }
/* clip (not hidden) contains wide content without becoming a scroll container — hidden
   coerces overflow-y to auto, which would break the Read view's position:sticky index. */
.space-layout__main { flex: 1; min-width: 0; padding: var(--space-6); overflow-x: clip; }
.activity { display: flex; flex-direction: column; }
.activity__row { display: flex; align-items: flex-start; gap: var(--space-2); padding: var(--space-2); border-radius: var(--radius); border-bottom: var(--border) solid var(--line-soft); }
.activity__row:last-child { border-bottom: 0; }
/* Linked rows are real buttons — reset chrome, keep the row layout, add hover/focus. */
button.activity__row { width: 100%; box-sizing: border-box; text-align: left; font: inherit; color: inherit; background: none; border-top: 0; border-left: 0; border-right: 0; cursor: pointer; }
.activity__row--link:hover { background: var(--surface-3); }
.activity__row--link:focus-visible { outline: none; box-shadow: inset 0 0 0 1px var(--accent-blue); }
/* Ticker: a new row slides in calmly at the top on a live update (max-height so the
   rows below ease down rather than jump). Only applied to genuinely-new rows. */
@keyframes activity-enter { from { opacity: 0; transform: translateY(-7px); max-height: 0; } to { opacity: 1; transform: none; max-height: 80px; } }
.activity__row--enter { animation: activity-enter .38s cubic-bezier(.2,.7,.3,1); overflow: hidden; }
@media (prefers-reduced-motion: reduce) { .activity__row--enter { animation: none; } }
.activity__avatar { width: 24px; height: 24px; flex-shrink: 0; background: var(--ink-soft); color: var(--on-ink); border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 9px; font-weight: 600; }
.activity__avatar--agent { background: var(--surface); border: var(--border) solid var(--ink); color: var(--ink); }
.activity__text { flex: 1; min-width: 0; }
.activity__line { display: flex; align-items: baseline; min-width: 0; column-gap: var(--space-1); font-size: var(--type-ui-compact); line-height: 1.4; }
.activity__lead { flex-shrink: 0; white-space: nowrap; }
.activity__glyph { flex-shrink: 0; color: var(--muted-2); display: inline-flex; vertical-align: -2px; margin-right: 5px; }
/* The title owns the row's leftover width and truncates with its own ellipsis (issue-096). */
.activity__entity { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-soft); }
.activity__entity--gone { text-decoration: line-through; color: var(--muted); }
.activity__meta { display: flex; align-items: center; flex-wrap: wrap; gap: 5px; margin-top: 3px; font-size: var(--type-meta); color: var(--muted); }
.activity__where { display: inline-flex; align-items: center; gap: var(--space-1); min-width: 0; }
.activity__where span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.activity__sep { color: var(--muted-2); }
.activity__tag { font-size: 9px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); border: var(--border) solid var(--line); border-radius: 999px; padding: 0 5px; }
/* Sticky day divider — gives the feed scannable rhythm. */
.activity__bucket { position: sticky; top: 0; z-index: 1; background: var(--surface-2); padding: var(--space-3) var(--space-2) var(--space-1); font-family: var(--font-mono); font-size: var(--type-meta); text-transform: uppercase; letter-spacing: var(--mono-tracking-wide); color: var(--muted); }
.activity__bucket:first-child { padding-top: var(--space-1); }
/* All / Agents / You filter — segmented pills under the header. */
.activity-filter { display: flex; gap: 5px; flex-shrink: 0; padding: var(--space-2) var(--space-3); border-bottom: var(--border) solid var(--line-soft); }
.activity-filter__btn { font-size: var(--type-ui-compact); padding: 3px 11px; border-radius: 999px; border: var(--border) solid var(--line-soft); background: none; color: var(--ink-soft); cursor: pointer; }
.activity-filter__btn:hover { background: var(--surface-3); }
.activity-filter__btn.is-active { background: var(--ink); color: var(--on-ink); border-color: var(--ink); }
.activity-filter__btn:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--accent-blue); }
/* Review action on an agent work-session row — opens the burst diff. */
.activity__review { margin-left: auto; flex-shrink: 0; font-size: var(--type-ui-compact); color: var(--ink-soft); background: none; border: var(--border) solid var(--line); border-radius: 999px; padding: 1px 9px; cursor: pointer; }
.activity__review:hover { background: var(--surface-3); color: var(--ink); }
.activity__review:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--accent-blue); }

/* --- Space dashboard boards: Resume · Open actions · Sections share one look --- */
/* Resume + Open actions sit side by side, equal width and (via flex stretch) equal
   height; they collapse to a single column when the row can't hold two 320px panels. */
.space-top { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-bottom: var(--space-2); }
.space-top:empty { display: none; }
.space-top > .board, .space-top > .open-actions { flex: 1 1 320px; min-width: 0; margin: 0; }

.board { border: var(--border) solid var(--line); border-radius: var(--radius); background: var(--surface); display: flex; flex-direction: column; min-width: 0; }
.board__head { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3); border-bottom: var(--border) solid var(--line-soft); }
.board__title { margin: 0; font-size: var(--type-heading-sm); font-weight: 600; letter-spacing: -0.01em; }
.board__count { font-family: var(--font-mono); font-size: var(--type-meta); color: var(--muted); border: var(--border) solid var(--line); border-radius: var(--radius); padding: 0 6px; }
.board__body { display: flex; flex-direction: column; }
.board__row { display: flex; align-items: center; gap: 9px; width: 100%; min-width: 0; padding: 8px var(--space-3); text-align: left; font: inherit; color: inherit; background: none; border: 0; border-top: var(--border) solid var(--line-soft); cursor: pointer; }
.board__body .board__row:first-child { border-top: 0; }
.board__row:hover { background: var(--surface-3); }
.board__primary { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; font-size: var(--type-ui-compact); }
.board__meta { flex-shrink: 0; font-size: var(--type-meta); color: var(--muted); white-space: nowrap; }
.resume-chip { display: inline-flex; align-items: center; gap: 5px; flex-shrink: 0; font-size: var(--type-ui-compact); color: var(--ink-soft); }
.resume-chip__sep { color: var(--muted-2); }

/* --- Usage settings page (merged plan usage) --- */
/* Two big meters for the workspace-wide caps (spaces, agent keys); the bar is ink on a
   soft track — monochrome, no decorative colour (design system). */
.usage-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4); }
.usage-meter { border: var(--border) solid var(--line); border-radius: var(--radius); padding: var(--space-4); background: var(--surface); display: flex; flex-direction: column; gap: var(--space-2); }
.usage-meter__head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); }
.usage-meter__count { font-family: var(--font-mono); font-size: var(--text-xl); font-weight: 600; }
.usage-meter__max { color: var(--muted); font-weight: 400; }
.usage-meter__note { color: var(--muted); }
.usage-bar { height: 6px; border-radius: 999px; background: var(--surface-3); overflow: hidden; }
.usage-bar__fill { height: 100%; min-width: 2px; background: var(--ink); border-radius: inherit; transition: width .3s ease; }
.usage-stats { display: flex; gap: var(--space-4); }
.usage-stat { flex: 1; border: var(--border) solid var(--line-soft); border-radius: var(--radius); padding: var(--space-4); display: flex; flex-direction: column; gap: 2px; }
.usage-stat__value { font-family: var(--font-mono); font-size: 24px; font-weight: 600; letter-spacing: -0.02em; }
.usage-space-list { display: flex; flex-direction: column; }
/* Fixed entries column (not `auto`) so every row's 1fr name + 200px bar resolve to the
   same widths — otherwise a row with a shorter entry count (e.g. "2" vs "38") widens its
   name column and shifts the bar out of line with the others (each row is its own grid). */
.usage-space-row { display: grid; grid-template-columns: minmax(0, 1fr) 200px 6rem; align-items: center; gap: var(--space-4); padding: var(--space-3) 0; border-bottom: var(--border) solid var(--line-soft); }
.usage-space-row:last-child { border-bottom: 0; }
.usage-space-row__name { font-weight: 500; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.usage-space-row__bar { display: flex; flex-direction: column; gap: var(--space-1); }
.usage-space-row__entries { white-space: nowrap; text-align: right; }
.usage-limits { margin: 0; }
@media (max-width: 640px) {
  .usage-grid { grid-template-columns: 1fr; }
  .usage-space-row { grid-template-columns: 1fr auto; }
  .usage-space-row__bar { grid-column: 1 / -1; }
}

/* --- Section head (title + action) --- */
.section-head { display: flex; align-items: center; justify-content: space-between; margin: 28px 0 12px; }
.section-head__title { display: flex; align-items: baseline; gap: var(--space-2); }

/* --- Section grid + card --- */
.section-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-3); }
/* Section list view (mirrors .entry-list): icon · name · description · entry count. */
.section-list { display: flex; flex-direction: column; }
.section-row { display: flex; align-items: center; gap: var(--space-3); padding: 11px 4px; border-bottom: var(--border) solid var(--line-soft); cursor: pointer; }
.section-row:hover { background: var(--surface-3); }
.section-row__name { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--type-ui-compact); font-weight: 500; }
.section-row__desc { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font-size: var(--type-ui-compact); }
.section-row__count { flex-shrink: 0; }
.section-card { border: var(--border) solid var(--line); border-radius: var(--radius); padding: var(--space-4); cursor: pointer; overflow: hidden; }
.section-card:hover { border-color: var(--ink); }
.section-card__preview { margin: calc(-1 * var(--space-4)) calc(-1 * var(--space-4)) var(--space-3); height: 96px; background: var(--surface-3); }
.section-card__preview-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.section-card__head { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-2); }
.section-card__name { flex: 1; font-size: var(--type-ui-compact); font-weight: 600; }
.section-card__desc { margin: 0; font-size: var(--type-ui-compact); color: var(--ink-soft); line-height: 1.5; }
.section-icon { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }

/* --- Nav row (left-nav section links) --- */
.nav-row {
  position: relative;
  display: flex; align-items: center; gap: var(--space-2);
  padding: 7px 9px; cursor: pointer; font-size: var(--type-ui-compact);
  border: 0; background: none; width: 100%; text-align: left; color: var(--ink);
  border-left: 2px solid transparent;
}
.nav-row:hover { background: var(--surface-3); }
.nav-row--active { background: var(--surface-3); border-left-color: var(--ink); font-weight: 600; }
.nav-row[draggable="true"] { cursor: grab; }
.nav-row--dragging { opacity: 0.4; }
.nav-row--dropinto { box-shadow: inset 0 2px 0 var(--ink); }

/* --- Section panel footer --- */
.panel__footer { display: flex; align-items: center; gap: var(--space-2); padding-top: var(--space-4); margin-top: var(--space-2); border-top: var(--border) solid var(--line-soft); }
/* Section row (issue-059): the wrapper is a non-interactive container; the open-section
 * target is a button that fills it, with the settings ⋯ as a sibling control. */
.nav-row--section { padding: 0; cursor: default; }
.nav-row__open { flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--space-2); padding: 7px 9px; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.nav-row__icon { display: inline-flex; color: var(--ink-soft); flex-shrink: 0; }
.nav-row__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Entry count: centered in the same 24px column as the section add/menu controls. */
.nav-row__count { width: 24px; margin-left: auto; flex-shrink: 0; font-variant-numeric: tabular-nums; text-align: center; transition: opacity .12s ease; }
.nav-row:hover .nav-row__count { opacity: 0; }
/* The ⋯ menu is out of flow (so the count stays flush right); it appears on hover. */
.nav-row__menu { position: absolute; right: 9px; top: 50%; transform: translateY(-50%); width: 24px; height: 24px; border: 0; background: none; color: var(--muted); cursor: pointer; opacity: 0; }
.nav-row:hover .nav-row__menu { opacity: 1; }
/* SECTIONS header sits at the top of the space nav (since issue-077 removed the space row),
   so it no longer needs the extra top gap that separated it from that row. */
.nav-section { display: flex; align-items: center; justify-content: space-between; padding: 4px 9px 4px; }
.nav-add { width: 24px; height: 24px; padding: 0; display: inline-flex; align-items: center; justify-content: center; border: 0; background: none; color: var(--muted); font-size: 16px; line-height: 1; cursor: pointer; }
.nav-add:hover { color: var(--ink); }

/* --- Top bar: ⌘K launcher --- */
.cmdk {
  display: inline-flex; align-items: center; gap: var(--space-2);
  height: 30px; padding: 0 10px; border: var(--border) solid var(--line); border-radius: var(--radius);
  background: var(--surface); color: var(--muted); cursor: pointer;
}
.cmdk:hover { border-color: var(--ink); }
.cmdk__icon { font-size: var(--text-md); }

/* --- Top bar: context actions (scoped Activity control — story-053) --- */
.top-bar__actions { display: inline-flex; align-items: center; gap: var(--space-2); }
.top-activity {
  position: relative; display: inline-flex; align-items: center; gap: 6px;
  height: 30px; padding: 0 10px; border: var(--border) solid var(--line); border-radius: var(--radius);
  background: var(--surface); color: var(--ink-soft); cursor: pointer;
}
.top-activity:hover { border-color: var(--ink); color: var(--ink); }
.top-activity__label { font-size: var(--type-meta); }
.top-activity__dot { display: none; width: 6px; height: 6px; border-radius: 50%; background: var(--accent-blue); }
.top-activity.has-unread .top-activity__dot { display: inline-block; animation: activity-pulse 1.8s ease-in-out infinite; }
@keyframes activity-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) { .top-activity.has-unread .top-activity__dot { animation: none; } }
@media (max-width: 640px) { .top-activity__label { display: none; } }

/* Activity feed in a popover anchored under the top-bar button (like the agents
   popover) — head + filter stay put, the feed scrolls (story-053). */
.activity-popover { position: fixed; z-index: 90; width: 340px; max-width: calc(100vw - 24px); display: flex; flex-direction: column; max-height: min(72vh, 620px); background: var(--surface); border: var(--border) solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-menu); overflow: hidden; animation: a-pop .12s ease; }
.activity-popover__head { flex-shrink: 0; padding: var(--space-3) var(--space-3) var(--space-2); }
.activity-popover .activity-filter { flex-shrink: 0; }
.activity-popover .activity-panel__body { flex: 1; min-height: 0; overflow-y: auto; padding: var(--space-2) var(--space-3) var(--space-3); scrollbar-width: thin; }

/* --- Top bar: agents cluster --- */
.agents-cluster {
  display: inline-flex; align-items: center; gap: var(--space-2);
  height: 30px; padding: 0 10px; border: var(--border) solid var(--ink); border-radius: var(--radius); cursor: pointer;
}
.cluster__pulse { width: 7px; height: 7px; border-radius: 50%; background: var(--ink); display: inline-block; }
.cluster__avatars { display: flex; }
.cluster__avatar {
  width: 20px; height: 20px; border-radius: 50%; margin-left: -7px;
  background: var(--ink-soft); color: var(--on-ink); border: 1.5px solid var(--surface);
  display: inline-flex; align-items: center; justify-content: center; font-size: 8px; font-weight: 600;
}
.cluster__avatar:first-child { margin-left: 0; }
/* Live agent presence (033c; presence model refined for issue-205): GREEN + motion are
   reserved for "acting now" (--live) — the highest-attention state. Connected-but-idle
   (--online) gets a CALM, STEADY, NEUTRAL cue so it can't be misread as working; a
   not-connected agent stays bare. Three clearly distinct looks: bare < neutral ring <
   green ring + pulse. (Popover text mirrors this: "connected · idle" vs "now · …".) */
.agents-cluster--online { border-color: var(--muted); }
.agents-cluster--live { border-color: var(--accent-green); } /* after --online so a mixed cluster reads active */
.agents-cluster--online .cluster__pulse { background: var(--muted); } /* steady, neutral */
.agents-cluster--live .cluster__pulse { background: var(--accent-green); animation: a-pulse 1.2s ease-in-out infinite; }
.cluster__avatar--online { box-shadow: 0 0 0 1.5px var(--surface), 0 0 0 2px var(--muted); } /* calm neutral ring */
.cluster__avatar--live { box-shadow: 0 0 0 1.5px var(--surface), 0 0 0 3px var(--accent-green); } /* bold green ring */
/* Standing visit ran within 24h (story 117): a faint green halo on the dot — a trace
   of history, deliberately quieter than --online/--live so it never reads as activity. */
.agents-cluster--visited .cluster__pulse { box-shadow: 0 0 0 2.5px color-mix(in srgb, var(--accent-green) 30%, transparent); }
.agents-popover__visit { color: var(--muted); }
.agents-popover__row--live { background: var(--surface-3); border-radius: var(--radius); }
.agents-popover__row--live .agents-popover__main > .label { color: var(--accent-green); }
/* A card that just arrived live (033d) eases in with a brief green ring. */
@keyframes a-live-in {
  0% { transform: translateY(-6px); opacity: 0.35; box-shadow: 0 0 0 2px var(--accent-green); }
  70% { box-shadow: 0 0 0 2px var(--accent-green); }
  100% { transform: none; opacity: 1; box-shadow: 0 0 0 0 transparent; }
}
.is-live-new { animation: a-live-in 1.1s ease-out; }
/* A counter ticking up live (033d) flashes green briefly. */
@keyframes a-live-count { 0%, 45% { color: var(--accent-green); } 100% { color: inherit; } }
.is-live-count { animation: a-live-count .8s ease-out; font-variant-numeric: tabular-nums; }
/* Activity ripple (037b): an element is "warm" while it — or something inside it —
   changed in the last ~5s, then fades. Depth-attenuated and calm: a leaf card gets
   a soft green ring; the chrome it lives under (nav rows, breadcrumb) gets only a
   faint green edge, so the eye is drawn *toward* the active region, not flooded.
   A warmed element also carries a who/what tooltip (037c). */
.section-card.is-warm, .entry-card.is-warm, .space-card.is-warm {
  box-shadow: 0 0 0 2px var(--accent-green); /* reuses the .15s box-shadow transition above */
}
.nav-row.is-warm { border-left-color: var(--accent-green); transition: border-left-color .5s ease; }
/* 072 — freshness on the breadcrumb: a calm neutral wash (the 4px halo gives breathing
 * room without shifting layout), not a green underline. Keeps accents section-markers-only. */
.top-bar__crumb.is-warm { background: var(--surface-3); box-shadow: 0 0 0 4px var(--surface-3); border-radius: var(--radius); transition: background .5s ease, box-shadow .5s ease; }
/* 073a — an agent READING: the same cue at half voice (research, not a change). */
.section-card.is-warm--soft, .entry-card.is-warm--soft, .space-card.is-warm--soft {
  box-shadow: 0 0 0 2px color-mix(in oklch, var(--accent-green) 40%, transparent);
}
.nav-row.is-warm--soft { border-left-color: color-mix(in oklch, var(--accent-green) 45%, var(--line)); transition: border-left-color .5s ease; }
.top-bar__crumb.is-warm--soft { background: var(--surface-3); border-radius: var(--radius); transition: background .5s ease; }
/* 073c — the cooling tail: after the warm 5s, a faint glow lingers ~5 min so a burst
   reads as "an agent was just here", not a blink you missed. Long fade-in smooths the
   warm→glow handoff; the tail itself is static (calm), and vanishes with the class. */
.section-card.is-glow, .entry-card.is-glow, .space-card.is-glow {
  box-shadow: 0 0 0 2px color-mix(in oklch, var(--accent-green) 18%, transparent);
  transition: box-shadow 2s ease;
}
.nav-row.is-glow { border-left-color: color-mix(in oklch, var(--accent-green) 25%, var(--line)); transition: border-left-color 2s ease; }
/* Reduced motion: keep the informational warmth (a static colour + the tooltip) but
   remove the fade so nothing animates — the cue appears/clears instantly (037c). */
@media (prefers-reduced-motion: reduce) {
  .is-live-new, .is-live-count { animation: none; }
  .section-card.is-warm, .entry-card.is-warm, .space-card.is-warm,
  .nav-row.is-warm, .top-bar__crumb.is-warm,
  .section-card.is-glow, .entry-card.is-glow, .space-card.is-glow, .nav-row.is-glow { transition: none; }
  .block--arriving { animation: none; } /* 073b: bulk updates land instantly */
}

/* 073b — burst replay: a remote bulk update reveals its changed blocks one after
   another (staggered via --arrive-delay), so an agent's burst reads as writing,
   not teleportation. Display-layer only — the content is already applied. */
@keyframes block-arrive {
  from { opacity: 0; transform: translateY(3px); }
  to { opacity: 1; transform: none; }
}
.block--arriving { animation: block-arrive .35s ease both; animation-delay: var(--arrive-delay, 0ms); }

/* --- Agents popover (contextual, from the top-bar cluster) --- */
.agents-popover__body { display: flex; flex-direction: column; gap: 2px; }
.agents-popover { position: fixed; z-index: 90; width: 280px; max-width: calc(100vw - 24px); background: var(--surface); border: var(--border) solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-menu); padding: var(--space-3); }
.agents-popover__head { padding-bottom: var(--space-2); margin-bottom: var(--space-2); border-bottom: var(--border) solid var(--line-soft); }
.agents-popover__row { display: flex; align-items: center; gap: var(--space-2); padding: 6px 2px; }
.agents-popover__main { flex: 1; min-width: 0; }
.agents-popover__name { font-size: var(--type-ui-compact); font-weight: 500; }
.agents-popover__manage { width: 100%; text-align: left; border: 0; background: none; padding: 8px 2px 2px; margin-top: var(--space-2); border-top: var(--border) solid var(--line-soft); font-size: var(--type-ui-compact); color: var(--ink-soft); cursor: pointer; }
.agents-popover__manage:hover { color: var(--ink); }
.cluster__count { font-family: var(--font-mono); font-size: var(--text-xs); }

/* --- Command palette (stub) --- */
.palette { position: fixed; z-index: 90; width: 520px; max-width: calc(100vw - 24px); background: var(--surface); border: var(--border) solid var(--ink); border-radius: var(--radius); padding: var(--space-3); box-shadow: var(--shadow-menu); animation: a-pop .12s ease; }
.palette__input { width: 100%; height: 40px; border: 0; outline: none; font-size: var(--type-body); }
.palette__results { margin-top: var(--space-2); padding-top: var(--space-2); border-top: var(--border) solid var(--line-soft); max-height: 60vh; overflow-y: auto; }
.palette__hint { margin: 0; }
.palette__group { margin-bottom: var(--space-3); }
.palette__group .label { display: block; margin-bottom: var(--space-1); }
.palette__item { display: flex; flex-direction: column; align-items: stretch; gap: 2px; width: 100%; text-align: left; border: 0; background: none; padding: 7px 9px; font-size: var(--type-ui-compact); cursor: pointer; border-radius: var(--radius); }
.palette__item-top { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); width: 100%; }
.palette__item:hover { background: var(--surface-3); }
.palette__item.is-selected { background: var(--ink); color: var(--on-ink); }
.palette__item.is-selected .label { color: var(--on-ink-muted); }
.palette__item-hint { flex-shrink: 0; }
/* Full-text search snippet (story 057a) — a dim, single-line preview under an entry hit. */
.palette__item-snippet { font-size: var(--type-meta); color: var(--ink-soft, #64748b); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.palette__item.is-selected .palette__item-snippet { color: var(--on-ink-soft); }

/* Search-result highlight (story 059) — transient, painted via the CSS Custom Highlight
   API (no DOM mutation, so it never enters editable content). Only a few properties are
   honoured on ::highlight(); background-color + color are enough for a find-style mark. */
::highlight(atomo-search-hit) { background-color: var(--search-hit); color: inherit; }
.palette__group-label { display: block; margin: var(--space-2) 0 4px; }
.palette__footer { display: flex; gap: var(--space-4); margin-top: var(--space-2); padding-top: var(--space-2); border-top: var(--border) solid var(--line-soft); }

/* --- Account card + menu --- */
.account-card {
  display: flex; align-items: center; gap: var(--space-2); width: 100%;
  border: 0; background: none; cursor: pointer; padding: var(--space-2); text-align: left;
}
.account-card:hover { background: var(--surface-3); }
.account-card__avatar { width: 28px; height: 28px; background: var(--ink); color: var(--on-ink); display: inline-flex; align-items: center; justify-content: center; font-size: 10px; font-weight: 600; flex-shrink: 0; overflow: hidden; }
.account-card__img { width: 100%; height: 100%; object-fit: cover; }
.account-card__id { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.account-card__name { font-size: var(--type-ui-compact); font-weight: 600; }
.account-card__chev { color: var(--muted-2); }
.account-menu { display: flex; flex-direction: column; border: var(--border) solid var(--line); border-radius: var(--radius); margin-bottom: var(--space-2); overflow: hidden; }
.account-menu__item { height: 34px; padding: 0 var(--space-3); border: 0; background: var(--surface); text-align: left; font-size: var(--type-ui-compact); cursor: pointer; display: flex; align-items: center; gap: var(--space-2); }
.account-menu__item:hover { background: var(--surface-3); }
/* Landing-page link (issue-181): a low-noise, smaller item below the version row. */
.account-menu__item--quiet { height: 30px; font-size: var(--type-ui-compact); color: var(--muted); }
.account-menu__item--quiet:hover { color: var(--ink); }
/* Build/release number — a quiet, non-interactive line above Log out. */
.account-menu__version { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: 4px var(--space-3); font-variant-numeric: tabular-nums; }
.account-menu__version:empty { display: none; }
/* Quiet live-connection status next to the version — a static dot, green when connected. */
.account-menu__conn { display: inline-flex; align-items: center; gap: 5px; color: var(--muted-2); }
.account-menu__conn-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--muted-2); flex-shrink: 0; }
.account-menu__conn.is-on { color: var(--accent-green); }
.account-menu__conn.is-on .account-menu__conn-dot { background: var(--accent-green); }
/* Workspace (frame 1): the menu is expanded inline, not a floating dropdown.
   One divider above the account block (.account-zone border-top), and one
   between the menu (…Log out) and the user-name card (.account-card--open). */
.account-menu--expanded { display: flex !important; border: 0; border-radius: 0; margin-bottom: 0; }
.account-card--open { border-top: var(--border) solid var(--line-soft); margin-top: var(--space-1); padding-top: var(--space-3); }
.account-card--open .account-card__chev { display: none; }
.account-card--static { cursor: default; }
.account-card--static:hover { background: none; }

/* --- Icon / colour pickers --- */
.picker { display: flex; gap: 7px; margin-bottom: var(--space-3); }
/* Icon + colour pickers fill the field width in equal columns (7 across) so the two
   rows of icons and the colour row line up edge-to-edge with the inputs above. */
.picker--grid { display: grid; grid-template-columns: repeat(7, 1fr); }
.picker__icon {
  height: 38px;
  display: grid; place-items: center;
  border: var(--border) solid var(--line-soft);
  border-radius: var(--radius); background: var(--surface); cursor: pointer; color: var(--muted);
}
.picker__icon.is-selected { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
/* "No icon" moved out of the grid (issue-131): a small secondary control beside the
   heading, so the 14 icons form two clean 7-wide rows. */
.picker-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); margin-bottom: 6px; }
.picker__none { font-size: var(--type-meta); color: var(--muted); border: var(--border) solid var(--line-soft); border-radius: var(--radius); padding: 2px 8px; background: var(--surface); cursor: pointer; }
.picker__none:hover { color: var(--ink-soft); border-color: var(--line); }
.picker__none.is-selected { color: var(--ink); border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
.picker__swatch {
  height: 38px; border: 0; border-radius: var(--radius); cursor: pointer;
}
.picker__swatch.is-selected { box-shadow: 0 0 0 2px var(--surface), 0 0 0 3.5px var(--ink); }
.picker--colors { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.picker--colors .picker__swatch { width: 100%; height: 24px; }

/* --- Segmented control (default view): full-width, equal-width items. --- */
.segmented { display: flex; border: var(--border) solid var(--line); border-radius: var(--radius); overflow: hidden; }
.segmented__item { flex: 1; height: 32px; padding: 0; border: 0; border-left: var(--border) solid var(--line); background: var(--surface); font-size: var(--type-ui-compact); font-weight: 500; color: var(--ink-soft); cursor: pointer; }
.segmented__item:first-child { border-left: 0; }
.segmented__item.is-selected { background: var(--ink); color: var(--on-ink); }

/* --- Section header title --- */
/* Icon leads the name + description; nudge it down so its top edge sits on the title's
   top line (flex-start otherwise pins it to the line box, ~5px above the glyphs). */
.section-head__title { display: flex; align-items: flex-start; gap: var(--space-3); }
.section-head__title > .section-icon { margin-top: 5px; }

/* --- Entry grid + card --- */
.entry-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-3); }
.entry-card { border: var(--border) solid var(--line); border-radius: var(--radius); padding: var(--space-4); cursor: pointer; display: flex; flex-direction: column; }
.entry-card:hover { border-color: var(--ink); }
.entry-card__meta { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-2); }
.entry-card__kind { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: var(--mono-tracking); text-transform: uppercase; color: var(--muted); }
.entry-card__date { font-family: var(--font-mono); font-size: var(--type-meta); color: var(--muted); }
.entry-card__meta-end { display: flex; align-items: center; gap: var(--space-2); }
.entry-card__actions { font-family: var(--font-mono); font-size: var(--type-meta); color: var(--muted); } /* open-actions count (036h) */
.entry-card__title { margin: 0 0 6px; font-size: var(--type-body); font-weight: 600; letter-spacing: -0.01em; display: flex; align-items: center; gap: 6px; }
/* Card thumbnail (story 068/078) — bleeds to the card edge; overflow clips the zoom (078). */
.entry-card__preview { margin: calc(-1 * var(--space-4)) calc(-1 * var(--space-4)) var(--space-3); height: 96px; background: var(--surface-3); overflow: hidden; }
.entry-card__preview-img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* 129 — headline INSIDE the thumbnail: taller strip, title pinned to the bottom, image absolute
   behind it, auto text colour, and a bottom scrim for images so the title stays readable. */
.entry-card__preview--titled { position: relative; display: flex; align-items: flex-end; height: 120px; }
.entry-card__preview--titled .entry-card__preview-img { position: absolute; inset: 0; }
.entry-card__preview--scrim::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: var(--scrim); }
.entry-card__title--inside { position: relative; z-index: 1; margin: 0; width: 100%; padding: var(--space-3); box-sizing: border-box; }
.entry-card__title--inside.entry-card__title--light { color: var(--on-image); text-shadow: 0 1px 3px var(--on-image-shadow); }
.entry-card__title--inside.entry-card__title--dark { color: var(--ink); }

/* Thumbnail picker + crop frame in the entry Details panel (story 078). */
.thumb-picker { display: flex; flex-wrap: wrap; gap: 6px; }
.thumb-picker__opt { width: 40px; height: 40px; border: var(--border) solid var(--line-soft); border-radius: var(--radius); background: var(--surface-3) center/cover no-repeat; cursor: pointer; padding: 0; }
.thumb-picker__opt--none { display: grid; place-items: center; font-family: var(--font-mono); font-size: var(--type-ui-compact); color: var(--muted); background-image: none; }
.thumb-picker__opt.is-selected { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
/* Rest state: a muted monochrome wash — "styles live here" without suggesting a palette. */
.thumb-picker__opt--style { background-image: linear-gradient(135deg, var(--surface-3), var(--line)); }
/* Style thumbnail editor (078 follow-up): WYSIWYG ghost card (drag strip = gradient
   direction) · preset strips · color wells (+/× toggles solid ↔ gradient). */
.thumb-style { margin-top: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2); }
.thumb-style__card { border: var(--border) solid var(--line-soft); border-radius: var(--radius); background: var(--surface); overflow: hidden; }
.thumb-style__strip { position: relative; height: 64px; }
.thumb-style__strip.is-grabbable { cursor: grab; touch-action: none; }
.thumb-style__strip.is-grabbing { cursor: grabbing; }
.thumb-style__body { padding: 8px 10px 10px; display: flex; flex-direction: column; gap: 5px; }
.thumb-style__bar { height: 5px; border-radius: var(--radius); background: var(--surface-3); }
.thumb-style__bar--wide { width: 82%; }
.thumb-style__bar--narrow { width: 55%; }
.thumb-style__presets { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.thumb-style__preset { height: 26px; border: var(--border) solid var(--line-soft); border-radius: var(--radius); cursor: pointer; padding: 0; }
.thumb-style__preset.is-selected { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
.thumb-style__row { display: flex; align-items: center; gap: var(--space-2); }
.thumb-style__wellwrap { position: relative; display: inline-flex; }
.thumb-style__well { position: relative; width: 28px; height: 28px; border: var(--border) solid var(--line); border-radius: var(--radius); padding: 0; display: inline-block; cursor: pointer; }
.thumb-style__well input[type="color"] { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; }
.thumb-style__well--add { background: var(--surface); border-style: dashed; color: var(--muted); font-size: 15px; line-height: 1; display: grid; place-items: center; }
.thumb-style__well--add:hover { color: var(--ink); border-color: var(--muted); }
/* 128 — always visible + a larger hit target (was 14px, hover-only) so the solid↔gradient
   remove control is discoverable and easy to tap. */
.thumb-style__well-x { position: absolute; top: -6px; right: -6px; width: 18px; height: 18px; border: var(--border) solid var(--line); border-radius: 50%; background: var(--surface); color: var(--muted); font-size: 12px; line-height: 1; display: grid; place-items: center; cursor: pointer; padding: 0; }
.thumb-style__well-x:hover { color: var(--accent-red); border-color: var(--accent-red); }
.thumb-style__deg { margin-left: auto; font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted); letter-spacing: var(--mono-tracking); }
.thumb-crop-wrap { margin-top: var(--space-3); display: flex; flex-direction: column; gap: 6px; }
.thumb-crop__zoom { accent-color: var(--ink); }
.thumb-crop { position: relative; height: 120px; overflow: hidden; border: var(--border) solid var(--line-soft); border-radius: var(--radius); background: var(--surface-3); cursor: grab; touch-action: none; }
.thumb-crop.is-grabbing { cursor: grabbing; }
.thumb-crop__img { width: 100%; height: 100%; object-fit: cover; display: block; pointer-events: none; user-select: none; }
.thumb-crop__controls { display: flex; align-items: center; gap: var(--space-2); }
.thumb-crop__zoom { flex: 1; }
/* 128 — visible zoom read-out + Reset */
.thumb-crop__zoomval { min-width: 34px; text-align: right; color: var(--ink-soft); }
.thumb-crop:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
/* 129 — title-placement segmented control (Below / Inside) */
.thumb-place-wrap { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-3); }
.thumb-place { display: inline-flex; border: var(--border) solid var(--line); border-radius: var(--radius); overflow: hidden; }
.thumb-place__opt { border: 0; background: var(--surface); color: var(--ink-soft); font-size: var(--type-ui-compact); font-family: var(--font-ui); padding: 4px 10px; cursor: pointer; }
.thumb-place__opt + .thumb-place__opt { border-left: var(--border) solid var(--line); }
.thumb-place__opt.is-selected { background: var(--ink); color: var(--surface); }

/* Rail hints are meaningful explanation prose (issue-217): compact role, UI face —
   markup must NOT also carry .label (that re-imposes 11px uppercase mono). */
.details__hint { margin: 0; color: var(--muted); font-size: var(--type-ui-compact); line-height: 1.5; }

/* --- Comments (story 070): margin markers · block popover · Details rows --- */
/* Marker: a quiet count pill in the right margin of an annotated block. */
.block__comment-marker {
  position: absolute; top: 3px; right: -42px; z-index: 3;
  display: inline-flex; align-items: center; gap: 3px; min-width: 20px; height: 19px; padding: 0 6px;
  border: var(--border) solid var(--line); border-radius: 10px; background: var(--surface);
  color: var(--muted); font-family: var(--font-mono); font-size: var(--text-xs); cursor: pointer;
}
.block__comment-marker:hover { color: var(--ink); border-color: var(--ink-soft); }
/* Cross-highlight: hovering the marker OR its rail card lights up both (keeps the marker's own
   colour — agent markers stay blue — and just adds emphasis), so the pair reads as one. */
.block__comment-marker.is-linked { border-color: var(--ink-soft); background: var(--surface-3); box-shadow: 0 0 0 3px var(--surface-3); }
/* Narrow screens have no right margin — tuck the marker inside the row. */
@media (max-width: 1200px) { .block__comment-marker { right: 2px; } }
/* The always-there "comment on this block" button: faint, revealed on block hover in the
   same right-margin spot as the marker. Hidden once the block has a count marker (that
   becomes the affordance). Mirrors how the drag handle reveals on hover in the left gutter. */
/* Styled like the count marker (bubble in a quiet pill) so the "new comment" affordance
   reads as the same family — same border, surface, radius, mono "+" — just with a + for "new". */
.block__comment-add {
  position: absolute; top: 3px; right: -42px; z-index: 3;
  display: inline-flex; align-items: center; gap: 2px; height: 19px; padding: 0 6px;
  border: var(--border) solid var(--line); border-radius: 10px; background: var(--surface);
  color: var(--muted); font-family: var(--font-mono); font-size: var(--text-xs); line-height: 1; cursor: pointer;
  opacity: 0; transition: opacity .12s ease, color .12s ease, border-color .12s ease;
}
.block:hover .block__comment-add, .block__comment-add:focus-visible { opacity: 1; }
.block__comment-add:hover { color: var(--ink); border-color: var(--ink-soft); }
.block:has(.block__comment-marker) .block__comment-add { display: none; } /* the count marker takes over */
@media (max-width: 1200px) { .block__comment-add { right: 2px; } }
@media (prefers-reduced-motion: reduce) { .block__comment-add { transition: none; } }
.comment-pop {
  position: fixed; z-index: 230; width: 320px; max-height: 60vh; overflow-y: auto;
  background: var(--surface); border: var(--border) solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-menu); padding: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2);
}
.comment-pop__head { display: flex; align-items: center; justify-content: space-between; }
.comment-pop__empty { margin: 0; color: var(--muted); }
.comment-pop__resolved summary { cursor: pointer; color: var(--muted); }
.comment-pop__resolved summary::marker { color: var(--muted-2); }
.comment-row { padding: 6px 0; border-bottom: var(--border) solid var(--line-soft); }
.comment-row:last-of-type { border-bottom: 0; }
.comment-row--resolved { opacity: 0.72; } /* recede, but keep resolved-by/body legible (was 0.55, below any usable floor) */
/* #8 — a grouped same-author reply: no avatar/name, tucked tighter under the row above; a 22px
   gap (matching the avatar) holds the column so bodies still line up. Reads as one conversation. */
.comment-row--compact { padding-top: 2px; border-top: 0; }
.comment-row__gap { flex-shrink: 0; width: 22px; }
/* #6 — optimistic post lifecycle: in-flight recedes; a failure surfaces a quiet, legible cue + Retry. */
.comment-row--pending { opacity: 0.6; }
.comment-row__sending { color: var(--muted); font-style: italic; }
.comment-row--failed { opacity: 1; }
.comment-row__failed-note { color: var(--muted); }
.comment-row__retry { border: 0; background: none; padding: 0; color: var(--ink); font: inherit; cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
.comment-row__retry:hover { color: var(--ink-soft); }
.comment-row__meta { display: flex; align-items: center; gap: 6px; margin-bottom: 2px; }
.comment-row__author { font-weight: 600; font-size: var(--type-meta); }
.comment-row__chip { border: var(--border) solid var(--line-soft); border-radius: 8px; padding: 0 5px; color: var(--ink-soft); }
/* Informational micro-text → --muted (4.56:1). --muted-2 is 2.75:1 ("never body copy" per
   tokens.css); resolved-by attribution + the orphan tag carry meaning, so they must be legible. */
.comment-row__orphan, .comment-row__resolvedby { color: var(--muted); }
.comment-row__body { font-size: var(--type-body); line-height: 1.5; white-space: pre-wrap; word-break: break-word; }
/* Composer — one bordered box (textarea + footer), so add/reply read as a single control
   rather than a stray field and a stray button. Focus darkens the border (calm, no loud ring). */
.comment-add { display: flex; flex-direction: column; border: var(--border) solid var(--line); border-radius: var(--radius); background: var(--surface); transition: border-color .12s ease; }
.comment-add.is-focused { border-color: var(--ink-soft); }
.comment-add__field { border: 0; background: none; resize: none; padding: 8px 10px 4px; font-family: var(--font-ui); font-size: var(--type-body); line-height: 1.5; min-height: 22px; max-height: 160px; color: var(--ink); }
.comment-add__field:focus { outline: none; }
.comment-add__field::placeholder { color: var(--muted); } /* the prompt is informational — legible (was --muted-2, 2.75:1) */
.comment-add__foot { display: flex; align-items: center; gap: 8px; padding: 0 6px 6px 8px; }
/* The "For:" delegation select: a quiet inline mono control that reads as part of the box. */
.comment-add__for { min-width: 0; border: 0; background: none; color: var(--muted); font-size: var(--type-meta); cursor: pointer; }
.comment-add__for:hover { color: var(--ink); }
.comment-add__hint { margin-left: auto; color: var(--muted); }
.comment-add__send { flex-shrink: 0; width: 26px; height: 26px; border: 0; border-radius: var(--radius); background: var(--ink); color: var(--surface); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; transition: background .12s ease; }
.comment-add__send:disabled { background: var(--line); cursor: default; }
.comment-add__send:not(:disabled):hover { background: var(--ink-soft); }

/* --- Comments made central (story 082): docked rail · compact thread list · click-to-link --- */
/* The rail shares the 340px right slot with Details (mutually exclusive toggles), same geometry. */
.editor__comments { width: 340px; flex-shrink: 0; border-left: var(--border) solid var(--line-soft); background: var(--surface-2); display: flex; flex-direction: column; min-height: 0; }
.editor-panel:not(.editor-panel--comments) .editor__comments { display: none; }
.editor__comments-head { height: 40px; flex-shrink: 0; display: flex; align-items: center; padding: 0 var(--space-4); border-bottom: var(--border) solid var(--line-soft); }
/* A plain, always-populated scrollable list (document order) — no absolute positioning; the
   snippet line + the margin marker link a thread to its block, not physical alignment. */
.comment-list { flex: 1; min-height: 0; overflow-y: auto; }
.comment-list__empty { margin: 0; padding: var(--space-4); color: var(--muted); font-size: var(--type-body); line-height: 1.5; }
.comment-list__retry { border: 0; background: none; padding: 0; color: var(--ink); font: inherit; cursor: pointer; text-decoration: underline; text-underline-offset: 2px; } /* monochrome ghost — no reserved blue */
.comment-list__retry:hover { color: var(--ink-soft); }
.comment-list__divider { display: block; padding: var(--space-3) var(--space-4) var(--space-1); color: var(--muted); border-top: var(--border) solid var(--line-soft); margin-top: var(--space-2); }
.comment-card { padding: var(--space-3) var(--space-4); border-bottom: var(--border) solid var(--line-soft); }
.comment-card--agent { box-shadow: inset 2px 0 0 var(--accent-blue); } /* blue == agent, the app's existing cue */
.comment-card.is-active { background: var(--surface-3); }
/* Lit up while its block's marker is hovered (and vice-versa) — the pairing cue. */
.comment-card.is-linked { background: var(--surface-3); box-shadow: inset 0 0 0 1.5px var(--muted-2); }
.comment-card--agent.is-linked { box-shadow: inset 2px 0 0 var(--accent-blue), inset 0 0 0 1.5px var(--muted-2); }
.comment-card.comment-flash { animation: comment-flash 1.2s ease; }
@keyframes comment-flash { 0%, 100% { background: transparent; } 22% { background: color-mix(in oklch, var(--accent-blue) 12%, transparent); } }
/* Context line: the annotated block's snippet, click to jump to it. */
.comment-card__context { display: flex; align-items: center; gap: 6px; width: 100%; margin-bottom: var(--space-2); padding: 0; border: 0; background: none; color: var(--muted); font: inherit; text-align: left; cursor: pointer; }
.comment-card__context:hover { color: var(--ink); }
.comment-card__snip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--type-meta); }
/* #8 — Reply is a plain affordance, not an agent cue: monochrome, so --accent-blue means ONLY "agent". */
.comment-card__reply { display: inline-block; margin-top: var(--space-1); padding: 0; border: 0; background: none; color: var(--ink-soft); cursor: pointer; }
.comment-card__reply:hover { text-decoration: underline; }
/* The commented block, flashed after a jump from its card. */
.block.comment-flash { animation: block-flash 1.2s ease; border-radius: var(--radius); }
@keyframes block-flash { 0%, 100% { box-shadow: none; } 25% { box-shadow: 0 0 0 3px color-mix(in oklch, var(--accent-blue) 30%, transparent); } }
/* Reduced-motion: the flash is the SOLE landing cue (jumpToBlock/focusCard use instant scroll),
   so keep a momentary highlight but swap the 1.2s pulse for a static tint that clears when the
   class is removed (~1.2s later, in flash()). Matches the file's no-motion-first discipline. */
@media (prefers-reduced-motion: reduce) {
  .comment-card.comment-flash { animation: none; background: var(--surface-3); }
  .block.comment-flash { animation: none; box-shadow: 0 0 0 3px color-mix(in oklch, var(--accent-blue) 22%, transparent); }
}
.comment-composer { flex-shrink: 0; border-top: var(--border) solid var(--line-soft); padding: var(--space-3) var(--space-4); }
/* Avatar in a comment row (owner = per-name accent, agent = blue non-human square). */
.comment-row { display: flex; gap: var(--space-2); align-items: flex-start; }
.comment-row__avatar { flex-shrink: 0; width: 22px; height: 22px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: var(--on-ink); font-size: 9px; font-weight: 600; font-family: var(--font-ui); }
.comment-row__avatar--agent { border-radius: 30%; }
.comment-row__content { flex: 1; min-width: 0; }
/* Header toggle: an open-count badge on the comments icon, so the count reads while closed. */
.icon-btn--badge { position: relative; }
.icon-btn__badge { position: absolute; top: 0; right: 0; min-width: 13px; height: 13px; padding: 0 3px; border-radius: 7px; background: var(--ink); color: var(--surface); font-family: var(--font-mono); font-size: 9px; line-height: 13px; text-align: center; display: none; }
.icon-btn--badge.has-badge .icon-btn__badge { display: block; }
.block__comment-marker--agent { color: var(--accent-blue); border-color: color-mix(in oklch, var(--accent-blue) 45%, var(--line)); }
.block__comment-marker--agent:hover { color: var(--accent-blue); border-color: var(--accent-blue); }

/* --- Agent threads (story 086): address to an agent · in-thread status · triage filter --- */
/* Triage filter: a quiet mono segmented control (shown only once an agent is involved). */
.comment-filter { display: flex; gap: 12px; flex-shrink: 0; padding: 8px var(--space-4); border-bottom: var(--border) solid var(--line-soft); }
.comment-filter__btn { padding: 0 0 3px; border: 0; background: none; color: var(--muted); cursor: pointer; }
.comment-filter__btn:hover { color: var(--ink-soft); }
.comment-filter__btn.is-on { color: var(--ink); box-shadow: inset 0 -1.5px 0 var(--ink); }
/* The "For <agent>" delegation chip on a comment row — the one reserved blue cue. */
.comment-row__for { border-color: color-mix(in oklch, var(--accent-blue) 40%, var(--line-soft)); color: var(--accent-blue); }
/* #8 — "needs your call" is an attention cue, not an agent-identity cue: strong ink, not blue.
   Blue now signals ONLY who/what is an agent (avatar, "agent" chip, "for <agent>", status lines). */
.comment-row__awaiting { color: var(--ink); font-weight: 600; }
/* An agent working step (thought|action) as a calm mono status line under the row. */
.comment-status { display: flex; gap: 6px; align-items: baseline; padding: 2px 0 2px 30px; color: var(--accent-blue); font-family: var(--font-mono); font-size: var(--type-meta); animation: comment-status-in .25s ease; }
.comment-status__who { flex-shrink: 0; color: var(--accent-blue); }
.comment-status__body { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-transform: none; letter-spacing: 0; color: color-mix(in oklch, var(--accent-blue) 78%, var(--ink)); }
@keyframes comment-status-in { from { opacity: 0; transform: translateY(-2px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .comment-status { animation: none; } }
/* -webkit-box path renders the ellipsis; the standard `line-clamp` shorthand is
   intentionally omitted — Chrome recomputes `display` to flow-root and drops the
   ellipsis when it's present (issue 049). */
.entry-card__snippet { margin: 0; font-size: var(--type-ui-compact); color: var(--ink-soft); line-height: 1.5; overflow: hidden; overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; }

/* --- Curator briefing prose (story 071; renderer shared with the unified element's
   curator-note row since 102 — the standalone card + its chrome are gone) --- */
.briefing__body { display: flex; flex-direction: column; gap: var(--space-2); }
/* issue-197: one step up (sm → md) so the curator note reads like a human note; light
   inline emphasis (**bold** / _italic_) rendered as real strong/em nodes. */
.briefing__para { margin: 0; font-size: var(--type-body); line-height: 1.6; color: var(--ink-soft); white-space: pre-line; }
.briefing__list { margin: 0; padding-left: 1.2em; font-size: var(--type-body); line-height: 1.6; color: var(--ink-soft); }
.briefing__list li { margin: 3px 0; }
.briefing__body strong { color: var(--ink); font-weight: 600; }
.briefing__body em { font-style: italic; }


.digest__caught { color: var(--muted); }
.digest__empty { margin: var(--space-2) 0 0; color: var(--muted); }

/* --- Inbox (story 074a; compose-first in 085): a full-width capture composer over a
       pending list on the workspace dashboard. --- */
.inbox { margin-bottom: var(--space-4); padding: var(--space-4); }
/* Composer: one bordered box that reads as a single input; the note field, attachment
   chips, and the action bar stack inside it. */
.inbox__composer { border: var(--border) solid var(--line); border-radius: var(--radius); padding: var(--space-3); background: var(--surface); }
.inbox__composer.is-drop { outline: 2px dashed var(--ink); outline-offset: 4px; }
/* The field is borderless, so the focus ring lives on the composer frame —
   the same visible-but-calm idiom as .input:focus (ink border + soft inset ring). */
.inbox__composer:focus-within { border-color: var(--ink); box-shadow: var(--focus-ring-inset); }
/* 098: the capture field reads like an entry paragraph block (17px/1.65 body type
   on a bare surface — the .block__rich reading grade, see line ~2023), not a form
   input. It stays a plain <textarea>: the editor feel is typographic only. */
.inbox__field {
  display: block; width: 100%;
  border: 0; padding: 2px 0; margin: 0;
  min-height: 60px;                 /* ~two lines at 17px/1.65 */
  resize: none; overflow-y: auto;   /* grows via JS to 320px, then scrolls */
  background: transparent; color: var(--ink); caret-color: var(--ink);
  font-family: var(--font-ui); font-size: 17px; line-height: 1.65;
}
.inbox__field::placeholder { color: var(--muted); opacity: 1; }
.inbox__field:focus { outline: 0; }
/* Textarea ghost-text (issue-179): an overlay mirrors the field's wrapped text in
   transparent ink, then paints the muted suggestion right after it — exactly at the
   caret. It sits ON TOP of the field (pointer-events:none), so the field keeps its own
   background/border and real text; only the muted suffix is visible. Metrics that must
   match (font/padding/width) are copied from the field onto the overlay in JS. */
.ta-ghost { position: relative; display: block; }
/* The wrapper takes the field's old layout slot (e.g. a flex child that stretched);
   the textarea must then fill the wrapper so its width doesn't collapse to the cols
   default. Harmless where the field is already width:100% (.inbox__field). */
.ta-ghost > textarea { width: 100%; box-sizing: border-box; }
.ta-ghost__overlay {
  position: absolute; inset: 0; z-index: 1; margin: 0; pointer-events: none; overflow: hidden;
  white-space: pre-wrap; overflow-wrap: break-word; word-break: break-word; color: transparent;
}
.ta-ghost__suffix { color: var(--muted-2); }
/* In the home capture the composer is a flex column with a growing field — keep the
   wrapper (now the flex child) growing the same way. */
.home-capture .inbox__composer > .ta-ghost { flex: 1 1 auto; display: flex; flex-direction: column; }
.inbox__chips { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
.inbox__chips:empty { margin-top: 0; }
.inbox__chip { display: inline-flex; align-items: center; gap: var(--space-2); padding: 3px 4px 3px 8px; border: var(--border) solid var(--line-soft); border-radius: var(--radius); background: var(--surface-2); font-size: var(--type-ui-compact); color: var(--ink-soft); max-width: 100%; }
.inbox__chip-kind { flex-shrink: 0; }
.inbox__chip-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.inbox__chip-thumb { height: 22px; width: 30px; object-fit: cover; border-radius: var(--radius); flex-shrink: 0; }
.inbox__chip-x { border: 0; background: none; cursor: pointer; color: var(--muted); font-size: var(--text-md); line-height: 1; padding: 0 2px; }
.inbox__chip-x:hover { color: var(--ink); }
.inbox__bar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-top: var(--space-3); }
.inbox__bar-side { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.inbox__attach { flex-shrink: 0; }
.inbox__confirm { color: var(--accent-green); }
/* Pending rows (now rendered inside the 104 popover, not inline). */
.inbox__row { display: flex; align-items: center; gap: var(--space-3); padding: 8px 0; border-top: var(--border) solid var(--line-soft); }
.inbox__kind { flex-shrink: 0; width: 14px; text-align: center; }
.inbox__body { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--type-ui-compact); }
.inbox__marks { flex-shrink: 0; display: flex; gap: var(--space-1); color: var(--muted-2); }
.inbox__thumb { height: 28px; width: 44px; object-fit: cover; display: block; border: var(--border) solid var(--line-soft); border-radius: var(--radius); flex-shrink: 0; }
.inbox__time { flex-shrink: 0; }
.inbox__delete { border: 0; background: none; cursor: pointer; color: var(--muted); font-size: var(--text-md); line-height: 1; padding: 2px 4px; border-radius: var(--radius); }
.inbox__delete:hover { color: var(--ink); background: var(--surface-3); }
.inbox__empty { margin: var(--space-2) 0 0; color: var(--muted); }
.inbox__preview { margin: 0 0 var(--space-2); font-size: var(--type-ui-compact); color: var(--ink-soft); border-left: 2px solid var(--line); padding-left: var(--space-3); overflow-wrap: anywhere; }

/* --- Capture inbox icon + badge (story 104): the composer-bar door to the popover. --- */
.capture-icon { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; flex-shrink: 0; border: var(--border) solid var(--line); border-radius: var(--radius); background: var(--surface); color: var(--ink-soft); cursor: pointer; }
.capture-icon:hover { color: var(--ink); border-color: var(--ink); }
.capture-icon:focus-visible { outline: 0; box-shadow: var(--focus-ring); }
.capture-icon[aria-expanded="true"] { color: var(--ink); border-color: var(--ink); }
.capture-icon__glyph { font-size: var(--text-md); line-height: 1; }
/* The count badge: an ink pill on the top-right corner; hidden at zero (JS sets display). */
.capture-icon__badge { position: absolute; top: -6px; right: -6px; min-width: 16px; height: 16px; padding: 0 4px; display: inline-flex; align-items: center; justify-content: center; border-radius: 999px; background: var(--ink); color: var(--surface); font-size: 10px; line-height: 1; }

/* --- Capture inbox popover (story 104): pending rows + "Filed for you", anchored under the icon.
       Mechanics mirror the activity popover (fixed, clamped, a-pop). --- */
.captures-pop { position: fixed; z-index: 90; width: 360px; max-width: calc(100vw - 24px); display: flex; flex-direction: column; max-height: min(72vh, 620px); background: var(--surface); border: var(--border) solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-menu); overflow: hidden; animation: a-pop .12s ease; }
.captures-pop:focus { outline: 0; }
.captures-pop__head { flex-shrink: 0; padding: var(--space-3) var(--space-3) var(--space-2); }
.captures-pop__body { flex: 1; min-height: 0; overflow-y: auto; padding: 0 var(--space-3) var(--space-3); scrollbar-width: thin; }
.captures-pop__pending > .inbox__row:first-child { border-top: 0; }
.captures-pop__subhead { display: block; margin: var(--space-3) 0 var(--space-1); color: var(--muted); }
/* "Filed for you" rows: agent (or you) filed a capture → this entry, with a View link. */
.captures-filed__row { display: flex; align-items: center; gap: var(--space-3); padding: 8px 0; border-top: var(--border) solid var(--line-soft); }
.captures-filed__glyph { flex-shrink: 0; width: 14px; text-align: center; color: var(--muted-2); }
.captures-filed__text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--type-ui-compact); }
.captures-filed__by { color: var(--muted); }
.captures-filed__ctx { color: var(--muted); }
.captures-filed__time { flex-shrink: 0; }

/* --- /capture page (story 074b): bare, fast, phone-first --- */
.capture-page { min-height: 100dvh; display: flex; justify-content: center; align-items: flex-start; padding: max(6vh, var(--space-5)) var(--space-4); }
.capture-page__card { width: 100%; max-width: 480px; display: flex; flex-direction: column; gap: var(--space-3); }
.capture-page__head { display: flex; align-items: center; justify-content: space-between; }
.capture-page__ws { border: 0; background: none; cursor: pointer; color: var(--muted); }
.capture-page__ws:hover { color: var(--ink); }
.capture-page__field { resize: vertical; min-height: 76px; font-size: var(--type-body); }
.capture-page__actions { display: flex; align-items: center; gap: var(--space-3); }
/* 134 — hidden file inputs (triggered by the Image buttons) + a drop affordance. */
.capture-page__file, .inbox__file { display: none; }
.capture-page__card.is-drop { outline: 2px dashed var(--ink); outline-offset: 6px; border-radius: var(--radius); }
.capture-page__status { margin: 0; }
.capture-page__status--ok { color: var(--accent-green); }
.capture-page__list { display: flex; flex-direction: column; margin-top: var(--space-2); }
.capture-page__row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); padding: 7px 0; border-top: var(--border) solid var(--line-soft); }
.capture-page__body { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--type-ui-compact); color: var(--ink-soft); }

/* --- Code block upgrades (story 076): overlay highlight · gutter · controls ---
   The <pre> overlay sits under a transparent-text textarea; identical font/padding/
   wrapping keeps them pixel-aligned, and autogrow means neither ever scrolls. */
/* Code block (076 + issue-122/123/124/125). ONE typography source (--code-*) shared by
   the textarea, the highlight overlay, the gutter, and Read view — so the overlay aligns
   exactly with the text (previously the overlay was 13px while the textarea was 15px). */
/* VSCode/Zed-grade caret alignment: the transparent <textarea> and the highlight <pre>
   overlay MUST share an IDENTICAL box model — same font metrics, padding, ZERO border /
   letter-spacing / word-spacing, explicit box-sizing + tab-size + direction, and
   white-space:pre (no wrap → removes the whole caret-drift class). The visible border
   lives on the container (not the textarea, which would offset content 1px); the overlay
   is scroll-synced in JS. Colours come from the active [data-code-theme] (below). Line
   height is 1.5 → an integer line box at the default reading scale. */
:root { --code-size: calc(14px * var(--reading-scale, 1)); --code-lh: 1.5; }
.block-code { position: relative; display: flex; gap: 0; overflow: hidden;
  border: var(--border) solid var(--line-soft); border-radius: var(--radius); background: var(--chl-bg, var(--surface-2)); }
.block-code:focus-within { border-color: var(--line); }
.block-code__stack { position: relative; flex: 1; min-width: 0; }
/* The alignment invariant: overlay and textarea get exactly the same box model here. */
.block-code__hl, .block-code .block__code {
  box-sizing: border-box; margin: 0; border: 0; padding: 10px 12px;
  font-family: var(--font-mono); font-size: var(--code-size); line-height: var(--code-lh);
  font-weight: 400; font-style: normal; letter-spacing: 0; word-spacing: 0;
  tab-size: 2; -moz-tab-size: 2; direction: ltr; white-space: pre; overflow-wrap: normal; word-break: normal;
}
.block-code__hl { display: none; }
.block-code--hl .block-code__hl {
  display: block; position: absolute; inset: 0; pointer-events: none; overflow: hidden;
  color: var(--chl-fg, var(--ink)); background: transparent;
}
.block-code .block__code {
  display: block; width: 100%; resize: none; outline: none; overflow: hidden; border-radius: 0;
  background: var(--chl-bg, var(--surface-2)); color: var(--chl-fg, var(--ink)); caret-color: var(--chl-caret, var(--ink));
}
.block-code--hl .block__code { color: transparent; background: transparent; position: relative; z-index: 1; }
/* Issue 4 — wrap lines: flip BOTH the overlay and the textarea to soft-wrap together so the
   alignment invariant holds (same box model → caret stays on the glyph). No horizontal scroll
   when wrapping; long unbroken tokens break so nothing overflows the column. */
.block-code--wrap .block-code__hl, .block-code--wrap .block__code { white-space: pre-wrap; overflow-wrap: anywhere; word-break: normal; }
.block-code .block__code::selection { background: var(--chl-sel, var(--line-soft)); }
.block-code__gutter { display: none; }
.block-code--nums .block-code__gutter {
  display: block; box-sizing: border-box; margin: 0; padding: 10px 8px 10px 12px; text-align: right; min-width: 38px;
  font-family: var(--font-mono); font-size: var(--code-size); line-height: var(--code-lh); white-space: pre;
  color: var(--chl-gutter, var(--muted-2)); background: var(--chl-bg, var(--surface-2));
  border-right: var(--border) solid var(--line-soft); user-select: none;
}
/* Chrome overlay: top-right, revealed on hover/focus, absolutely positioned (no layout shift). */
/* The chrome follows the CODE theme's foreground (not the app ink), so its controls stay
   legible on the dark Midnight/Contrast surfaces as well as light Paper. */
.block-code__chrome {
  position: absolute; top: 6px; right: 6px; z-index: 3; display: flex; align-items: center; gap: var(--space-1);
  opacity: 0; transition: opacity 120ms ease; background: color-mix(in oklch, var(--chl-bg, var(--surface-2)) 92%, transparent);
  border: var(--border) solid color-mix(in oklch, var(--chl-fg, var(--ink)) 20%, transparent); border-radius: var(--radius); padding: 2px;
}
.block-code:hover .block-code__chrome, .block-code:focus-within .block-code__chrome { opacity: 1; }
@media (hover: none) { .block-code__chrome { opacity: 1; } }
.block-code__lang {
  font-family: var(--font-ui); font-size: var(--text-xs); color: var(--chl-fg, var(--ink-soft)); border: 0; background: transparent;
  padding: 2px 4px; border-radius: var(--radius); cursor: pointer; appearance: auto; max-width: 96px;
}
/* Native <select> popups follow the theme darkness so their options stay readable. */
[data-code-theme="midnight"] .block-code__lang, [data-code-theme="contrast"] .block-code__lang { color-scheme: dark; }
.block-code__ctl {
  display: grid; place-items: center; width: 24px; height: 22px; padding: 0; border: 0; border-radius: var(--radius);
  background: transparent; color: color-mix(in oklch, var(--chl-fg, var(--muted)) 62%, transparent); cursor: pointer;
}
.block-code__ctl:hover { background: color-mix(in oklch, var(--chl-fg, var(--ink)) 14%, transparent); color: var(--chl-fg, var(--ink)); }
.block-code__ctl.is-active { color: var(--chl-fg, var(--ink)); background: color-mix(in oklch, var(--chl-fg, var(--ink)) 16%, transparent); }
.block-code__copy .icon-check { display: none; }
.block-code__copy.is-copied { color: var(--accent-green); }
.block-code__copy.is-copied .icon-copy { display: none; }
.block-code__copy.is-copied .icon-check { display: block; }
/* --- Syntax token colours reference the active theme's vars (set by [data-code-theme]). --- */
.chl-kw { color: var(--chl-kw); }
.chl-str { color: var(--chl-str); }
.chl-num { color: var(--chl-num); }
.chl-com { color: var(--chl-com); }
.chl-fn { color: var(--chl-fn); }
.chl-type { color: var(--chl-type); }
.chl-bool { color: var(--chl-bool); }
.chl-op { color: var(--chl-op); }
.chl-punct { color: var(--chl-punct); }
.chl-prop { color: var(--chl-prop); }
.chl-regex { color: var(--chl-regex); }
.chl-cmd { color: var(--chl-cmd); }
.chl-flag { color: var(--chl-flag); }
.chl-var { color: var(--chl-var); }
.chl-builtin { color: var(--chl-builtin); }
.chl-md-h { color: var(--chl-md-h); font-weight: 700; }
.chl-md-mark, .chl-md-fence { color: var(--chl-md-mark); }
.chl-md-b { color: var(--chl-md-b); font-weight: 700; }
.chl-md-i { color: var(--chl-md-i); font-style: italic; }
.chl-md-code { color: var(--chl-md-code); }
.chl-md-quote { color: var(--chl-md-quote); }
.chl-md-link { color: var(--chl-md-link); }
.chl-md-url { color: var(--chl-md-url); text-decoration: underline; }
/* --- Code color themes (a GLOBAL editor preference, keyed by [data-code-theme]; Paper = default). --- */
:root, [data-code-theme="paper"] {
  --chl-bg:#fbfaf8; --chl-fg:#1c1b19; --chl-caret:#1c1b19; --chl-sel:rgba(91,91,214,.16); --chl-gutter:#a9a7a2;
  --chl-kw:#8a4b2f; --chl-str:#2f7d4f; --chl-num:#4a4ac0; --chl-com:#8a8880; --chl-fn:#2f6b8f; --chl-type:#7a5aa8;
  --chl-bool:#8a4b2f; --chl-op:#6a6862; --chl-punct:#9a9892; --chl-prop:#356a52; --chl-regex:#a05a3a;
  --chl-cmd:#2f6b8f; --chl-flag:#4a4ac0; --chl-var:#8a4b2f; --chl-builtin:#7a5aa8;
  --chl-md-h:#1c1b19; --chl-md-mark:#a9a7a2; --chl-md-b:#1c1b19; --chl-md-i:#3a3833; --chl-md-code:#8a4b2f;
  --chl-md-quote:#6a6862; --chl-md-link:#2f6b8f; --chl-md-url:#4a4ac0;
}
[data-code-theme="midnight"] {
  --chl-bg:#1a1b26; --chl-fg:#c9d1e6; --chl-caret:#c9d1e6; --chl-sel:rgba(122,162,247,.24); --chl-gutter:#565f89;
  --chl-kw:#c778dd; --chl-str:#a3d17a; --chl-num:#e6a56a; --chl-com:#6b7394; --chl-fn:#79b8ff; --chl-type:#5fd0c4;
  --chl-bool:#e6a56a; --chl-op:#8fa3d6; --chl-punct:#7a83a8; --chl-prop:#82c9ff; --chl-regex:#e08fb0;
  --chl-cmd:#79b8ff; --chl-flag:#e6a56a; --chl-var:#c778dd; --chl-builtin:#5fd0c4;
  --chl-md-h:#82aaff; --chl-md-mark:#6b7394; --chl-md-b:#e2e8f7; --chl-md-i:#c9d1e6; --chl-md-code:#a3d17a;
  --chl-md-quote:#8b93b5; --chl-md-link:#79b8ff; --chl-md-url:#5fd0c4;
}
[data-code-theme="contrast"] {
  --chl-bg:#0c0c0e; --chl-fg:#f4f4f6; --chl-caret:#ffffff; --chl-sel:rgba(255,214,10,.28); --chl-gutter:#8a8a92;
  --chl-kw:#ff8fd0; --chl-str:#7fe08a; --chl-num:#ffb347; --chl-com:#b7b7bf; --chl-fn:#6cc4ff; --chl-type:#5ee6d0;
  --chl-bool:#ffb347; --chl-op:#e4e4ea; --chl-punct:#b0b0b8; --chl-prop:#9ad4ff; --chl-regex:#ffa3c4;
  --chl-cmd:#6cc4ff; --chl-flag:#ffb347; --chl-var:#ff8fd0; --chl-builtin:#5ee6d0;
  --chl-md-h:#ffd60a; --chl-md-mark:#c6c6ce; --chl-md-b:#ffffff; --chl-md-i:#f4f4f6; --chl-md-code:#7fe08a;
  --chl-md-quote:#c6c6ce; --chl-md-link:#6cc4ff; --chl-md-url:#5ee6d0;
}

/* --- Pinned entries (story 080): intent shortcuts as a left-nav section --- */
.nav-pinned { margin-top: var(--space-3); }
.nav-pinned .nav-section { margin-bottom: 2px; }
.nav-row--pin { padding: 0; cursor: default; } /* nav-row__open provides padding, like section rows */
/* issue-126: a pin is a shortcut, not the active page — don't wear the left-beam that
   reads as "current nav". Live warmth (037/073) becomes a soft background wash instead,
   distinct from the active-nav border. (These come after the .is-warm rules, so they win.) */
.nav-row--pin { border-left-color: transparent; }
.nav-row--pin.is-warm { border-left-color: transparent; background: color-mix(in oklch, var(--accent-green) 12%, transparent); }
.nav-row--pin.is-warm--soft { border-left-color: transparent; background: color-mix(in oklch, var(--accent-green) 7%, transparent); }
.nav-row--pin.is-glow { border-left-color: transparent; background: color-mix(in oklch, var(--accent-green) 4%, transparent); }
/* issue-139: pinned rows carry a second, muted "Space › Section" line so duplicate/empty
   titles stay unambiguous. The open target becomes a two-line block. */
.nav-row__open--pin { align-items: flex-start; padding-top: 6px; padding-bottom: 6px; }
.nav-row__pinlabel { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; overflow: hidden; }
.nav-row__ctx { font-size: var(--type-meta); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-row__open--pin .section-icon { margin-top: 2px; }
/* Unpin control: a flex sibling of nav-row__open, so it reserves its own space (no
   overlap with the title). A muted pushpin at rest → the two-step "Unpin" pill. */
.nav-row__unpin { flex-shrink: 0; display: inline-flex; align-items: center; height: 30px; padding: 0 9px 0 4px; border: 0; background: none; color: var(--muted); cursor: pointer; }
.nav-row:hover .nav-row__unpin { color: var(--ink-soft); }
.pin-icon { display: inline-flex; } /* shared pushpin glyph (nav + entries rail) */
/* Armed (click 1): the pin gains a red slash (an "unpin" glyph); click again confirms.
   Both selectors carry .is-armed so they outrank `.nav-row:hover .nav-row__unpin`
   (the armed state is normally reached while hovering). */
.nav-row__unpin.is-armed, .nav-row:hover .nav-row__unpin.is-armed { color: var(--accent-red); }

/* --- Collection bar controls (filter · sort · view-toggle) --- */
.collection-bar__filter { width: 220px; height: 30px; }
.collection-bar__btn { display: inline-flex; align-items: center; gap: 5px; height: 30px; padding: 0 11px; border: var(--border) solid var(--line); border-radius: var(--radius); background: var(--surface); font-size: var(--type-ui-compact); color: var(--ink-soft); cursor: pointer; }
.collection-bar__caret { color: var(--muted-2); }
.collection-bar__clear { margin-left: 1px; padding: 0 4px; border-radius: var(--radius); color: var(--ink-soft); font-weight: 600; line-height: 1; }
.collection-bar__clear:hover { background: var(--surface-3); color: var(--ink); }
.view-toggle { display: inline-flex; border: var(--border) solid var(--line); border-radius: var(--radius); overflow: hidden; }
.view-toggle__btn { width: 32px; height: 30px; display: inline-flex; align-items: center; justify-content: center; border: 0; border-left: var(--border) solid var(--line); background: var(--surface); color: var(--ink-soft); cursor: pointer; }
.view-toggle__btn:first-child { border-left: 0; }
.view-toggle__btn.is-selected { background: var(--ink); color: var(--on-ink); }
.view-toggle__icon { display: inline-flex; }

/* Collection-bar dropdown (Labels ▾) */
.section-menu { display: flex; flex-direction: column; background: var(--surface); border: var(--border) solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-menu); z-index: 80; min-width: 160px; padding: 4px; animation: a-pop .12s ease; }
.section-menu__item { display: flex; align-items: center; gap: var(--space-2); height: 32px; padding: 0 var(--space-3); border: 0; background: none; text-align: left; font-size: var(--type-ui-compact); cursor: pointer; border-radius: var(--radius); }
.section-menu__item:hover, .section-menu__item:focus { background: var(--surface-3); outline: none; }
.section-menu__item.is-selected { font-weight: 600; }

/* --- Entry list view --- */
.entry-list { display: flex; flex-direction: column; }
.entry-row { display: flex; align-items: center; gap: var(--space-4); padding: 11px 4px; border-bottom: var(--border) solid var(--line-soft); cursor: pointer; }
.entry-row:hover { background: var(--surface-3); }
.entry-row__title { flex: 1; font-size: var(--type-ui-compact); font-weight: 500; display: flex; align-items: center; gap: 6px; min-width: 0; }
.entry-row__title > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.entry-row__date { flex-shrink: 0; }

/* --- Read view (article) --- */
/* === Section Read view (story-052) — a reading feed === */
/* A centred reading column (grid col 2) with a sticky index in the right gutter (col 3).
   The auto col 3 collapses to 0 when there's no index (single entry). (issue-075) */
.read { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, var(--read-w, 680px)) auto minmax(0, 1fr); align-items: start; --reading-scale: 1; }
.read__doc { grid-column: 2; grid-row: 1; min-width: 0; }
/* Reading prefs shared with the editor Aa control (story-052b). */
.read--width-s { --read-w: 600px; }
.read--width-l { --read-w: 860px; }
.read--text-s { --reading-scale: 0.9; }
.read--text-l { --reading-scale: 1.15; }
.read--align-left { grid-template-columns: 0 minmax(0, var(--read-w, 680px)) auto minmax(0, 1fr); } /* flush to the edge */
.read--align-leftpad { grid-template-columns: clamp(24px, 6vw, 100px) minmax(0, var(--read-w, 680px)) auto minmax(0, 1fr); }
.read--serif .read__title, .read--serif .read__h, .read--serif .read__p, .read--serif .read__col { font-family: var(--font-serif); }

/* scroll-margin-top so jumping to an entry lands it below the sticky top bar, not under it. */
.read__entry { padding: var(--space-6) 0; border-bottom: var(--border) solid var(--line-soft); scroll-margin-top: calc(53px + var(--space-4)); }
.read__entry:first-of-type { padding-top: var(--space-3); }
.read__title { margin: 0; font-size: calc(23px * var(--reading-scale)); letter-spacing: -0.02em; }
.read__title-link { color: inherit; text-decoration: none; }
.read__title-link:hover { text-decoration: underline; text-decoration-color: var(--muted-2); text-underline-offset: 3px; }
/* Byline — quiet one-line identity under the title (story-052c). */
.read__byline { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 6px 0 var(--space-4); font-family: var(--font-mono); font-size: var(--type-meta); letter-spacing: 0.04em; color: var(--muted); }
.read__h { font-size: calc(19px * var(--reading-scale)); margin: var(--space-4) 0 var(--space-2); }
.read__p { font-size: calc(16px * var(--reading-scale)); line-height: 1.7; margin: 0 0 var(--space-3); color: var(--ink); }
.read__p blockquote { border-left: 2px solid var(--ink); margin: 0; padding-left: var(--space-3); color: var(--ink-soft); }
.read__p ul, .read__p ol { margin: var(--space-2) 0; padding-left: var(--space-5); }
.read__p li { margin: 3px 0; padding-left: 2px; }
.read__p li::marker { color: var(--muted-2); }
/* Read-view code (issue-125): parity with the editor — highlight + optional gutter,
   shared --code-* typography. Wrap holds an optional line-number gutter beside the <pre>. */
/* Read view carries the same global code theme (so a dark theme's tokens sit on a dark surface). */
.read__code-wrap { display: flex; background: var(--chl-bg, var(--surface-3)); color: var(--chl-fg, var(--ink)); border-radius: var(--radius); overflow-x: auto; margin: var(--space-3) 0; }
.read__code-gutter { margin: 0; padding: var(--space-3) 8px var(--space-3) var(--space-3); text-align: right; color: var(--chl-gutter, var(--muted-2)); font-family: var(--font-mono); font-size: var(--code-size); line-height: var(--code-lh); user-select: none; border-right: var(--border) solid var(--line-soft); }
.read__code { flex: 1; min-width: 0; font-family: var(--font-mono); font-size: var(--code-size); line-height: var(--code-lh); background: none; color: inherit; padding: var(--space-3); border-radius: 0; margin: 0; }
.read__code-wrap .read__code { overflow: visible; }
/* A bare read__code (no wrap — shouldn't happen now, but keep it styled). */
.read__p + .read__code, article > .read__code { background: var(--surface-3); padding: var(--space-3); border-radius: var(--radius); overflow-x: auto; }
.read__img { max-width: 100%; border: var(--border) solid var(--line-soft); border-radius: var(--radius); margin: var(--space-2) 0; }
/* 063 — Read view figure/caption + spacing for the reused callout/knowledge cards. */
/* 130 — image + right-side caption on desktop; wraps below on a wide image / narrow screen. */
.read__figure { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--space-2) var(--space-4); margin: var(--space-4) 0; }
.read__figure .read__img { flex: 0 0 auto; margin: 0; }
.read__caption { flex: 1 1 12rem; min-width: 10rem; max-width: 34ch; align-self: flex-start; text-align: left; font-style: italic; color: var(--ink-soft); font-size: var(--type-meta); margin: 0; }
.read__entry .block-callout, .read__entry .block-knowledge { margin: 0 0 var(--space-3); }
/* Callout/knowledge text reads at the body size (they don't inherit .read__p) — 053b. */
.read__entry .block-callout__text, .read__entry .block-knowledge__text { font-size: calc(16px * var(--reading-scale)); }
.read__table { border-collapse: collapse; font-size: calc(14px * var(--reading-scale)); margin: var(--space-2) 0; }
.read__table td { border: var(--border) solid var(--line); padding: 6px 9px; }
/* Columns block in Read view (story-036d-i) — side-by-side, stacks on narrow widths. */
.read__columns { display: flex; gap: var(--space-5); align-items: flex-start; margin: var(--space-3) 0; }
/* Column text reads at the body size (it doesn't inherit .read__p) — 053b. */
.read__col { flex: 1 1 0; min-width: 0; font-size: calc(16px * var(--reading-scale)); line-height: 1.7; }
@media (max-width: 720px) { .read__columns { flex-direction: column; gap: var(--space-3); } }

/* Index (story-052d): a sticky right-gutter list of entry titles on wide screens. It
   aligns with the first headline, truncates long titles, and sticks below the top bar
   (top: bar height + gap) as you scroll — moving with the feed, then holding in view. */
.read__toc { grid-column: 3; grid-row: 1; justify-self: start; align-self: start; width: 190px; margin-left: calc(var(--space-6) + var(--space-2)); padding-top: var(--space-5); position: sticky; top: calc(53px + var(--space-5)); max-height: calc(100vh - 53px - var(--space-5) - var(--space-4)); overflow-y: auto; display: flex; flex-direction: column; gap: 7px; }
.read__toc-title { display: block; width: 100%; margin: 0 0 2px; padding: 0; text-align: left; background: none; border: 0; font: inherit; font-size: var(--type-ui-compact); font-weight: 600; letter-spacing: -0.01em; color: var(--ink); cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.read__toc-title:hover { text-decoration: underline; text-underline-offset: 2px; text-decoration-color: var(--muted-2); }
.read__toc-link { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--type-ui-compact); color: var(--ink-soft); text-decoration: none; padding-left: 10px; }
.read__toc-link:hover { color: var(--ink); }
/* Scrollspy — the entry you're currently reading. An inset left bar avoids any reflow. */
.read__toc-link.is-active { color: var(--ink); font-weight: 600; box-shadow: inset 2px 0 0 var(--ink); }

/* === Labels (story 062) — chips, the entry editor, and the section filter =========== */
.label-chips { display: inline-flex; flex-wrap: wrap; gap: 5px; align-items: center; vertical-align: middle; }
.label-chip { display: inline-flex; align-items: center; gap: 5px; max-width: 190px; padding: 1px 8px; border-radius: 999px;
  font-size: var(--text-xs); line-height: 1.6; color: var(--ink); background: var(--surface-3); border: 1px solid var(--line-soft); white-space: nowrap; }
.label-chip__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--chip, var(--accent-blue)); flex: none; }
.label-chip__name { overflow: hidden; text-overflow: ellipsis; }
.label-chip--more { color: var(--ink-soft); }
.label-chip__x { border: 0; background: none; color: var(--muted); cursor: pointer; font-size: 13px; line-height: 1; padding: 0 0 0 1px; }
.label-chip__x:hover { color: var(--ink); }

.label-editor { display: flex; flex-direction: column; gap: var(--space-2); }
.label-editor__chips { display: flex; flex-wrap: wrap; gap: 6px; }
.label-editor__chips:empty { display: none; }
.label-editor__add { position: relative; width: 100%; }
.label-editor__input { width: 100%; box-sizing: border-box; }
.label-editor__max { display: none; margin: 6px 0 0; color: var(--muted); } /* shown at the 8-label cap (UX review) */
.label-editor__menu { position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 40; display: none;
  background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius); box-shadow: var(--shadow-menu);
  max-height: 220px; overflow-y: auto; padding: 4px; }
.label-editor__menu.is-open { display: block; }
.label-editor__opt, .label-filter-menu__opt { display: flex; align-items: center; gap: var(--space-2); width: 100%; text-align: left; border: 0;
  background: none; cursor: pointer; padding: 6px 8px; border-radius: 6px; font-size: var(--type-ui-compact); color: var(--ink); }
.label-editor__opt:hover, .label-filter-menu__opt:hover { background: var(--surface-3); }
/* Keyboard-roving highlight mirrors :hover so the active option reads the same (issue-146). */
.label-editor__opt.is-active, .label-editor__opt[aria-selected="true"] { background: var(--surface-3); }
.label-editor__opt-name, .label-filter-menu__opt-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.label-editor__opt-use { color: var(--muted); }
.label-editor__opt--create { color: var(--ink-soft); font-style: italic; }

.label-filter-menu { position: fixed; z-index: 60; min-width: 190px; background: var(--surface); border: 1px solid var(--line-soft);
  border-radius: var(--radius); box-shadow: var(--shadow-menu); padding: 6px; }
.label-filter-menu__mode { display: flex; align-items: center; gap: 6px; padding: 2px 6px 8px; border-bottom: 1px solid var(--line-soft); margin-bottom: var(--space-1); }
.label-filter-menu__mode .label { margin-right: auto; }
.label-filter-menu__mode-btn { border: 1px solid var(--line-soft); background: var(--surface); color: var(--ink-soft); cursor: pointer;
  font-size: var(--type-meta); padding: 2px 11px; border-radius: 999px; }
.label-filter-menu__mode-btn.is-selected { background: var(--ink); color: var(--surface); border-color: var(--ink); }
.label-filter-menu__list { max-height: 244px; overflow-y: auto; }
.label-filter-menu__check { width: 14px; text-align: center; color: var(--ink); }
.label-filter-menu__opt.is-on { font-weight: 600; }

/* Manage-labels list in Space settings */
.labels-manager { display: flex; flex-direction: column; gap: 2px; }
.labels-manager__empty { padding: 4px 0; }
.labels-manager__row { display: flex; align-items: center; gap: var(--space-2); padding: 4px 0; }
.labels-manager__color { position: relative; flex: none; }
.labels-manager__dot { width: 16px; height: 16px; border-radius: 50%; background: var(--chip, var(--accent-blue)); border: 1px solid var(--line-soft); cursor: pointer; padding: 0; }
.labels-manager__colors { position: absolute; top: calc(100% + 4px); left: 0; z-index: 40; display: none; grid-template-columns: repeat(7, 16px); gap: 5px;
  background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius); box-shadow: var(--shadow-menu); padding: 6px; }
.labels-manager__colors.is-open { display: grid; }
.labels-manager__swatch { width: 16px; height: 16px; border-radius: 50%; border: 2px solid transparent; cursor: pointer; padding: 0; }
.labels-manager__swatch.is-selected { border-color: var(--ink); }
.labels-manager__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; cursor: text; }
.labels-manager__use { color: var(--muted); min-width: 18px; text-align: right; font-variant-numeric: tabular-nums; }
.labels-manager__del { border: 0; background: none; color: var(--muted); cursor: pointer; font-size: 16px; line-height: 1; padding: 0 2px; }
.labels-manager__del:hover { color: var(--accent-red); }
/* Not enough right gutter for a sidebar — fall back to a wrapped strip on top. */
@media (max-width: 1200px) {
  .read { display: block; max-width: var(--read-w, 680px); margin: 0 auto; }
  .read--align-left { margin-left: 0; }
  .read--align-leftpad { margin-left: clamp(24px, 6vw, 100px); }
  .read__toc { position: static; width: auto; margin-left: 0; padding-top: 0; max-height: none; overflow: visible; flex-direction: row; flex-wrap: wrap; align-items: baseline; gap: 8px 14px; padding-bottom: var(--space-4); margin-bottom: var(--space-4); border-bottom: var(--border) solid var(--line-soft); }
}
/* Show-more (story-052d). */
.read__more { display: flex; justify-content: center; margin: var(--space-5) 0 var(--space-2); }
/* Back-to-top — appears once scrolled (story-052d). */
.read__totop { position: fixed; right: var(--space-6); bottom: var(--space-6); width: 40px; height: 40px; border-radius: 50%; border: var(--border) solid var(--line); background: var(--surface); color: var(--ink); font-size: 18px; line-height: 1; cursor: pointer; box-shadow: var(--shadow-menu); opacity: 0; pointer-events: none; transform: translateY(6px); transition: opacity 0.18s ease, transform 0.18s ease; z-index: 60; }
.read__totop.is-visible { opacity: 1; pointer-events: auto; transform: none; }

/* --- Entry editor --- */
/* Ambient save dot: pulses amber while saving, fades to nothing once saved. */
.editor__status { width: 7px; height: 7px; border-radius: 50%; background: transparent; transition: background .3s ease, opacity .4s ease; flex-shrink: 0; }
.editor__status--editing { background: var(--line); }
.editor__status--saving { background: var(--accent-amber); animation: a-pulse 1.1s ease-in-out infinite; }
.editor__status--saved { background: transparent; }
.editor__status--error { background: var(--accent-red); }
@keyframes a-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

/* --- Presence cluster --- */
.presence { display: flex; }
.presence__avatar {
  width: 22px; height: 22px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--on-ink); font-size: 9px; font-weight: 600; font-family: var(--font-ui);
  border: 1.5px solid var(--surface); margin-left: -6px;
}
.presence__avatar:first-child { margin-left: 0; }
/* An MCP agent in the room (story 030b): square-ish + accent ring to read as non-human. */
.presence__avatar--agent { border-radius: 30%; box-shadow: 0 0 0 1.5px var(--surface), 0 0 0 3px var(--ink); }
/* 138 — a READING agent: swap the solid ring for a dashed one so "reading" reads distinct from
   "editing/present" without depending on colour or hover. Rule follows --agent so it wins. */
.presence__avatar--reading { box-shadow: 0 0 0 1.5px var(--surface); outline: 1.5px dashed var(--ink); outline-offset: 1.5px; }
/* "+N" overflow pill when more people are present than the cluster shows. */
.presence__more { background: var(--surface-3); color: var(--ink-soft); font-size: 8px; }

/* --- Editor title / label --- */
/* background:transparent — it's an <input>, so without this it falls back to the UA field
   colour (white on light themes, a grey slab on dark), which matches no theme surface. Sits
   directly on the editor canvas, so transparent is correct on every theme (cf. .inbox__field). */
.editor__title { width: 100%; border: 0; outline: none; background: transparent; font-family: var(--font-ui); font-size: 30px; font-weight: 600; letter-spacing: -0.02em; padding: 0; margin-bottom: var(--space-4); }
.editor__label { width: 200px; }
.editor__blocks { display: flex; flex-direction: column; gap: 3px; }
/* 074 — persistent remote-change banner: sticks to the top of the writing column, quiet but
   actionable, until the user Reloads (applies) or an idle refetch clears it. Full column width. */
.remote-notice { position: sticky; top: 0; z-index: 20; width: 100%; max-width: 720px; box-sizing: border-box;
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  margin: 0 0 var(--space-3); padding: 8px var(--space-3); border: var(--border) solid var(--line);
  border-radius: var(--radius); background: var(--surface-2); box-shadow: var(--shadow-menu); }
.remote-notice[hidden] { display: none; }
.remote-notice__text { font-size: var(--type-ui-compact); color: var(--ink-soft); }
.remote-notice__reload { border: 0; background: var(--ink); color: var(--surface); font-size: var(--type-ui-compact);
  font-family: var(--font-ui); padding: 4px 12px; border-radius: 6px; cursor: pointer; white-space: nowrap; }
.remote-notice__reload:hover { opacity: .9; }

/* --- Block row: the body is flush; one quiet handle overlays the left margin. */
.block { position: relative; animation: a-fade .14s ease; }
/* A co-editor / agent is writing this block: frame it and label it with a tab, so
   nothing overlays the text (was: an absolute label sitting on the first line). */
.block--locked { box-shadow: 0 0 0 1px var(--line); border-radius: var(--radius); background: var(--surface-2); padding: 20px 12px 8px; transition: box-shadow .18s ease, padding .18s ease, background .18s ease; }
.block--drop { box-shadow: inset 0 2px 0 var(--ink); }
/* 036e — multi-block selection: a calm monochrome wash. The 3px halo bridges the
 * inter-block gap so a selected range reads as one continuous block. */
/* Calm, monochrome text selection in the editor — so a drag that starts as text-select
   flows into the grey block-select without a blue→grey jump (same tint as the wash below). */
.editor__main ::selection { background: var(--line-soft); }
.block--selected { background: var(--line-soft); box-shadow: 0 0 0 3px var(--line-soft); border-radius: var(--radius); }
.block--selected:focus { outline: none; }
.block--selected .block__gutter { opacity: 1; }
.block__gutter { position: absolute; left: -30px; top: 4px; opacity: 0; transition: opacity .12s ease; display: inline-flex; gap: 2px; align-items: center; }
.block:hover .block__gutter, .block:focus-within .block__gutter { opacity: 1; }
.block__handle { cursor: grab; color: var(--muted); font-size: 14px; border: 0; background: none; line-height: 1; width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; border-radius: var(--radius); }
.block__handle:hover { color: var(--ink); background: var(--surface-3); }
/* The lock tab: a small ink chip with a padlock glyph, tucked at the top-left inside
   the frame — text set by JS (`<name> editing`); shown only when non-empty. */
.block__lock-label { position: absolute; top: 5px; left: 12px; z-index: 2; display: none; align-items: center; gap: 5px; background: var(--ink); color: var(--on-ink); font-family: var(--font-mono); font-size: 9px; line-height: 1.2; text-transform: uppercase; letter-spacing: .07em; padding: 3px 7px; border-radius: 3px; white-space: nowrap; }
.block__lock-label:not(:empty) { display: inline-flex; }
.block__lock-label::before { content: ""; width: 8px; height: 9px; flex-shrink: 0; background: currentColor; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='M3.5 6V4.5a3.5 3.5 0 0 1 7 0V6H11a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h.5zm1.5 0h4V4.5a2 2 0 0 0-4 0V6z'/%3E%3C/svg%3E") center/contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='M3.5 6V4.5a3.5 3.5 0 0 1 7 0V6H11a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h.5zm1.5 0h4V4.5a2 2 0 0 0-4 0V6z'/%3E%3C/svg%3E") center/contain no-repeat; }

/* --- Block bodies: rich text / code / divider --- */
.block__rich { outline: none; font-family: var(--font-ui); font-size: var(--type-body); line-height: 1.7; padding: 3px 0; color: var(--ink); }
.block__rich--h { font-size: var(--type-heading-sm); font-weight: 600; }
/* Placeholder only on the focused empty block (no repeated hints). */
.block__rich:empty:focus::before { content: attr(data-placeholder); color: var(--muted); pointer-events: none; }
.block__rich blockquote { border-left: 2px solid var(--ink); margin: 0; padding-left: var(--space-3); color: var(--ink-soft); }
.block__rich h2 { font-size: var(--type-heading-sm); font-weight: 600; margin: 0; }
.block__rich ul, .block__rich ol { margin: 4px 0; padding-left: var(--space-5); }
.block__rich li { margin: 3px 0; padding-left: 2px; }
.block__rich li::marker { color: var(--muted-2); }
.block__rich li > ul, .block__rich li > ol { margin: 3px 0; } /* nested lists sit tight to their item */
/* Content links read as links — an underline affordance (monochrome; the global
   `a { text-decoration:none }` reset otherwise made an added link look like plain
   text). Accents stay area-markers, so no link colour. Editor + Read view. */
.block__rich a, .read__entry a { text-decoration: underline; text-decoration-color: var(--muted-2); text-decoration-thickness: 1px; text-underline-offset: 2px; cursor: pointer; }
.block__rich a:hover, .read__entry a:hover { text-decoration-color: var(--ink); }
/* 058 — inline entry links: a quiet mono chip (thin border, near-square), distinct from
   an underlined external link, so "this points inside Atomo" reads at a glance. */
.entry-link {
  display: inline; padding: 0 4px; border: var(--border) solid var(--line);
  border-radius: 3px; background: var(--surface-2); color: var(--ink);
  text-decoration: none; white-space: nowrap; cursor: pointer;
}
.block__rich a.entry-link, .read__entry a.entry-link { text-decoration: none; }
.entry-link:hover { border-color: var(--ink); }
.entry-link::before { content: "↳ "; color: var(--muted); font-size: .85em; }
/* A deleted target: inert, dimmed, struck — the link is provenance, not a 404 trip.
   Qualified with the container so it outranks `.block__rich a`/`.read__entry a`
   (0,1,1), which would otherwise keep the pointer cursor on an inert link. */
.entry-link--gone,
.block__rich a.entry-link--gone, .read__entry a.entry-link--gone {
  color: var(--muted); text-decoration: line-through; cursor: default;
}
.entry-link--gone:hover { border-color: var(--line); }
/* Code: a hairline frame + a faint tint, not a heavy grey fill. */
.block__code { width: 100%; border: var(--border) solid var(--line-soft); outline: none; resize: none; overflow-y: hidden; font-family: var(--font-mono); font-size: var(--text-sm); background: var(--surface-2); padding: var(--space-3); border-radius: var(--radius); color: var(--ink); }
.block__code:focus { border-color: var(--line); }
.block--divider hr { border: 0; border-top: var(--border) solid var(--line-soft); margin: var(--space-3) 0; }

/* 036c — callout blocks: icon + thin accent rule + a calm marker tint (never a saturated fill) */
.block-callout { display: flex; gap: var(--space-3); align-items: flex-start; border-left: 2px solid var(--line); border-radius: 0 var(--radius) var(--radius) 0; padding: 12px 14px; }
/* Fixed-width icon column so every callout's text starts at the same x — different
   glyphs (ℹ ✓ ⚠ ✎) render at different natural widths and were ragged (053b). */
.block-callout__icon { flex-shrink: 0; width: 20px; text-align: center; font-size: var(--text-lg); line-height: 1.7; }
.block-callout__text { flex: 1; min-width: 0; }
.block-callout.is-info { background: var(--callout-info-bg); border-left-color: var(--callout-info-edge); }
.block-callout.is-tip { background: var(--callout-tip-bg); border-left-color: var(--callout-tip-edge); }
.block-callout.is-warning { background: var(--callout-warn-bg); border-left-color: var(--callout-warn-edge); }
.block-callout.is-note { background: var(--callout-note-bg); border-left-color: var(--callout-note-edge); }
.block-callout.is-quote { background: transparent; border-left-color: var(--ink); }
.block-callout.is-quote .block-callout__text { font-family: var(--font-serif); font-style: italic; color: var(--ink-soft); }

/* 036c — collapsible headings: a fold chevron in the gutter + a folded-count badge
 * (the base .block__gutter rule above also carries the inline-flex layout). */
.block--heading .block__gutter { left: -54px; }
.block__fold { border: 0; background: none; color: var(--muted); cursor: pointer; font-size: 13px; width: 24px; height: 24px; border-radius: var(--radius); line-height: 1; }
.block__fold:hover { color: var(--ink); background: var(--surface-3); }
.block.is-folded .block__gutter { opacity: 1; }
.is-hidden-by-fold { display: none !important; }
.block.is-folded { display: flex; align-items: baseline; gap: 10px; }
.block__fold-count { font-family: var(--font-mono); font-size: 11px; color: var(--muted); }

/* 036h — knowledge-native blocks: a quiet mono tag chip (Decision/Finding/Spec) or a checkbox (Action) */
.block-knowledge { display: flex; gap: 9px; align-items: baseline; }
/* Fixed-width tag column so Decision / Finding / Spec all align their text (their labels
   have different lengths, which left the text ragged) — a tidy status-badge column (053b). */
.block-knowledge__tag { flex-shrink: 0; box-sizing: border-box; width: 74px; text-align: center; font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); border: var(--border) solid var(--line); border-radius: var(--radius); padding: 1px 6px; }
.block-knowledge__text { flex: 1; min-width: 0; }
/* Custom monochrome checkbox — the native control was the one OS-blue element in a
   mono UI (blue is reserved for the focus ring). A 2px-corner square that fills with
   ink + a checkmark when done; the global :focus-visible ring still applies. */
.block-knowledge__check {
  appearance: none; -webkit-appearance: none;
  /* Centre the 16px box on the FIRST line of body text rather than its baseline.
     Body line-height is 17px × 1.75 ≈ 29.75px, so (29.75 − 16) / 2 ≈ 7px. */
  flex-shrink: 0; align-self: flex-start; margin-top: 7px;
  /* A checkbox reads as a to-do — keep it close to its label (just the flex gap), rather
     than pushed out to the tag column (053b). */
  margin-right: 6px;
  width: 16px; height: 16px;
  border: var(--border) solid var(--muted-2); border-radius: var(--radius);
  background: var(--surface); cursor: pointer; position: relative;
  transition: background .12s ease, border-color .12s ease;
}
.block-knowledge__check:not(:disabled):hover { border-color: var(--ink); }
.block-knowledge__check:checked { background: var(--ink); border-color: var(--ink); }
.block-knowledge__check:checked::after {
  content: ""; position: absolute; left: 5px; top: 2px; width: 4px; height: 8px;
  border: solid var(--surface); border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.block-knowledge__check:disabled { cursor: default; } /* read view */
.block-knowledge.is-done .block-knowledge__text { color: var(--muted); text-decoration: line-through; }

/* --- Action assignee (story 063): a trailing chip that opens the you/agent picker.
   Ghosted when unassigned so a plain to-do stays clean, then surfaces on row hover /
   focus; an assigned chip is always visible. Keyboard path: "@" in the action text. --- */
.block-knowledge__assignee {
  flex-shrink: 0; align-self: center; display: inline-flex; align-items: center; gap: 5px;
  margin-left: var(--space-2); padding: 2px 9px; height: 22px; box-sizing: border-box;
  border: var(--border) solid var(--line); border-radius: 999px;
  background: var(--surface); color: var(--ink); cursor: pointer;
  font-size: var(--type-meta); line-height: 1;
  transition: border-color .12s ease, color .12s ease, opacity .12s ease;
}
.block-knowledge__assignee:hover { border-color: var(--ink); }
.block-knowledge__assignee-glyph { font-size: 12px; line-height: 1; color: var(--muted); }
.block-knowledge__assignee-name { font-size: var(--type-meta); }
/* Unassigned: a dashed "＋" ghost — hidden until the row is hovered or the chip is focused. */
.block-knowledge__assignee--empty { border-style: dashed; padding: 2px 7px; color: var(--muted); opacity: 0; }
.block:hover .block-knowledge__assignee--empty,
.block--editing .block-knowledge__assignee--empty,
.block-knowledge__assignee--empty:focus-visible { opacity: 1; }
/* Small round initials avatar for the owner (chip + assignee picker). */
.block-knowledge__avatar {
  flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--surface-3); color: var(--ink);
  font-family: var(--font-mono); font-size: 9px; letter-spacing: 0; text-transform: uppercase;
}

/* --- Open-actions rollup (036h): unfinished actions across an section, checkable in place --- */
/* Same shell as .board (shared header + hairline rows) so the two panels read as peers. */
.open-actions { border: var(--border) solid var(--line); border-radius: var(--radius); margin: var(--space-5) 0 var(--space-4); background: var(--surface); display: flex; flex-direction: column; }
.open-actions__head { display: flex; align-items: center; gap: var(--space-2); width: 100%; padding: var(--space-2) var(--space-3); border: 0; border-bottom: var(--border) solid var(--line-soft); background: none; color: var(--ink); }
.open-actions__title { margin: 0; font-size: var(--type-heading-sm); font-weight: 600; letter-spacing: -0.01em; }
.open-actions__count { font-family: var(--font-mono); font-size: var(--type-meta); color: var(--muted); border: var(--border) solid var(--line); border-radius: var(--radius); padding: 0 6px; }
.open-actions__list { display: flex; flex-direction: column; min-width: 0; }
/* min-width:0 + overflow:hidden cut the nowrap min-content chain so a long action
 *  text truncates (ellipsis) instead of widening the row → main → whole page. */
.open-actions__row { display: flex; align-items: center; gap: 9px; min-width: 0; overflow: hidden; padding: 8px var(--space-3); border-top: var(--border) solid var(--line-soft); }
.open-actions__list .open-actions__row:first-child { border-top: 0; }
.open-actions__row:hover { background: var(--surface-3); }
.open-actions__row .block-knowledge__check { margin-top: 0; align-self: center; }
.open-actions__row--done { opacity: .5; }
.open-actions__row--done .open-actions__text { text-decoration: line-through; }
/* Peer panel to Resume (Atomo issue 43): primary rows share the compact role and the
   count shares the meta token, so neither right-panel sibling reads heavier. */
.open-actions__text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--type-ui-compact); }
.open-actions__entry { flex-shrink: 0; max-width: 34%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--type-ui-compact); color: var(--muted); border: 0; background: none; cursor: pointer; }
.open-actions__entry:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }
.open-actions__by { flex-shrink: 0; font-size: var(--type-meta); color: var(--muted); } /* ✦ agent provenance (036h) */
/* Assignee marker in the rollup (story 063): who should do it (agent / owner). */
.open-actions__assignee { flex-shrink: 0; font-size: var(--type-meta); color: var(--muted); border: var(--border) solid var(--line); border-radius: 999px; padding: 1px 8px; }

/* --- Format toolbar (shown while a rich block is focused) --- */
/* 036b — selection toolbar: a light hairline card (matches popupMenu), inline marks only */
.fmt { display: none; gap: 1px; align-items: center; background: var(--surface); border: var(--border) solid var(--line); padding: 3px; border-radius: var(--radius); width: max-content; }
/* Floating selection toolbar: positioned above the selection, JS-toggled. */
.fmt--floating { position: fixed; transform: translateX(-50%); z-index: 90; box-shadow: var(--shadow-menu); animation: a-pop .12s ease; }
.fmt__btn { border: 0; background: none; color: var(--ink); font-size: 13px; padding: 4px 8px; cursor: pointer; font-family: var(--font-ui); border-radius: 3px; line-height: 1; }
.fmt__btn:hover { background: var(--surface-3); }
.fmt__btn--b { font-weight: 700; }
.fmt__btn--i { font-style: italic; }
.fmt__btn--u { text-decoration: underline; }
.fmt__btn--s { text-decoration: line-through; }
.fmt__btn--code { font-family: var(--font-mono); font-size: 11px; }
.fmt__btn--clear { color: var(--muted); }
.fmt__sep { width: 1px; height: 16px; background: var(--line); margin: 0 2px; }
/* Highlight marker popover + the authoring markers (provisional palette — pending sign-off) */
.fmt-markers { position: fixed; z-index: 95; display: flex; gap: 6px; background: var(--surface); border: var(--border) solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-menu); padding: 8px; }
.fmt-markers button { width: 22px; height: 22px; border-radius: 3px; border: var(--border) solid var(--line-soft); cursor: pointer; padding: 0; }
.fmt-markers .mk-none { position: relative; background: var(--surface); }
.fmt-markers .mk-none::after { content: "⁄"; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: var(--muted); }
.block__rich mark { border-radius: var(--radius); padding: 0 1px; color: inherit; }
.block__rich code { font-family: var(--font-mono); font-size: 0.88em; background: var(--surface-3); padding: 1px 4px; border-radius: 3px; }
.mk-yellow { background: var(--mark-yellow); }
.mk-green { background: var(--mark-green); }
.mk-blue { background: var(--mark-blue); }
.mk-rose { background: var(--mark-rose); }
.mk-grey { background: var(--mark-grey); }
/* 047 — inline text colour: <span class="fc-…"> wraps + the toolbar "A" button. */
.fc-blue { color: var(--accent-blue); }
.fc-green { color: var(--accent-green); }
.fc-amber { color: var(--accent-amber); }
.fc-red { color: var(--accent-red); }
.fc-purple { color: var(--accent-purple); }
.fmt__btn--fc { position: relative; }
.fmt__btn--fc::after { content: ""; position: absolute; left: 4px; right: 4px; bottom: 3px; height: 2px; border-radius: 1px;
  background: linear-gradient(90deg, var(--accent-blue), var(--accent-green), var(--accent-amber), var(--accent-red), var(--accent-purple)); }

/* --- Block picker menu --- */
.block-picker { display: flex; flex-direction: column; background: var(--surface); border: var(--border) solid var(--ink); border-radius: var(--radius); box-shadow: var(--shadow-menu); z-index: 80; min-width: 140px; }
.block-picker__item { display: flex; align-items: center; height: 32px; padding: 0 var(--space-3); border: 0; background: none; text-align: left; font-size: var(--type-ui-compact); cursor: pointer; }
.block-picker__item:hover { background: var(--surface-3); }
.block-picker__item:focus { background: var(--ink); color: var(--on-ink); outline: none; }
.block-picker__query { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-3); padding: 5px var(--space-3); font-family: var(--font-mono); font-size: var(--type-meta); color: var(--muted); border-bottom: var(--border) solid var(--line-soft); }
.block-picker__query-hint { font-family: var(--font-ui); color: var(--muted); white-space: nowrap; }
/* Keyboard hint shown right-aligned in a menu row (036e). */
.menu-hint { margin-left: auto; padding-left: var(--space-4); font-family: var(--font-mono); font-size: var(--type-meta); color: var(--muted); }
.block-picker__item:focus .menu-hint { color: var(--on-ink-muted); }
/* Slash-menu richness (041a): category headers, per-item icon + description. */
.block-picker--rich { min-width: 248px; }
.block-picker__group { padding: 6px var(--space-3) 2px; font-family: var(--font-mono); font-size: var(--type-meta); color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.block-picker__group:first-child { padding-top: 4px; }
.block-picker--rich .block-picker__item { height: auto; padding: 6px var(--space-3); gap: var(--space-3); align-items: flex-start; }
.block-picker__icon { flex: 0 0 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center; font-family: var(--font-mono); font-size: var(--text-sm); border: var(--border) solid var(--line); border-radius: 4px; color: var(--ink); }
.block-picker__item:focus .block-picker__icon { border-color: var(--on-ink-dim); color: var(--on-ink); }
.block-picker__text { display: flex; flex-direction: column; line-height: 1.25; }
.block-picker__label { font-size: var(--type-ui-compact); }
.block-picker__desc { font-size: var(--type-meta); color: var(--muted); }
.block-picker__item:focus .block-picker__desc { color: var(--on-ink-soft); }

/* 090 — Connections block (third pass, owner-calibrated middle): the first pass's
   anatomy — two labelled groups (LINKED FROM · RELATED) of quiet button rows with
   accent dot · title · section name · sim % — but framed in the entry's own dialect:
   a callout/blockquote-style LEFT rule, not a fully boxed card (that box was the
   canvas's only perimeter-framed element and read as a foreign widget). */
.block-conn { border-left: 2px solid var(--line); padding: 2px 0 2px var(--space-4); display: flex; flex-direction: column; gap: var(--space-3); }
.block-conn__group { display: flex; flex-direction: column; gap: 1px; }
.block-conn__heading { color: var(--muted); margin-bottom: 3px; }
.block-conn__row { display: flex; align-items: center; gap: var(--space-2); width: 100%; text-align: left; border: 0; background: none; padding: 4px 6px; cursor: pointer; border-radius: var(--radius); min-width: 0; }
.block-conn__row:hover { background: var(--surface-3); }
.block-conn__row .section-dot { flex-shrink: 0; width: 7px; height: 7px; }
/* issue-198: title one step up (sm → md) so linked/related entries scan easily; meta
   and similarity stay secondary but get an explicit readable size, not tiny. */
.block-conn__title { font-size: var(--type-ui-compact); color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.block-conn__meta { font-size: var(--type-meta); color: var(--muted); flex-shrink: 0; }
.block-conn__sim { margin-left: auto; font-size: var(--type-meta); color: var(--muted); flex-shrink: 0; font-variant-numeric: tabular-nums; }
.block-conn__empty, .block-conn__loading { color: var(--muted); padding: 2px 6px; }

/* 058 — "@" mention picker: block-picker chrome, but the active row is class-driven
   (focus stays in the editable while the picker filters), and the list has a calm
   empty/typing hint. */
.mention-picker { min-width: 220px; max-width: 320px; }
.mention-picker .block-picker__item { width: 100%; }
.mention-picker .block-picker__item.is-active { background: var(--ink); color: var(--on-ink); }
.mention-picker .block-picker__item.is-active .block-picker__icon { border-color: var(--on-ink-dim); color: var(--on-ink); }
.mention-picker .block-picker__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mention-picker__hint { padding: 8px var(--space-3); }

/* --- 036e — multi-block action-bar (surface 3): batched ops over a selection.
 * Mirrors the floating selection toolbar's hairline-card language. --- */
.block-bar { position: fixed; z-index: 92; display: none; gap: 2px; align-items: center; background: var(--surface); border: var(--border) solid var(--line); padding: 3px 4px; border-radius: var(--radius); box-shadow: var(--shadow-menu); width: max-content; animation: a-pop .12s ease; }
.block-bar__btn { border: 0; background: none; color: var(--ink); font-size: 12px; padding: 4px 8px; cursor: pointer; font-family: var(--font-ui); border-radius: 3px; line-height: 1; }
.block-bar__btn:hover { background: var(--surface-3); }
.block-bar__btn--danger { color: var(--accent-red); }
.block-bar__btn--danger:hover { background: var(--accent-red); color: var(--on-ink); }
.block-bar__sep { width: 1px; height: 16px; background: var(--line); margin: 0 2px; }
.block-bar__count { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted); padding: 0 6px 0 4px; white-space: nowrap; }

/* --- Image block --- */
.block-image__img { max-width: 100%; border: var(--border) solid var(--line-soft); border-radius: var(--radius); display: block; cursor: zoom-in; }
/* 062 — image figure: caption reads as a figcaption; alt is editorial metadata.
   048 — figure shrink-wraps the image and a % width keeps it responsive (never
   wider than the column); a corner handle resizes it. */
/* 130 — the figure is a flex-wrap row so a written caption sits beside the image (right
   column). An empty caption (:placeholder-shown) drops to a full-width basis so it never
   reserves awkward blank side space; a wide image or a narrow screen also wraps it below. */
.block-image__figure { margin: 0; display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--space-2) var(--space-4); max-width: 100%; }
/* Shrink-wraps the image (fit-content, capped at the figure width) so the resize beam
   always hugs the image's right edge even when the figure is wider than a small image (issue-108). */
.block-image__imgwrap { position: relative; display: block; width: fit-content; max-width: 100%; flex: 0 0 auto; }
.block-image__caption { flex: 1 1 12rem; min-width: 10rem; max-width: 34ch; align-self: flex-start; margin-top: 2px; border: 0; background: none; text-align: left; font-style: italic; color: var(--ink-soft); font-size: var(--type-ui-compact); padding: 6px 0 2px; outline: none; }
.block-image__caption:placeholder-shown { flex-basis: 100%; min-width: 0; max-width: none; text-align: center; } /* empty → below the image */
.block-image__caption::placeholder { color: var(--muted); font-style: italic; }
.block-image__meta { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-1); }
/* 048 — keep the technical bits (caption, alt, replace) + resize handle out of sight
   until you hover or are editing the block, like the table controls. */
.block-image__caption, .block-image__meta, .block-image__resize { opacity: 0; transition: opacity .12s ease; }
.block-image:hover .block-image__caption, .block-image:focus-within .block-image__caption,
.block-image:hover .block-image__meta, .block-image:focus-within .block-image__meta,
.block-image:hover .block-image__resize, .block-image:focus-within .block-image__resize { opacity: 1; }
.block-image__caption:not(:placeholder-shown) { opacity: 1; } /* a written caption always shows */
/* 108 — resize is a vertical beam on the image's right edge (not a corner box); the
   drag maps clientX → width, so a right-edge grip reads correctly. */
.block-image__resize { position: absolute; right: 3px; top: 50%; transform: translateY(-50%); width: 6px; height: 42px; padding: 0; cursor: ew-resize;
  border: 0; border-radius: 4px; background: var(--ink); box-shadow: 0 0 0 2px var(--surface); }
.block-image__resize:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: 2px; }
/* 108 — alt text lives in a small popover off the main surface (not a permanent form row). */
.block-image__altwrap { position: relative; display: inline-flex; }
.block-image__altpop { position: absolute; z-index: 30; left: 0; bottom: calc(100% + 6px); min-width: 240px;
  background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius); box-shadow: var(--shadow-menu); padding: 6px; }
.block-image__altpop[hidden] { display: none; }
.block-image__alt { width: 100%; box-sizing: border-box; font-family: var(--font-mono); font-size: var(--type-meta); color: var(--ink); border: var(--border) solid var(--line-soft); border-radius: var(--radius); padding: 6px 8px; background: var(--surface-2); outline: none; }
.block-image__alt:focus { border-color: var(--line); }
.block-image__empty { display: flex; flex-direction: column; gap: var(--space-2); border: var(--border) dashed var(--line-soft); border-radius: var(--radius); padding: var(--space-4); transition: border-color .12s ease, background .12s ease; }
.block-image__empty.is-drop { border-color: var(--ink); background: var(--surface-3); }
.block-image__controls { display: flex; gap: var(--space-2); align-items: center; }
.block-image__controls .input { flex: 1; }
.block-image__file { display: none; }

/* --- Table block: hairline cells; controls only on hover --- */
/* A wide table scrolls horizontally inside this box instead of overflowing the
   writing column on a narrow viewport (issue-148). */
/* position: relative — the Issue 5 column-resize beams are absolutely positioned children,
   so they live in the scrolled content and stay glued to their column border.
   overflow-y is explicitly hidden (Issue 11): `overflow-x: auto` alone computes overflow-y
   to auto, so any sub-pixel overhang (a resize beam on a fractional table height) made the
   box vertically scrollable and drew a phantom vertical scrollbar. Only horizontal
   scrolling is ever wanted here — the container wraps the table's full height. */
.block-table__scroll { overflow-x: auto; overflow-y: hidden; max-width: 100%; position: relative; }
/* Issue 5 — column resize: an invisible 9px grab strip centred on each column border
   (cursor signals it); a thin ink beam fades in on hover/focus, like the image handle. */
.block-table__resize { position: absolute; width: 9px; transform: translateX(-50%); padding: 0; border: 0; background: none; cursor: col-resize; z-index: 2; }
.block-table__resize::after { content: ""; position: absolute; inset: 2px 3px; background: var(--ink); opacity: 0; border-radius: 2px; transition: opacity .12s ease; }
.block-table__resize:hover::after { opacity: .55; }
.block-table__resize:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: -2px; }
.block-table__resize:focus-visible::after { opacity: .55; }
.block-table__table { border-collapse: collapse; width: 100%; font-size: var(--type-ui-compact); }
/* `height` on a table cell acts as a MINIMUM (content still grows it), and unlike
   `min-height` it's honoured on table-cell boxes — so a fresh EMPTY row reserves a
   comfortable, clickable height in Firefox too, not just Chrome (issue-106). `em`
   keeps it in step with the reading-scale font. */
.block-table__cell { border: var(--border) solid var(--line-soft); padding: 6px 9px; min-width: 60px; height: 2.6em; outline: none; }
/* Issue 6 — cells carry .block__rich (for the selection toolbar) but keep table typography:
   inherit the table's font-size/line-height instead of the full-block reading grade. */
.block-table__cell.block__rich { font-size: inherit; line-height: inherit; padding: 6px 9px; }
.block-table__cell:focus { box-shadow: inset 0 0 0 1px var(--ink); }
/* Header row (041b): the first row reads as column headers. */
.block-table__cell--head { background: var(--surface-2); font-weight: 600; text-align: left; }
.block-table__controls { display: flex; gap: var(--space-2); margin-top: var(--space-2); opacity: 0; transition: opacity .12s ease; }
.block-table:hover .block-table__controls, .block-table:focus-within .block-table__controls { opacity: 1; }
/* Per-row / per-column delete controls (041b): appear on hover. The control cells collapse
   to zero size and the delete buttons float OUT of the table's flow, so the table's data
   lines up with the rest of the content and never shifts on hover (053b). */
/* Issue 9 follow-up: the delete ×s overlay the WRAP, not the table — the issue-148 scroll
   box clips its overflow, which had silently hidden the in-table control cells ever since.
   JS places them (same reflow machinery as the resize beams); wrap is their offset parent. */
.block-table { position: relative; }
.block-table__del { width: 16px; height: 16px; line-height: 1; padding: 0; border: 0; background: none; color: var(--muted); cursor: pointer; font-size: var(--text-md); opacity: 0; transition: opacity .12s ease, color .12s ease; }
.block-table__del--col { position: absolute; transform: translateX(-50%); z-index: 2; }
.block-table__del--row { position: absolute; transform: translateY(-50%); z-index: 2; }
.block-table:hover .block-table__del, .block-table:focus-within .block-table__del { opacity: .55; }
.block-table__del:hover { opacity: 1; color: var(--danger, #c0392b); }

/* Columns block (story-036d-i): 2–4 even rich-text columns, hairline gutter. */
.block-columns { display: flex; gap: var(--space-4); align-items: flex-start; width: 100%; }
.block-columns__col { flex: 1 1 0; min-width: 0; position: relative; padding-left: var(--space-4); border-left: var(--border) solid var(--line-soft); }
.block-columns__col:first-child { padding-left: 0; border-left: 0; }
.block-columns__rich { outline: none; min-height: 1.6em; }
.block-columns__rm { position: absolute; top: 0; right: 0; width: 18px; height: 18px; padding: 0; border: 0; background: none; color: var(--muted); font-size: 14px; line-height: 1; cursor: pointer; opacity: 0; transition: opacity .12s ease; }
.block-columns__col:hover .block-columns__rm, .block-columns__col:focus-within .block-columns__rm { opacity: 1; }
.block-columns__rm:hover { color: var(--ink); }
.block-columns__add { flex: 0 0 26px; align-self: stretch; min-height: 2.4em; border: var(--border) dashed var(--line); background: none; color: var(--muted); border-radius: var(--radius); cursor: pointer; font-size: 16px; opacity: 0; transition: opacity .12s ease; }
.block-columns:hover .block-columns__add, .block-columns:focus-within .block-columns__add { opacity: 1; }
.block-columns__add:hover { background: var(--surface-3); color: var(--ink); }
@media (max-width: 720px) {
  .block-columns { flex-direction: column; }
  .block-columns__col { padding-left: 0; border-left: 0; padding-top: var(--space-3); border-top: var(--border) solid var(--line-soft); }
  .block-columns__col:first-child { padding-top: 0; border-top: 0; }
  .block-columns__add { align-self: flex-start; flex-basis: auto; padding: 4px 12px; }
}

/* Calm focus: dim the Details column slightly while writing. */
.editor-panel--writing .editor__details { opacity: 0.55; transition: opacity .2s ease; }

/* --- Add block --- */
/* Click-to-write tail: a full-width keyboard-operable button styled as open
   space (text cursor); Enter/Space adds a paragraph. */
.editor__tail { display: block; width: 100%; min-height: 140px; border: 0; background: none; cursor: text; text-align: left; }
.editor__tail:focus-visible { outline: none; box-shadow: inset 0 1px 0 var(--line-soft); }

/* --- Framed editor panel (mockup frame 5 workbench) --- */
.editor-panel { display: flex; flex-direction: column; height: calc(100vh - 53px - 2 * var(--space-6)); border: var(--border) solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--surface); }

/* ===== Entry editor: Miller columns (story 022) =====
   Level 1 = narrow icon rail (chrome nav), level 2 = entries column,
   level 3 = the editor panel (here it's the right column, no outer frame). */
.shell__main--flush { padding: 0; }
/* overflow: visible lets the account menu (position:absolute, pops out to the right of
   the 58px rail) escape the nav instead of being clipped away — the icon list still
   scrolls inside .shell__nav-top's own overflow. */
.shell__nav--rail { width: 58px; padding: var(--space-3) 0; overflow: visible; }
.shell__nav--rail .shell__nav-top, .shell__nav--rail .shell__nav-items { display: flex; flex-direction: column; align-items: center; gap: var(--space-1); }
.shell__nav--rail .account-zone { align-items: center; position: relative; }
.shell__nav--rail .account-card__id, .shell__nav--rail .account-card__chev { display: none; }
.shell__nav--rail .account-card { justify-content: center; padding: var(--space-2) 0; }
/* The narrow rail can't hold the settings menu inline, so float it out to the right as a
   popover (full width, readable) instead of squishing it into the 58px column. */
.shell__nav--rail .account-menu {
  position: absolute; left: calc(100% + var(--space-2)); bottom: 0; min-width: 220px;
  margin: 0; background: var(--surface); box-shadow: var(--shadow-modal); z-index: 50;
}

.iconnav__section { position: relative; width: 34px; height: 34px; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; border: var(--border) solid transparent; background: none; border-radius: var(--radius); cursor: pointer; }
.iconnav__section:hover { background: var(--surface-3); }
.iconnav__section.is-active { border-color: var(--ink); background: var(--surface-3); }

.editor-cols { display: flex; height: calc(100vh - 53px); }
.editor-cols .editor-panel { flex: 1; height: 100%; border: 0; border-radius: 0; }
.entries-col { width: 264px; flex-shrink: 0; border-right: var(--border) solid var(--line-soft); display: flex; flex-direction: column; background: var(--surface); }
.entries-col__head { height: 48px; flex-shrink: 0; display: flex; align-items: center; gap: var(--space-2); padding: 0 var(--space-4); border-bottom: var(--border) solid var(--line-soft); }
.entries-col__section { flex: 1; min-width: 0; font-weight: 600; font-size: var(--type-ui-compact); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.entries-col__section--link { border: 0; background: none; cursor: pointer; text-align: left; color: var(--ink); padding: 3px 6px; margin: -3px -6px; border-radius: var(--radius); transition: background .12s ease; }
.entries-col__section--link:hover { background: var(--surface-3); }
/* issue-162: the section header doubles as the entry view's "‹ {Section title}" back-to-parent
   row — a leading chevron (muted, sized like the space-nav back chevron) with the section name
   ellipsis-truncating beside it. */
.entries-col__section--back { display: inline-flex; align-items: center; gap: 1px; }
.entries-col__section--back .nav-back__chev { color: var(--muted); }
.entries-col__section-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.entries-col__sub { display: flex; align-items: center; gap: var(--space-2); padding: 10px 12px 4px; }
.entries-col__list { flex: 1; overflow-y: auto; padding: 2px var(--space-2) var(--space-2); }
/* Items match the nav-row idiom (subtle active: surface + ink left-border). */
/* Rail rows (080): a non-interactive wrapper with sibling open + pin controls
   (no nested buttons); the open button carries the old row padding. */
.entries-col__item { display: flex; align-items: stretch; width: 100%; border-left: 2px solid transparent; cursor: pointer; }
.entries-col__item:hover { background: var(--surface-3); }
.entries-col__item.is-active { background: var(--surface-3); border-left-color: var(--ink); }
.entries-col__open { flex: 1; min-width: 0; text-align: left; border: 0; background: none; padding: 8px 0 8px 11px; cursor: pointer; color: inherit; font: inherit; }
.entries-col__pin { flex-shrink: 0; display: inline-flex; align-items: center; padding: 0 10px 0 6px; border: 0; background: none; cursor: pointer; color: var(--muted); opacity: 0; }
.entries-col__item:hover .entries-col__pin, .entries-col__pin:focus-visible { opacity: 1; }
.entries-col__pin.is-pinned { opacity: 1; } /* a pinned entry shows its pin persistently */
.entries-col__pin:hover { color: var(--ink); }
.entries-col__pin.is-armed, .entries-col__item:hover .entries-col__pin.is-armed { color: var(--accent-red); opacity: 1; }
.entries-col__item.is-active .entries-col__title { font-weight: 600; }
.entries-col__item--dragging { opacity: 0.4; }
.entries-col__item--dropinto { box-shadow: inset 0 2px 0 var(--ink); }
.entries-col__title { font-size: var(--type-ui-compact); color: var(--ink); display: flex; align-items: center; gap: 5px; min-width: 0; }
.entries-col__title > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.entries-col__meta { margin-top: 2px; }
.editor-panel__header { display: flex; align-items: center; gap: var(--space-3); height: 48px; flex-shrink: 0; padding: 0 var(--space-4); border-bottom: var(--border) solid var(--line-soft); }
.editor-panel__body { display: flex; flex: 1; min-height: 0; }
.icon-btn { width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center; border: 0; background: none; color: var(--ink-soft); cursor: pointer; border-radius: var(--radius); }
.icon-btn:hover { background: var(--surface-3); color: var(--ink); }
.icon-btn.is-on { background: var(--surface-3); color: var(--ink); }

.editor__main { flex: 1; min-width: 0; overflow-y: auto; overflow-x: clip; display: flex; flex-direction: column; align-items: center; padding: var(--space-6); }
.editor__main > * { width: 100%; max-width: 720px; }

.editor__details { width: 340px; flex-shrink: 0; border-left: var(--border) solid var(--line-soft); background: var(--surface-2); display: flex; flex-direction: column; min-height: 0; }
.editor__details-head { height: 40px; flex-shrink: 0; display: flex; align-items: center; padding: 0 var(--space-4); border-bottom: var(--border) solid var(--line-soft); }
.editor__details-body { flex: 1; overflow-y: auto; }
.details__heading { display: block; margin-bottom: 10px; }

/* Details is collapsible and defaults to closed — shown only when the panel opts in
   (the ⓘ toggle adds `editor-panel--details`), so the entry reads full-width by default. */
.editor-panel:not(.editor-panel--details) .editor__details { display: none; }

/* === 036a — reading-grade canvas: typography · theme · width · size · align === */
/* Article-grade measure + scale — the canvas should read like a publication, not a form. */
/* All three steps trimmed ~8% smaller (base/small/large kept in proportion); the
   section Read view keeps its own scale (see .read* above). */
.editor-panel { --reading-scale: 0.92; }
.editor-panel--text-s { --reading-scale: 0.81; }
.editor-panel--text-l { --reading-scale: 1.06; }
.editor__main > * { max-width: 880px; }                 /* default reading width */
.editor-panel--width-s .editor__main > * { max-width: 660px; } /* ~64ch at 17px */
.editor-panel--width-l .editor__main > * { max-width: 1080px; }
/* Left-align the column instead of centering it in the panel. */
.editor-panel--align-left .editor__main { align-items: flex-start; } /* flush to the edge */
/* Left, but with a comfortable margin so it isn't hard against the edge. */
.editor-panel--align-leftpad .editor__main { align-items: flex-start; }
.editor-panel--align-leftpad .editor__main > * { margin-left: clamp(24px, 6vw, 100px); }
.editor__title { font-size: calc(32px * var(--reading-scale)); line-height: 1.18; margin-bottom: 18px; }
.block__rich { font-size: calc(17px * var(--reading-scale)); line-height: 1.65; }
.block__rich--h, .block__rich h2 { font-size: calc(21px * var(--reading-scale)); line-height: 1.3; letter-spacing: -0.01em; }
/* Code + table were --text-sm (~12px) against 17px body — too small/inconsistent on the
   reading-grade canvas; bring them up and let them scale with the Aa text size (053b). */
.editor__main .block__code { font-size: var(--code-size); line-height: var(--code-lh); } /* one source with the overlay/gutter (issue-123) */
.editor__main .block-table__table { font-size: calc(15px * var(--reading-scale)); }
.block { margin: 1px 0; }
/* Serif "document" theme */
.editor-panel--serif .editor__title { font-family: var(--font-serif); letter-spacing: -0.01em; }
.editor-panel--serif .block__rich { font-family: var(--font-serif); font-size: calc(18.5px * var(--reading-scale)); }
/* The Aa popover */
.aa-pop { position: fixed; width: 236px; background: var(--surface); border: var(--border) solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-menu); z-index: 80; padding: 13px; }
.aa-pop__label { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); margin: 0 0 6px; }
.aa-seg { display: flex; border: var(--border) solid var(--line); border-radius: var(--radius); overflow: hidden; margin-bottom: 13px; }
.aa-seg button { flex: 1; padding: 6px; border: 0; background: none; font-size: var(--type-ui-compact); color: var(--ink-soft); cursor: pointer; }
.aa-seg button.is-on { background: var(--ink); color: var(--on-ink); }
.aa-pop__note { font-size: var(--type-meta); color: var(--muted); line-height: 1.5; margin: 0; }

/* Ghost text (story 089) — the muted inline continuation after the caret.
   Non-interactive by design: contenteditable=false keeps the caret out; these
   rules keep the pointer + selection out too, so it never behaves like content. */
.block__ghost { color: var(--muted); user-select: none; pointer-events: none; white-space: pre-wrap; }

/* History timeline (Details column) */
.timeline { display: flex; flex-direction: column; gap: 2px; }
.timeline__row { display: flex; align-items: flex-start; gap: var(--space-2); width: 100%; text-align: left; border: 0; background: none; padding: 6px 4px; cursor: pointer; border-radius: var(--radius); }
.timeline__row:hover { background: var(--surface-3); }
.timeline__avatar { width: 22px; height: 22px; flex-shrink: 0; background: var(--ink-soft); color: var(--on-ink); border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 9px; font-weight: 600; }
.timeline__line { font-size: var(--type-ui-compact); }

/* 058d — backlinks ("Linked from"): a calm list of entries pointing here. */
.backlinks { display: flex; flex-direction: column; gap: 2px; }
.backlinks__row { display: flex; flex-direction: column; gap: 1px; width: 100%; text-align: left; border: 0; background: none; padding: 6px 4px; cursor: pointer; border-radius: var(--radius); }
.backlinks__row:hover { background: var(--surface-3); }
.backlinks__title { font-size: var(--type-meta); color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.backlinks__meta { color: var(--muted); }


/* --- Version diff modal --- */
.version-overlay { position: fixed; inset: 0; background: var(--overlay-modal); display: flex; align-items: center; justify-content: center; z-index: 210; }
.version-modal { background: var(--surface); border: var(--border) solid var(--line); border-radius: var(--radius); width: 760px; max-width: calc(100vw - 32px); max-height: 86vh; display: flex; flex-direction: column; box-shadow: var(--shadow-modal); }
.version-modal__head { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-4); border-bottom: var(--border) solid var(--line-soft); }
.version-diff { padding: var(--space-4); overflow-y: auto; font-family: var(--font-mono); font-size: var(--type-ui-compact); }
.diff__line { display: flex; gap: var(--space-2); padding: 2px 6px; line-height: 1.5; white-space: pre-wrap; }
.diff__mark { width: 12px; flex-shrink: 0; color: var(--muted); }
.diff__line--same { color: var(--ink-soft); }

/* Version-history changelog (issue 61): id-based New / Changed / Deleted rows with a summary line,
   replacing the old index-based +/−/~ list. Colour is used semantically (status), not decoratively. */
.vdiff__summary { font-family: var(--font-ui); padding: 0 2px var(--space-3); margin-bottom: var(--space-2); border-bottom: var(--border) solid var(--line-soft); }
.vdiff__row { display: flex; gap: var(--space-3); padding: 5px 6px; line-height: 1.5; align-items: flex-start; border-radius: var(--radius); }
.vdiff__tag { flex-shrink: 0; width: 58px; font-family: var(--font-ui); font-size: var(--type-meta); font-weight: 600; text-transform: uppercase; letter-spacing: .03em; padding-top: 1px; }
.vdiff__body { flex: 1; min-width: 0; white-space: pre-wrap; word-break: break-word; }
.vdiff__row--new { background: color-mix(in oklch, var(--accent-green) 12%, transparent); }
.vdiff__row--new .vdiff__tag { color: var(--accent-green); }
.vdiff__row--changed { background: color-mix(in oklch, var(--accent-amber) 12%, transparent); }
.vdiff__row--changed .vdiff__tag { color: var(--accent-amber); }
.vdiff__row--deleted { background: color-mix(in oklch, var(--accent-red) 11%, transparent); }
.vdiff__row--deleted .vdiff__tag { color: var(--accent-red); }
.vdiff__row--deleted .vdiff__text { color: var(--ink-soft); text-decoration: line-through; }
.vdiff__old { color: var(--ink-soft); text-decoration: line-through; }
.vdiff__new { margin-top: 2px; }
.vdiff__ctx { font-family: var(--font-ui); font-style: italic; color: var(--muted); font-size: var(--type-meta); }

/* Multi-entry burst review (036f): the version-modal body is a scroll of per-entry sections,
   each a per-block diff where changed/added blocks can be reverted individually. */
.burst-review__body { overflow-y: auto; }
.burst-review__entry { border-bottom: var(--border) solid var(--line-soft); }
.burst-review__entry:last-child { border-bottom: 0; }
.burst-review__entry--applied { opacity: .55; }
.burst-review__entry-head { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4) 0; }
.burst-review__open { border: 0; background: none; color: var(--ink); font-weight: 600; font-size: var(--type-ui-compact); cursor: pointer; padding: 0; text-align: left; }
.burst-review__open:hover { text-decoration: underline; }
.burst-review__diff { padding: var(--space-2) var(--space-4) var(--space-3); font-family: var(--font-mono); font-size: var(--type-ui-compact); }
.burst-review__hunk { display: flex; align-items: center; gap: var(--space-2); padding: 2px 6px; line-height: 1.5; border-radius: 4px; }
.burst-review__hunk--changed { background: color-mix(in oklch, var(--accent-amber) 14%, transparent); }
.burst-review__hunk--added { background: color-mix(in oklch, var(--accent-green) 14%, transparent); }
.burst-review__hunk--removed { background: color-mix(in oklch, var(--accent-red) 12%, transparent); color: var(--ink-soft); text-decoration: line-through; }
.burst-review__hunk-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.burst-review__hunk--rejected { opacity: .55; }
.burst-review__hunk--rejected .burst-review__hunk-text { text-decoration: line-through; }
.burst-review__revert { flex-shrink: 0; border: var(--border) solid var(--line); background: var(--surface); color: var(--ink-soft); cursor: pointer; font-family: var(--font-ui); font-size: var(--text-xs, 11px); padding: 2px 8px; border-radius: 4px; }
.burst-review__revert:hover { background: var(--surface-3); color: var(--ink); }
.burst-review__revert.is-on { background: var(--ink); color: var(--on-ink); border-color: var(--ink); }
.burst-review__same { padding: 4px 6px; }

/* No divider between sections — the mono headings + spacing separate them (fewer lines).
   Only the destructive Delete zone gets a rule to set it apart. */
.details__section { padding: var(--space-4); }
.details__section--danger { border-top: var(--border) solid var(--line-soft); }
.details__danger-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.details__danger-row .details__heading { margin-bottom: 0; }
.details__section .editor__label { width: 100%; margin-bottom: var(--space-2); }
/* Agent-instruction field (story 054) — a plain-text guidance box in Details /
   section settings, in the monochrome house style. */
.details__instruction {
  width: 100%; box-sizing: border-box; min-height: 60px; resize: vertical;
  font: inherit; font-size: var(--type-ui-compact); line-height: 1.5;
  padding: var(--space-2); border: var(--border) solid var(--line);
  border-radius: var(--radius); background: var(--surface); color: inherit;
}
.details__instruction:focus { outline: none; border-color: var(--ink, #111); }
.details__saved { float: right; font-weight: 400; opacity: .55; }
/* "Insert template" in the entry rail's instruction heading (story 113) — rides right,
   next to the saved status; the picker__none base gives it the small mono-button look. */
.details__instr-template { float: right; margin-left: var(--space-2); font-weight: 400; }
.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.section-chip { display: inline-flex; align-items: center; gap: 5px; border: var(--border) solid var(--line); border-radius: var(--radius); padding: 3px 8px; font-size: var(--type-ui-compact); background: var(--surface); }
.section-chip__x { border: 0; background: none; color: var(--muted); cursor: pointer; font-size: 13px; min-width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; }
.section-chip--add { border-style: dashed; color: var(--muted); cursor: pointer; }

/* --- Space header --- */
/* Lift the title a little (space + section views) so it sits closer to the breadcrumb and
   aligns with the SECTIONS nav header — the column top padding otherwise drops it ~32px down. */
.space-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); margin-top: calc(var(--space-3) * -1); margin-bottom: var(--space-5); }
.space-head__actions { display: inline-flex; align-items: center; gap: var(--space-2); flex-shrink: 0; }
/* "✦ agent brief" chip (story 113) — active guidance made visible at the header.
   Set → always shown (mono chip, house border). Unset → invisible at rest; a faint
   "+ agent brief" fades in while the header is hovered or the chip has focus, so the
   affordance teaches itself without adding chrome. Colour stays monochrome. */
.agent-brief { border: var(--border) solid var(--line-soft); border-radius: var(--radius); background: var(--surface); color: var(--muted); padding: 3px 8px; cursor: pointer; white-space: nowrap; }
.agent-brief:hover { color: var(--ink-soft); border-color: var(--line); }
.agent-brief--set { color: var(--ink-soft); }
.agent-brief--empty { opacity: 0; transition: opacity .15s ease; }
.space-head:hover .agent-brief--empty, .agent-brief--empty:focus-visible { opacity: .7; }
.space-head__title-wrap { min-width: 0; }
.space-head__title-row { display: flex; align-items: center; gap: var(--space-2); min-width: 0; } /* marker icon + name (068) */
.space-head__menu { font-size: var(--text-xl); line-height: 1; }
/* Inline-edit (story-053): title + description edited in place, like an entry title.
   Quiet until hover/focus so it doesn't read as a form field. */
/* A display heading you can edit — not a form field. At rest it's plain; a calm tint on
   hover hints it's editable; the box only shows while you're actually editing (focus). */
.inline-edit { outline: none; border-radius: var(--radius); cursor: text; transition: background .12s ease, box-shadow .12s ease; }
.inline-edit:hover { background: var(--surface-3); }
.inline-edit:focus { background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-soft); }
.inline-edit:empty::before { content: attr(data-placeholder); color: var(--muted); pointer-events: none; }
h1.inline-edit { padding: 1px 6px; margin-left: -6px; }
p.inline-edit { padding: 2px 6px; margin-left: -6px; }
.space-head__desc { margin-top: 2px; }
/* Section header: the description is a full-width, multi-line write area; the title keeps
   its own width. Scoped to the space/section header (not the settings .section-head). */
.space-head .section-head__title { flex: 1; min-width: 0; }
.space-head .section-head__title .space-head__title-wrap { flex: 1; min-width: 0; }
.space-head .section-head__title .view__title { width: fit-content; max-width: 100%; }
.section-head__title .space-head__desc { white-space: pre-wrap; margin-bottom: 0; }
/* Tighten the gap between the description and the entries toolbar (was ~48px: the
   description's own bottom margin + the header/toolbar margin). Section view only. */
.space-head:has(.section-head__title) { margin-bottom: var(--space-6); }
.space-head:has(.section-head__title) + .collection-bar { margin-top: 0; }
/* Empty description: reserve a full-width ~3-line area that greys on hover/focus (no focus
   box), so it reads as a writable field; Cmd/Ctrl+Enter adds rows. */
.section-head__title .space-head__desc:empty { min-height: 3.4em; }
.section-head__title .space-head__desc:focus { box-shadow: none; background: var(--surface-3); }

/* --- Empty state (design review: a place to act, not a cold blank) --- */
.empty-state { display: grid; place-items: center; gap: var(--space-2); text-align: center; padding: 56px var(--space-4); color: var(--ink-soft); }
.empty-state--inset { padding: 40px; border: var(--border) dashed var(--line); border-radius: var(--radius); }
.empty-state__title { margin: 0; font-size: var(--text-xl); letter-spacing: -0.01em; color: var(--ink); }
.empty-state__icon { color: var(--muted-2); opacity: 0.8; margin-bottom: var(--space-1); }
/* Ato's curious pose greets an empty section (12×9 sprite at 6px cells; spec:
   documents/ato-mascot.md — integer scale + pixelated so the blocks stay crisp). */
.empty-state__sprite { width: 72px; height: 54px; image-rendering: pixelated; }
.empty-state__cta { margin-top: var(--space-3); }

/* --- Panel (right-side overlay) --- */
.panel-backdrop {
  position: fixed; inset: 0;
  background: var(--overlay-panel);
  display: flex; justify-content: flex-end;
  z-index: 50;
}
.panel {
  /* Issue 25: every .panel sits on a blocking backdrop (unlike the docked 340px
     entry Details rail), so the old 360px bought nothing — settings forms and
     copy blocks get room to breathe. Content-heavy panels use .panel--wide. */
  width: 460px; max-width: 100%;
  background: var(--surface);
  border-left: var(--border) solid var(--line);
  display: flex; flex-direction: column;
  box-shadow: var(--shadow-modal);
}
.panel__head {
  display: flex; align-items: center; justify-content: space-between;
  height: 53px; padding: 0 var(--space-4);
  border-bottom: var(--border) solid var(--line-soft);
}
.panel__close { border: 0; background: none; color: var(--muted); font-size: 14px; cursor: pointer; }
.panel__body { padding: var(--space-5); overflow-y: auto; }
.panel__danger {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: var(--space-5); padding-top: var(--space-4);
  border-top: var(--border) solid var(--line-soft);
}

/* --- Agents --- */
.agent-list { display: flex; flex-direction: column; gap: var(--space-2); }
.agent-row {
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4);
  border: var(--border) solid var(--line); border-radius: var(--radius); padding: var(--space-4);
}
.agent-row__main { min-width: 0; flex: 1; }
.agent-row__actions { display: flex; gap: var(--space-2); flex-shrink: 0; flex-wrap: wrap; justify-content: flex-end; }
/* Connect-a-client panel (story 034) */
.connect-panel { display: flex; flex-direction: column; gap: var(--space-4); }
.connect-clients { display: flex; gap: var(--space-2); }
.connect-client { flex: 1; padding: 10px; border: var(--border) solid var(--line); border-radius: var(--radius); background: var(--surface); cursor: pointer; font-size: var(--type-ui-compact); color: var(--ink); }
.connect-client:hover { background: var(--surface-3); }
.connect-client.is-selected { border-color: var(--ink); background: var(--surface-3); font-weight: 600; }
.connect-method { display: flex; flex-direction: column; gap: var(--space-3); }
.connect-step { display: flex; flex-direction: column; gap: var(--space-2); }
.connect-toggle { align-self: flex-start; border: 0; background: none; color: var(--ink-soft); text-decoration: underline; cursor: pointer; font-size: var(--type-ui-compact); padding: 0; }
.connect-toggle:hover { color: var(--ink); }
/* 142/143 — the guided "Connect an AI tool" wizard: a recommended-OAuth card, a quiet
   CLI disclosure, a test-connection block, and clearly secondary static-key copy. */
.connect-rec { border: var(--border) solid var(--ink); border-radius: var(--radius); padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-3); }
.connect-rec__head { display: flex; align-items: center; gap: var(--space-2); }
.connect-badge { font-family: var(--font-mono); font-size: var(--text-xs); text-transform: uppercase; letter-spacing: var(--mono-tracking-wide); background: var(--ink); color: var(--surface); padding: 2px 8px; border-radius: 999px; }
.connect-rec__why { margin: 0; color: var(--ink-soft); }
.connect-success { margin: 0; color: var(--accent-green); }
.connect-note { margin: 0; color: var(--muted); line-height: 1.5; font-size: var(--type-body); } /* 202: helper prose readable */
.connect-rec__why, .connect-success { font-size: var(--type-ui-compact); line-height: 1.5; }
.connect-warn { margin: 0; color: var(--accent-amber); font-weight: 500; }
/* One-click install link (story 112, Cursor deeplink) — reads as a solid mini button. */
.connect-deeplink { display: inline-block; padding: 6px 12px; border: var(--border) solid var(--ink); border-radius: var(--radius); background: var(--ink); color: var(--surface); text-decoration: none; font-size: var(--type-ui-compact); font-weight: 600; }
.connect-deeplink:hover { opacity: 0.85; }
.connect-disclosure > summary { cursor: pointer; color: var(--ink-soft); list-style: none; padding: var(--space-2) 0; }
.connect-disclosure > summary::-webkit-details-marker { display: none; }
.connect-disclosure > summary::before { content: "›"; display: inline-block; margin-right: 6px; transition: transform .12s ease; }
.connect-disclosure[open] > summary::before { transform: rotate(90deg); }
.connect-disclosure > *:not(summary) { margin: var(--space-2) 0 0; }
.connect-test { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-3); background: var(--surface-2); border-radius: var(--radius); }
.connect-links { display: flex; gap: var(--space-4); flex-wrap: wrap; }
/* Issues 27 + 222: EVERY prompt/config box takes the full available width with its
   Copy button on its own row below — a side column squeezes the code (the /docs/mcp
   examples measured ~251px wide beside their buttons). */
.copy-block { display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-2); }
.copy-block .docs-code { width: 100%; margin: 0; }
.copy-block--canonical { flex-wrap: wrap; }
.copy-block--canonical > .label { flex-basis: 100%; }
.agent-row__name { font-size: var(--type-ui-compact); font-weight: 600; margin-bottom: 2px; }
.agent-row__meta { line-height: 1.45; overflow-wrap: anywhere; }
.agent-row__health { margin-top: 2px; }
.agent-row__health--warn { color: var(--accent-amber); }
.key-reveal {
  display: block; font-family: var(--font-mono); font-size: var(--type-ui-compact);
  background: var(--surface-3); border: var(--border) solid var(--line); border-radius: var(--radius);
  padding: var(--space-3); word-break: break-all; user-select: all;
}

/* --- While-you-were-away digest --- */
.digest { margin-bottom: var(--space-5); border-color: var(--ink); }
.digest__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-3); padding-bottom: var(--space-3); border-bottom: var(--border) solid var(--line-soft); }
.digest__row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); padding: 6px 0; font-size: var(--type-ui-compact); }
/* Progressive "Show more" for the digest + activity feeds. */
.show-more { width: 100%; border: 0; background: none; color: var(--ink-soft); cursor: pointer; padding: var(--space-1) var(--space-2); margin-top: 0; font-size: var(--type-ui-compact); }
.show-more:hover { color: var(--ink); text-decoration: underline; }
.digest__entity { color: var(--ink-soft); }

/* Connect-in-60s onboarding card (story 077): shown until the owner's first agent
   write, then flips to a one-time celebration. */
.connect-card { margin-bottom: var(--space-5); border-color: var(--ink); }
.connect-card__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-2); }
.connect-card__lead { margin: 0 0 var(--space-3); }
.connect-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); }
.connect-step { display: inline-flex; align-items: center; gap: 6px; font-size: var(--type-body); color: var(--muted); }
.connect-step.is-done { color: var(--ink); }
.connect-step__mark { display: inline-grid; place-items: center; width: 16px; height: 16px; border-radius: 50%; font-size: var(--text-xs); border: var(--border) solid var(--line); color: var(--muted); }
.connect-step.is-done .connect-step__mark { border-color: var(--accent-green); color: var(--accent-green); }
.connect-card--done { display: flex; align-items: center; gap: var(--space-4); }
.connect-card__burst { font-size: 28px; color: var(--accent-amber); line-height: 1; animation: connect-pop 600ms ease-out; }
.connect-card__title { font-weight: 600; font-size: var(--type-heading-sm); letter-spacing: -0.01em; }
@keyframes connect-pop { 0% { transform: scale(0.4); opacity: 0; } 60% { transform: scale(1.25); } 100% { transform: scale(1); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .connect-card__burst { animation: none; } }

/* --- Settings page (dedicated, routed — mockup frame 21; replaced the old
 * settings-overlay/settings-ws modal, story 032) --- */
.settings-page { display: flex; flex-direction: column; height: 100vh; }
.settings-page__bar { display: flex; align-items: center; gap: var(--space-3); height: 53px; flex-shrink: 0; padding: 0 var(--space-5); border-bottom: var(--border) solid var(--line); }
.settings-page__back { border: 0; background: none; cursor: pointer; font-size: var(--type-ui-compact); color: var(--ink-soft); padding: 6px 8px; margin-left: -8px; border-radius: var(--radius); max-width: 60vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.settings-page__back:hover { background: var(--surface-3); color: var(--ink); }
.settings-page__title { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: var(--mono-tracking); text-transform: uppercase; color: var(--muted); }
.settings-page__body { flex: 1; display: flex; min-height: 0; }
.settings-page__side { width: 240px; flex-shrink: 0; border-right: var(--border) solid var(--line); padding: var(--space-5) var(--space-4); display: flex; flex-direction: column; }
.settings-page__owner { display: flex; align-items: center; gap: var(--space-2); padding-bottom: var(--space-3); margin-bottom: var(--space-3); border-bottom: var(--border) solid var(--line-soft); }
.settings-page__avatar { width: 36px; height: 36px; flex-shrink: 0; background: var(--ink); color: var(--on-ink); border-radius: 50%; overflow: hidden; display: inline-flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 600; }
.settings-page__avatar-img { width: 100%; height: 100%; object-fit: cover; }
.settings-page__owner-name { font-size: var(--type-ui-compact); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.settings-page__nav { display: flex; flex-direction: column; gap: 2px; }
.settings-page__nav-item { display: flex; align-items: center; gap: var(--space-2); text-align: left; border: 0; border-left: 2px solid transparent; background: none; padding: 9px 11px; font-size: var(--type-ui-compact); color: var(--ink-soft); cursor: pointer; border-radius: var(--radius); }
.settings-page__nav-item:hover { background: var(--surface-3); }
.settings-page__nav-item.is-active { background: var(--surface-3); border-left-color: var(--ink); color: var(--ink); font-weight: 600; }
/* Bottom-left footer: Log out (action) + the quiet build version. */
.settings-page__foot { margin-top: auto; padding-top: var(--space-3); border-top: var(--border) solid var(--line-soft); }
.settings-page__foot-item { display: flex; align-items: center; gap: var(--space-2); width: 100%; text-align: left; border: 0; background: none; padding: 9px 11px; border-radius: var(--radius); font-size: var(--type-ui-compact); color: var(--ink-soft); cursor: pointer; }
.settings-page__foot-item:hover { background: var(--surface-3); color: var(--ink); }
.settings-page__foot-icon { display: inline-flex; color: var(--muted); }
.settings-page__version { padding: 2px 11px 6px; font-variant-numeric: tabular-nums; }
.settings-page__version:empty { display: none; }
/* Scroll container is full width (scrollbar at the panel edge); the readable width
   constraint lives on the inner content wrapper (issue-127). */
.settings-page__main { flex: 1; overflow-y: auto; min-width: 0; }
.settings-page__content { max-width: 760px; margin: 0 auto; padding: var(--space-6); }
.settings-page__main > .view__title { margin-bottom: var(--space-5); }
@media (max-width: 768px) {
  .settings-page__body { flex-direction: column; }
  .settings-page__side { width: 100%; border-right: 0; border-bottom: var(--border) solid var(--line); }
  .settings-page__nav { flex-direction: row; flex-wrap: wrap; }
}

.settings__section { display: flex; flex-direction: column; gap: var(--space-4); }
.field-row { display: flex; align-items: center; gap: var(--space-4); }
.field-row .field { flex: 1; }

/* --- Plan cards --- */
.plan-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
.plan-card { border: var(--border) solid var(--line); border-radius: var(--radius); padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-3); }
.plan-card--current { border-color: var(--ink); }
.plan-card__head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); }
.plan-card__price { font-family: var(--font-mono); font-size: var(--type-body); color: var(--ink); }
/* Free-beta price (Atomo issue 44): "$0 in beta" with the future price as a quiet
   second line, right-aligned under it; the note keeps the mono meta styling. */
.plan-card__price--beta { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.plan-card__price-note { text-transform: none; letter-spacing: var(--mono-tracking); }
.plan-beta-note { margin-top: var(--space-3); }
.plan-beta-note a { color: var(--ink); }
.plan-card__list { margin: 0; padding-left: var(--space-4); font-size: var(--type-body); color: var(--ink-soft); display: flex; flex-direction: column; gap: var(--space-1); }

/* --- Admin --- */
.admin__table { width: 100%; border-collapse: collapse; }
/* Issue 219 (WCAG reflow): wide admin tables scroll inside this labelled,
   keyboard-focusable region instead of widening the document. */
.admin__table-scroll { max-width: 100%; overflow-x: auto; overflow-y: hidden; }
.admin__table-scroll:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; border-radius: var(--radius); }
.admin__table th { text-align: left; padding: 8px 10px; border-bottom: var(--border) solid var(--line); }
.admin__table td { padding: 10px; border-bottom: var(--border) solid var(--line-soft); vertical-align: middle; }
.admin__num { font-family: var(--font-mono); font-size: var(--type-ui-compact); }
.admin__row { cursor: pointer; }
.admin__row:hover { background: var(--surface-3); }
.admin__row--suspended { opacity: 0.5; }
/* Plan-limits editor */
.admin__limit-input { width: 92px; height: 30px; }

/* --- Admin console shell (frame 15): top bar · rail · section main --- */
.admin-shell { display: flex; flex-direction: column; height: 100vh; }
.admin-topbar { height: 52px; flex-shrink: 0; display: flex; align-items: center; gap: var(--space-4); padding: 0 var(--space-5); border-bottom: var(--border) solid var(--line); }
/* Issue 219 (WCAG reflow): with the table contained, the non-wrapping topbar (fixed
   280px search + actions) was the remaining page-width driver at 320px — wrap it. */
@media (max-width: 640px) {
  .admin-topbar { height: auto; flex-wrap: wrap; padding: 10px var(--space-4); row-gap: var(--space-2); }
  .admin-topbar__search { order: 9; width: 100%; }
}
.admin-topbar__badge { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: var(--mono-tracking); border: var(--border) solid var(--ink); border-radius: var(--radius); padding: 2px 7px; }
.admin-topbar__search { display: flex; align-items: center; gap: 6px; width: 280px; height: 32px; padding: 0 10px; border: var(--border) solid var(--line); border-radius: var(--radius); color: var(--muted); }
/* The class `display:flex` beats the UA `[hidden]` rule, so honour hidden explicitly
   (issue-193: the global owner search hides on sections with their own search). */
.admin-topbar__search[hidden] { display: none; }
.admin-topbar__search input { border: 0; outline: none; background: none; flex: 1; font-size: var(--type-body); color: var(--ink); }
.admin-topbar__search-clear { flex-shrink: 0; border: 0; background: none; padding: 0 2px; font-size: var(--type-ui-compact); line-height: 1; color: var(--muted); cursor: pointer; }
.admin-topbar__search-clear:hover { color: var(--ink); }
.admin-shell__body { flex: 1; display: flex; min-height: 0; }
.admin-shell__main { flex: 1; overflow-y: auto; padding: var(--space-6) var(--space-6); }

.admin-rail { width: 210px; flex-shrink: 0; border-right: var(--border) solid var(--line); padding: var(--space-4) var(--space-3); display: flex; flex-direction: column; gap: 2px; }
.admin-rail__head { padding: 0 var(--space-2) var(--space-2); }
.admin-rail__nav { display: flex; flex-direction: column; gap: 2px; }
.admin-rail__item { display: flex; align-items: center; gap: var(--space-2); height: 34px; padding: 0 var(--space-3); border: 0; border-left: 2px solid transparent; background: none; text-align: left; font-size: var(--type-ui-compact); color: var(--ink-soft); cursor: pointer; border-radius: var(--radius); text-decoration: none; }
.admin-rail__item span:first-child { flex: 1; }
.admin-rail__item:hover { background: var(--surface-3); }
.admin-rail__item.is-active { background: var(--surface-3); border-left-color: var(--ink); color: var(--ink); font-weight: 600; }
.admin-rail__foot { margin-top: auto; padding: var(--space-3) var(--space-2) 0; display: flex; flex-direction: column; gap: 2px; }
.admin-rail__version:empty { display: none; } /* issue-196: hide the version line until it loads */
/* Issue 219 (WCAG reflow): at phone widths the fixed 210px rail left ~110px of
   content — stack the shell instead: the rail becomes a horizontal nav strip
   (locally scrollable) and the main column takes the full viewport. */
@media (max-width: 640px) {
  .admin-shell__body { flex-direction: column; }
  .admin-rail { width: 100%; flex-direction: row; align-items: center; overflow-x: auto; border-right: 0; border-bottom: var(--border) solid var(--line); padding: var(--space-2) var(--space-3); }
  .admin-rail__head, .admin-rail__foot { display: none; }
  .admin-rail__nav { flex-direction: row; gap: var(--space-1); }
  .admin-rail__item { height: 32px; white-space: nowrap; border-left: 0; }
  .admin-shell__main { padding: var(--space-4); }
}

.admin-section { max-width: 1080px; }
.admin-section__head { margin-bottom: var(--space-5); }
.admin-section__head .view__title { margin-bottom: var(--space-1); }

.admin-stats { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-bottom: var(--space-5); }
.admin-stat { flex: 1; min-width: 120px; border: var(--border) solid var(--line-soft); border-radius: var(--radius); padding: 12px 14px; }
.admin-stat__num { font-family: var(--font-mono); font-size: 22px; font-weight: 600; margin-top: var(--space-1); }

.admin-status { display: inline-flex; align-items: center; gap: 6px; font-size: var(--type-ui-compact); }
.admin-status__dot { width: 7px; height: 7px; border-radius: 50%; }
.admin-status--active .admin-status__dot { background: var(--accent-green); }
.admin-status--pending .admin-status__dot { background: var(--accent-amber); }
.admin-status--suspended { color: var(--muted); }
.admin-status--suspended .admin-status__dot { background: var(--accent-red); }

/* Plan-limit cards (Plans & limits section) */
/* Plans & limits editor (story 129 usability pass): ONE comparison grid — rows
   are limits, columns are Free | Pro — so the two tiers can be read against each
   other. Changed inputs highlight; the save bar appears only when dirty. */
.admin-plans { border: var(--border) solid var(--line); border-radius: var(--radius); padding: var(--space-4) var(--space-5); }
.admin-plans__grid { display: grid; grid-template-columns: minmax(200px, 1fr) minmax(120px, 150px) minmax(120px, 150px); column-gap: var(--space-5); align-items: center; max-width: 760px; }
.admin-plans__colhead { display: flex; flex-direction: column; gap: 1px; padding-bottom: var(--space-2); }
.admin-plans__plan { font-weight: 600; font-size: var(--type-heading-sm); }
.admin-plans__group { grid-column: 1 / -1; margin-top: var(--space-3); padding: var(--space-2) 0; border-top: var(--border) solid var(--line-soft); color: var(--muted); }
.admin-plans__rowlabel { display: flex; flex-direction: column; gap: 1px; padding: 6px 0; }
.admin-plans__hint { color: var(--muted); }
.admin-plans__cell { display: flex; align-items: center; gap: var(--space-2); padding: 3px 0; }
.admin-plans__cell .admin__limit-input { width: 92px; text-align: right; }
.admin-plans__unit { color: var(--muted); min-width: 20px; }
.input--dirty { border-color: var(--ink); }
.admin-plans__savebar { display: flex; align-items: center; gap: var(--space-3); margin-top: var(--space-4); padding-top: var(--space-3); border-top: var(--border) solid var(--line-soft); }
.admin-plans__savebar[hidden] { display: none; }
/* Narrow admin: the grid keeps three columns but lets the label column shrink;
   below that the whole card scrolls locally rather than leaking page scroll. */
@media (max-width: 560px) { .admin-plans { overflow-x: auto; } .admin-plans__grid { min-width: 480px; } }

/* Billing card (story 129): the beta ↔ live mode is headline-level — a pill
   with a functional status dot, amber = beta (free), green = live (charging). */
.admin-billing { margin-top: var(--space-6); }
.admin-billing__head { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-2); }
.admin-billing__title { font-size: var(--type-heading-sm); letter-spacing: -0.01em; margin: 0; }
.admin-billing__spacer { flex: 1; }
.admin-billing__drift { color: var(--accent-amber); }
.admin-mode { display: inline-flex; align-items: center; gap: 7px; font-family: var(--font-mono); font-size: var(--text-xs); text-transform: uppercase; letter-spacing: var(--mono-tracking); border: var(--border) solid var(--line); border-radius: 999px; padding: 3px 10px; white-space: nowrap; }
.admin-mode::before { content: ""; width: 7px; height: 7px; border-radius: 50%; flex: none; }
.admin-mode--beta::before { background: var(--accent-amber); }
.admin-mode--live::before { background: var(--accent-green); }

/* Free-beta cohort table + action bar (story 129). */
.admin-cohort { margin-top: var(--space-5); }
.admin-cohort .section-title { margin: 0 0 6px; }
.admin-cohort__check { width: 28px; }
.admin-cohort__check input { vertical-align: middle; }
.admin-cohort__bar { display: flex; align-items: center; gap: var(--space-3); margin-top: var(--space-3); }
.admin-cohort__due { color: var(--accent-amber); }

/* Provider-key cards (story 098) — monochrome provenance pill + mono last4. */
.admin-key__pill { display: inline-block; margin-left: var(--space-2); padding: 1px 7px; border: var(--border) solid var(--line); border-radius: var(--radius); font-size: var(--text-xs); color: var(--muted); text-transform: uppercase; letter-spacing: .04em; vertical-align: middle; }
.admin-key__pill--admin { color: var(--ink); border-color: var(--ink); }
.admin-key__last4 { font-family: var(--font-mono); font-size: var(--type-meta); color: var(--ink-soft); }
.admin-key__row { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-3); }
.admin-key__row .admin-key__input { flex: 1; min-width: 0; font-family: var(--font-mono); }
.admin-key__resultrow { min-height: 18px; margin-top: var(--space-2); }
.admin-key__result--ok { color: var(--ink); }
.admin-key__result--fail { color: var(--accent-red); }
.admin-key__warn { color: var(--accent-red); margin: var(--space-2) 0; }

/* Traffic panel (story 133): only the window toggle needs a rule — everything
   else reuses the admin stats/trends/table idiom. */
.admin-traffic__bar { display: flex; gap: var(--space-2); margin-bottom: var(--space-3); }

/* "Right now" strip (story 134): the anonymous event ticker — mono rows, local
   scroll (a busy ticker must never grow the page), calm empty state. */
.admin-live { margin-bottom: var(--space-4); }
.admin-live__ticker { border: var(--border) solid var(--line-soft); border-radius: var(--radius); padding: var(--space-2) var(--space-3); max-height: 220px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; margin-top: var(--space-2); }
.admin-live__row { display: flex; gap: var(--space-3); font-family: var(--font-mono); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.admin-live__time { color: var(--muted); flex-shrink: 0; }
.admin-live__empty { font-style: italic; }

/* Admin MCP (story 131): the atma_ credential card — create row, one-time code
   reveal, and the per-agent actions column. Codes render in mono and wrap-scroll
   locally so a long secret URL never widens the page. */
.admin-mcp__create { display: flex; gap: var(--space-2); align-items: center; margin: var(--space-3) 0; max-width: 480px; }
.admin-mcp__name { flex: 1; }
.admin-mcp__reveal { border: var(--border) solid var(--line); border-radius: var(--radius); padding: var(--space-3); margin: var(--space-3) 0; display: flex; flex-direction: column; gap: var(--space-2); background: var(--surface-3); }
.admin-mcp__code-row { display: flex; gap: var(--space-2); align-items: center; min-width: 0; }
.admin-mcp__code { font-family: var(--font-mono); font-size: var(--type-meta); overflow-x: auto; white-space: nowrap; flex: 1; min-width: 0; padding: 4px 6px; background: var(--surface); border: var(--border) solid var(--line-soft); border-radius: var(--radius); }
.admin-mcp__actions { display: flex; gap: var(--space-2); justify-content: flex-end; }

/* AI-model cards (story 097) — reuse the plan-card/key families; inputs get room. */
.admin-model .admin-plan-card__row .input { flex: 1; min-width: 0; max-width: 320px; }
.admin-model .admin-plan-card__row .admin__limit-input { flex: 0 0 auto; width: 80px; }
.admin-model__url--fixed { color: var(--muted); background: var(--paper-soft, transparent); }
.admin-model .admin-plan-card__head .label { font-family: var(--font-mono); }

/* Recommended-models reference table (issue 165) — static, monochrome, thin
   borders; exact model ids + prices in JetBrains Mono. Scrolls on narrow widths. */
.admin-modelref { margin-top: var(--space-6); }
.admin-modelref__scroll { overflow-x: auto; border: var(--border) solid var(--line); border-radius: var(--radius); }
.admin-modelref__table { min-width: 640px; }
.admin-modelref__table th, .admin-modelref__table td { padding: 8px 12px; }
.admin-modelref__table td { vertical-align: top; }
.admin-modelref__row td:nth-child(3) { color: var(--muted); }
.admin-modelref__id { font-family: var(--font-mono); font-size: var(--type-meta); color: var(--ink); background: none; padding: 0; }
.admin-modelref__price { font-family: var(--font-mono); font-size: var(--type-meta); color: var(--ink); background: none; padding: 0; white-space: nowrap; }
.admin-modelref__flag { color: var(--muted); font-family: var(--font-mono); }
.admin-modelref__note { margin: var(--space-3) 0 0; color: var(--muted); line-height: 1.5; }
/* issue 178: the quick-rating matrix — compact mono star cells, rating columns centred. */
.admin-modelmatrix { margin-top: var(--space-5); }
.admin-modelmatrix__table { min-width: 520px; }
.admin-modelmatrix__table th, .admin-modelmatrix__table td { padding: 8px 12px; }
.admin-modelmatrix__table th:not(:first-child), .admin-modelmatrix__table td:not(:first-child) { text-align: center; }
.admin-modelmatrix__rating { font-family: var(--font-mono); letter-spacing: 2px; color: var(--ink); white-space: nowrap; }

/* Usage bars (detail panel + usage section) */
.admin-usage { margin: 10px 0; }
.admin-usage__row { display: flex; justify-content: space-between; margin-bottom: var(--space-1); }
.admin-usage__track { height: 6px; background: var(--surface-3); border-radius: 3px; overflow: hidden; }
.admin-usage__fill { height: 100%; background: var(--ink); }
.admin-dist { margin-top: var(--space-5); }
.admin-detail__plan { display: flex; gap: var(--space-2); align-items: center; margin-bottom: var(--space-3); }
.admin-detail__plan select { flex: 1; }

/* --- Admin observability (story 050) --- */
.admin-subhead { display: block; margin: var(--space-5) 0 var(--space-2); }
/* Live "now" dot on a pulse tile. */
.admin-stat__live { display: inline-block; width: 7px; height: 7px; margin-left: var(--space-2); vertical-align: middle; border-radius: 50%; background: var(--accent-green); animation: aa-pulse 1.6s ease-in-out infinite; }
/* 14-day trend sparklines. */
.admin-trends { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--space-3); }
/* Connect-in-60s funnel (story 077): step tiles with count + % of signups, arrow-linked. */
.admin-funnel { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: stretch; }
.admin-funnel__step { flex: 1; min-width: 96px; position: relative; border: var(--border) solid var(--line-soft); border-radius: var(--radius); padding: 10px 12px; }
.admin-funnel__step:not(:last-child)::after { content: "→"; position: absolute; right: calc(-1 * var(--space-2)); top: 50%; transform: translateY(-50%); color: var(--muted-2); font-size: var(--text-sm); }
.admin-funnel__num { font-family: var(--font-mono); font-size: 20px; font-weight: 600; letter-spacing: -0.02em; }
.admin-funnel__pct { color: var(--accent-green); margin-top: 2px; }
.admin-funnel__median { margin: var(--space-3) 0 0; color: var(--muted); }
.admin-spark-card { border: var(--border) solid var(--line-soft); border-radius: var(--radius); padding: 12px 14px; }
.admin-spark-card__head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 10px; }
.admin-spark-card__total { font-family: var(--font-mono); font-size: 18px; font-weight: 600; }
.admin-spark { display: flex; align-items: flex-end; gap: 3px; height: 40px; }
.admin-spark__bar { flex: 1; min-width: 2px; background: var(--ink); border-radius: 1px; opacity: .82; }
/* Admin-wide activity feed. */
.admin-feed { display: flex; flex-direction: column; }
.admin-feed__row { display: flex; align-items: flex-start; gap: var(--space-2); padding: var(--space-2) 0; border-bottom: var(--border) solid var(--line-soft); }
.admin-feed__row:last-child { border-bottom: 0; }
.admin-feed--compact .admin-feed__row { padding: 6px 0; }
.admin-feed__avatar { width: 24px; height: 24px; flex-shrink: 0; border-radius: 50%; background: var(--ink-soft); color: var(--on-ink); display: inline-flex; align-items: center; justify-content: center; font-size: 9px; font-weight: 600; }
.admin-feed__avatar.is-agent { background: var(--surface); border: var(--border) solid var(--ink); color: var(--ink); font-size: 11px; }
.admin-feed__main { flex: 1; min-width: 0; }
.admin-feed__line { font-size: var(--type-ui-compact); line-height: 1.4; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.admin-feed__entity { color: var(--ink-soft); }
.admin-feed__meta { margin-top: 2px; }
.admin-detail__activity { margin-top: var(--space-4); }
/* Overview → Recent activity table (filterable, paged 12). Sits under its own
   collection-bar; rows are read-only so they don't take the .admin__row pointer. */
/* --- Support cases (issue-191): owner /support page + shared bits. --- */
.support-form { display: flex; flex-direction: column; gap: var(--space-3); margin-bottom: var(--space-5); }
.support-form__details { resize: vertical; min-height: 84px; }
.support-list { display: flex; flex-direction: column; gap: var(--space-3); }
.support-case { border: var(--border) solid var(--line); border-radius: var(--radius); padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-2); }
.support-case--closed { opacity: 0.65; }
.support-case__head { display: flex; align-items: center; gap: var(--space-3); }
.support-case__when { margin-left: auto; }
.support-case__body { margin: 0; font-size: var(--type-body); white-space: pre-wrap; }
.support-status { display: inline-flex; align-items: center; gap: 6px; }
.support-status::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--muted-2); }
.support-status--open::before { background: var(--accent-blue); }
.support-status--waiting_on_support::before { background: var(--accent-amber); }
.support-status--waiting_on_owner::before { background: var(--accent-green); }
.support-shots { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.support-shot { position: relative; display: inline-flex; }
.support-shot__img { width: 88px; height: 66px; object-fit: cover; border: var(--border) solid var(--line); border-radius: var(--radius); }
.support-shot__remove { position: absolute; top: -6px; right: -6px; width: 18px; height: 18px; border-radius: 50%; border: var(--border) solid var(--line); background: var(--surface); font-size: 10px; line-height: 1; cursor: pointer; }
.support-thread { display: flex; flex-direction: column; gap: var(--space-2); }
.support-msg { border-left: 2px solid var(--line); padding-left: var(--space-3); }
.support-msg--admin { border-left-color: var(--ink); }
.support-reply { display: flex; gap: var(--space-2); align-items: flex-end; }
.support-reply__input { flex: 1; resize: vertical; }

/* Admin detail drawers (issue-195): the base .panel width covers them since issue 25
   (the old 440px override would now be NARROWER than standard panels). */
.admin-detail-grid { display: flex; flex-direction: column; }
.admin-detail-row { display: grid; grid-template-columns: 1fr auto; align-items: baseline; gap: var(--space-3); padding: 5px 0; border-bottom: var(--border) solid var(--line-soft); }
.admin-detail-row:last-child { border-bottom: 0; }
.admin-detail-row > .label { color: var(--muted); }
.admin-detail-row__value { font-size: var(--type-ui-compact); text-align: right; overflow-wrap: anywhere; }
/* A titled control group in the drawer (Respond · Case status) — heading + its own row. */
.admin-detail-group { margin-top: var(--space-3); }

/* Admin owner-drawer danger zone (issue-194): separated, red-hairline block for the
   destructive lifecycle actions (suspend / permanent delete). */
.admin-danger { margin-top: var(--space-4); padding: var(--space-3); border: var(--border) solid var(--accent-red); border-radius: var(--radius); display: flex; flex-direction: column; gap: var(--space-2); align-items: flex-start; }
.admin-danger__head { color: var(--accent-red); }

/* --- Agent settings (issue-201): ready-made job cards + grouped MCP catalogue.
   issue-202 typography: important prose one step up (sm→md, xs→sm) with roomier
   line-height; only true metadata (counts, previews, status) stays .label-small.
   Hierarchy kept: titles strongest, prose next, metadata quiet. --- */
.recipe-lead { display: block; margin: 0 0 var(--space-2); font-size: var(--type-body); line-height: 1.55; color: var(--ink-soft); }
.recipe-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); margin-top: var(--space-3); }
@media (max-width: 640px) { .recipe-grid { grid-template-columns: 1fr; } }
.recipe-card { border: var(--border) solid var(--line); border-radius: var(--radius); padding: var(--space-3); display: flex; flex-direction: column; gap: 5px; }
.recipe-card__title { font-size: var(--type-body); font-weight: 600; }
.recipe-card__trigger { font-size: var(--type-ui-compact); line-height: 1.5; color: var(--ink-soft); }
.recipe-card__ladder { font-family: var(--font-mono); font-size: var(--type-ui-compact); color: var(--muted); overflow-wrap: anywhere; }
.recipe-card__rule { font-size: var(--type-ui-compact); color: var(--muted); line-height: 1.5; }
.recipe-more { align-self: flex-start; margin-top: var(--space-2); border: 0; background: none; color: var(--ink-soft); font-size: var(--type-ui-compact); cursor: pointer; padding: 0; }
.recipe-more:hover { color: var(--ink); text-decoration: underline; }
.tool-groups { border: var(--border) solid var(--line); border-radius: var(--radius); }
.tool-group + .tool-group { border-top: var(--border) solid var(--line-soft); }
.tool-group__head { display: flex; align-items: baseline; gap: var(--space-2); width: 100%; text-align: left; border: 0; background: none; padding: 10px 14px; cursor: pointer; }
.tool-group__head:hover { background: var(--surface-3); }
.tool-group__title { font-size: var(--type-body); font-weight: 600; }
.tool-group__head > .label { margin-left: auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tool-group__body { padding: 4px 14px 12px; display: flex; flex-direction: column; gap: 6px; }
.tool-group__row { display: flex; gap: var(--space-3); align-items: baseline; }
.tool-group__name { flex-shrink: 0; width: 190px; font-family: var(--font-mono); font-size: var(--type-ui-compact); }
.tool-group__desc { overflow-wrap: anywhere; font-size: var(--type-body); line-height: 1.5; color: var(--ink-soft); }
@media (max-width: 640px) {
  .tool-group__row { flex-direction: column; gap: 2px; }
  .tool-group__name { width: auto; }
}

/* Privacy note under the image-upload dropzone (issue-186). */
.block-image__note { display: block; margin-top: var(--space-2); font-size: var(--type-meta); color: var(--muted); }
/* Usage page segmented control (issue-189): a row of underline tabs, ink for active. */
.admin-tabs { display: flex; gap: var(--space-4); border-bottom: var(--border) solid var(--line); margin: 0 0 var(--space-4); }
.admin-tab { padding: var(--space-2) 0; margin-bottom: -1px; border: 0; border-bottom: 2px solid transparent; background: none; color: var(--ink-soft); font-size: var(--type-ui-compact); cursor: pointer; }
.admin-tab:hover { color: var(--ink); }
.admin-tab.is-active { color: var(--ink); border-bottom-color: var(--ink); font-weight: 600; }
.admin-activity__table { margin-top: var(--space-2); }
.admin-activity__row td { font-size: var(--type-ui-compact); }
.admin-activity__actor { display: inline-flex; align-items: center; gap: var(--space-2); min-width: 0; }
.admin-activity__actor > span:last-child { overflow: hidden; text-overflow: ellipsis; }
/* Owner (username) filter — a compact search field sitting in the activity bar
   next to the actor/action dropdowns. Reuses the topbar search look. */
.admin-activity__owner { width: 200px; height: 30px; }
@media (max-width: 720px) { .admin-activity__owner { flex: 1 1 100%; width: auto; } }
/* Owner Agents (issue-187): local search field in the agents filter bar. */
.admin-agents__searchbox { width: 260px; height: 30px; }
@media (max-width: 720px) { .admin-agents__searchbox { flex: 1 1 100%; width: auto; } }

/* --- Public MCP docs (story 030c) --- */
.docs-code {
  background: var(--ink); color: var(--surface);
  font-family: var(--font-mono); font-size: var(--type-ui-compact); line-height: 1.5;
  padding: var(--space-4); border-radius: var(--radius);
  /* Prompts/configs wrap instead of hiding behind a horizontal scrollbar
     (owner, follow-up to Issue 27); long tokens (keys, URLs) break cleanly.
     Entry code blocks are a separate system with their own wrap toggle. */
  white-space: pre-wrap; overflow-wrap: anywhere; margin: var(--space-3) 0;
}
.docs-tool-filter { max-width: 320px; margin: var(--space-3) 0 0; }
.docs-tools__empty { margin-top: var(--space-4); }
.docs-tool-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: var(--space-3); margin-top: var(--space-4); }
.docs-tool { display: flex; flex-direction: column; gap: 2px; padding: var(--space-3); border: var(--border) solid var(--line-soft); border-radius: var(--radius); }
.docs-tool__name { font-family: var(--font-mono); font-size: var(--type-ui-compact); color: var(--ink); }
/* Tool/recipe descriptions are documentation PROSE, not labels (issue-217 v378 retest):
   compact role size, UI face, normal case. code-flavoured desc lines (tool ladders,
   config snippets) keep their mono face from the element, only sized up. */
.docs-tool__desc { font-size: var(--type-ui-compact); line-height: 1.4; overflow-wrap: anywhere; } /* slash-joined arg tokens must break at 320px */
.docs-tool__desc.label { font-family: var(--font-ui); text-transform: none; letter-spacing: normal; }

/* "Connected now" dot (story 030c) — an agent with an open MCP session. */
.conn-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--accent-green); margin-right: 6px; vertical-align: middle; }
.mcp-guide__link { display: inline-block; margin-top: var(--space-3); color: var(--ink); font-size: var(--type-ui-compact); font-weight: 600; }

/* --- Responsive grid columns (issue-121) --------------------------------------
   These MUST live after every base grid declaration: media queries don't raise
   specificity, so at equal specificity the later rule wins. The shared @media block
   near the top of this file was defeated by base `.space-grid`/`.entry-grid`/… rules
   declared lower down (3-col base overrode the mobile 1-col on a 390px viewport). */
@media (max-width: 1024px) {
  .space-grid, .entry-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 720px) {
  .space-grid, .entry-grid, .section-grid, .plan-grid, .template-chooser {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Entry-editor mobile refinements at ≤720px (issue-148). Placed after the base
   editor/nav rules so equal-specificity overrides win on source order. */
@media (max-width: 720px) {
  /* The entry editor always renders the rail nav; on mobile it must be a full-width
     strip, not a 58px sliver. The compound selector outranks base .shell__nav--rail. */
  .shell__nav.shell__nav--rail { width: 100%; padding: var(--space-2) var(--space-4); }
  .shell__nav.shell__nav--rail .shell__nav-items { flex: 0 1 auto; min-height: 0; flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
  /* On a phone the rail is a wrapping horizontal strip: the icon scroller flows inline with the
     rest (no vertical scroll, no fade masks, no divider rule) — the whole strip wraps instead. */
  .shell__nav.shell__nav--rail .shell__nav-top { overflow: visible; }
  .shell__nav.shell__nav--rail .iconnav__scroll { flex: 0 1 auto; flex-direction: row; flex-wrap: wrap; overflow: visible; -webkit-mask-image: none; mask-image: none; }
  .shell__nav.shell__nav--rail .iconnav__divider { display: none; }
  /* Give prose more room on a phone: drop the editor's 32px inset to 16px. */
  .editor__main { padding: var(--space-4); }
  /* (The entry cover's phone bleed override lives in the fix-cluster K section at the end of this
     file — after its base rule, so it wins; media queries don't raise specificity.) */
  /* 130 — image captions always stack below the image on phones. */
  .block-image__caption, .read__caption { flex-basis: 100%; min-width: 0; max-width: none; text-align: center; }
}

/* --- Living knowledge map (story 075) ------------------------------------------
   Monochrome canvas: white ground, thin rings, ink bodies — accent appears only
   as the section marker it already is. Freshness reuses the 073c tier classes
   (is-warm / is-warm--soft / is-glow), rendered here as a green halo ring. The
   map is STILL when the workspace is idle: the only continuous animation is an
   agent dot in transit (rAF-driven, no CSS keyframes). */
.map-head { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-3); flex-wrap: wrap; }
.map-head__spacer { flex: 1; }
.map-actions { display: inline-flex; align-items: center; gap: 4px; }
.map-info { position: relative; display: inline-flex; align-items: center; }
.map-info-btn {
  width: 23px; height: 23px; display: inline-flex; align-items: center; justify-content: center;
  padding: 0; border: var(--border) solid var(--line); border-radius: 50%;
  background: var(--surface); color: var(--ink-soft); cursor: pointer;
  font-family: var(--font-mono); font-size: var(--type-ui-compact); letter-spacing: 0;
}
.map-info-btn:hover, .map-info-btn[aria-expanded="true"] { background: var(--surface-3); color: var(--ink); border-color: var(--ink-soft); }
.map-info-pop {
  position: absolute; top: calc(100% + 7px); left: 0; z-index: 8;
  width: min(360px, 88vw); padding: var(--space-3);
  display: flex; flex-direction: column; gap: var(--space-3);
  background: var(--surface); border: var(--border) solid var(--line); border-radius: var(--radius);
}
.map-info-pop[hidden] { display: none; }
.map-info-pop__section { display: flex; flex-direction: column; gap: var(--space-2); }
.map-info-pop__title {
  font-family: var(--font-mono); font-size: var(--type-meta); letter-spacing: var(--mono-tracking);
  text-transform: uppercase; color: var(--ink);
}
.map-info-list {
  margin: 0; display: grid; grid-template-columns: max-content minmax(0, 1fr);
  gap: 5px var(--space-3); font-size: var(--type-ui-compact); line-height: 1.35;
}
.map-info-list dt {
  font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: var(--mono-tracking);
  color: var(--ink-soft); text-transform: uppercase;
}
.map-info-list dd { margin: 0; color: var(--muted); min-width: 0; }
.map-insights-btn {
  font-family: var(--font-mono); font-size: var(--type-ui-compact); letter-spacing: var(--mono-tracking);
  padding: 3px 10px; border: var(--border) solid var(--line); border-radius: var(--radius);
  background: var(--surface); color: var(--ink-soft); cursor: pointer;
}
.map-insights-btn.is-on { background: var(--ink); color: var(--surface); border-color: var(--ink); }

.map-wrap { position: relative; border: var(--border) solid var(--line); border-radius: var(--radius); background: var(--surface); }
.map-wrap:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
/* 075d: the canvas is draggable to pan (grab), zoomable by wheel. touch-action:none
   keeps a touch-drag from scrolling the page instead of panning. */
.map-canvas { display: block; width: 100%; height: auto; max-height: calc(100vh - 162px); aspect-ratio: 1; margin: 0 auto; cursor: grab; touch-action: none; }
.map-wrap.is-panning .map-canvas { cursor: grabbing; }
.map-empty { padding: var(--space-6); display: flex; flex-direction: column; gap: var(--space-4); align-items: flex-start; }
.map-lens-note {
  position: absolute; top: var(--space-3); right: var(--space-3); z-index: 4;
  max-width: min(360px, calc(100% - 2 * var(--space-3)));
  padding: 5px 8px; color: var(--muted); text-align: right;
  background: color-mix(in oklch, var(--surface) 86%, transparent);
  border: var(--border) solid var(--line); border-radius: var(--radius);
  backdrop-filter: blur(6px);
}
.map-lens-note[hidden] { display: none; }

/* Map control chips — mono, compact, matching the Insights button language. */
.map-zoom-btn {
  font-family: var(--font-mono); font-size: var(--type-ui-compact); letter-spacing: var(--mono-tracking);
  min-width: 24px; padding: 3px 7px; cursor: pointer; color: var(--ink-soft);
  background: var(--surface); border: var(--border) solid var(--line); border-radius: var(--radius);
}
.map-zoom-btn:hover:not(:disabled) { background: var(--surface-3); color: var(--ink); }

/* 095: the 3D toggle — same mono chip as its lens siblings; pressed = inverted,
   matching the Insights/Attention on-state. Monochrome, no shadows. */
.map-3d-btn.is-on { background: var(--ink); color: var(--surface); border-color: var(--ink); }

/* 075e: time-travel slider — a bottom-right overlay that rewinds the map through
   its own history. Hidden until the workspace spans a scrubbable stretch of time. */
.map-time {
  position: absolute; right: var(--space-3); bottom: var(--space-3); z-index: 4;
  display: flex; align-items: center; gap: var(--space-2);
  padding: 5px 8px 5px 10px;
  background: color-mix(in oklch, var(--surface) 82%, transparent);
  border: var(--border) solid var(--line); border-radius: var(--radius);
  backdrop-filter: blur(6px);
}
.map-time[hidden] { display: none; }
/* Fixed width (fits the longest localized date) so the bar never jumps as the
   date text changes width. */
.map-time__readout { color: var(--ink-soft); width: 120px; text-align: right; white-space: nowrap; overflow: hidden; }
.map-time__range { width: 240px; accent-color: var(--ink); cursor: pointer; }
/* Transport: back · play/pause · forward — a connected trio of mono chips. */
.map-time__transport { display: inline-flex; gap: 2px; }
.map-time__btn {
  font-family: var(--font-mono); font-size: var(--type-ui-compact); line-height: 1;
  min-width: 26px; padding: 4px 6px; cursor: pointer; color: var(--ink-soft);
  background: var(--surface); border: var(--border) solid var(--line); border-radius: var(--radius);
}
.map-time__btn:hover { background: var(--surface-3); color: var(--ink); }
.map-time__btn--play.is-playing { background: var(--ink); color: var(--surface); border-color: var(--ink); }

/* Agent dots are a "now" concept — hide them while the map is rewound. */
.map-wrap.is-history .map-layer-agents { display: none; }

.map-ring { fill: none; stroke: var(--line-soft); stroke-width: 1; }
.map-ring-label {
  font-family: var(--font-mono); font-size: 12px; letter-spacing: var(--mono-tracking);
  fill: var(--ink-soft); cursor: pointer; paint-order: stroke; stroke: var(--surface); stroke-width: 4px;
}
.map-ring-label:hover, .map-ring-label:focus-visible { fill: var(--ink); outline: none; }
.map-hub { fill: var(--ink); }

.map-node { cursor: pointer; outline: none; }
.map-node .map-body { transition: transform .2s ease; transform-box: fill-box; transform-origin: center; }
.map-node:hover .map-body, .map-node:focus-visible .map-body { transform: scale(1.25); }
.map-node:focus-visible .map-body { stroke: var(--ink); stroke-width: 1.5; }
.map-node--section .map-body { stroke: var(--surface); stroke-width: 1.5; }
.map-node--entry .map-body { fill: var(--ink); opacity: .5; }
.map-node--entry:hover .map-body { opacity: .9; }
.map-node--overflow .map-body { fill: var(--surface-3); stroke: var(--line); stroke-width: 1; }
.map-overflow-label { font-family: var(--font-mono); font-size: 8px; fill: var(--ink-soft); pointer-events: none; }
.map-node-label {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--mono-tracking);
  fill: var(--ink-soft); pointer-events: none; paint-order: stroke; stroke: var(--surface); stroke-width: 3px;
}
/* 075g: zoom-aware labels. Entry titles are a level-of-detail layer (lighter, shown
   only when zoomed in); --hidden is the collision/LOD off-switch. JS sets the actual
   font-size/stroke-width inline (counter-scaled by zoom); these are just fallbacks. */
.map-entry-label { fill: var(--muted); }
.map-label--hidden { display: none; }
/* 130: semantic zoom. Sub-lines (entry meta · excerpt+labels · section counts) are
   revealed per tier by the relabel solver — JS drives --hidden, this just styles.
   The attention marker + count earn always-on visibility once a node is zoomed to
   the detail tier (.map-node--lod2), independent of the Attention lens. */
.map-entry-sub, .map-section-sub { fill: var(--muted); }
.map-attn-count {
  font-family: var(--font-mono); letter-spacing: var(--mono-tracking);
  fill: var(--ink-soft); paint-order: stroke; stroke: var(--surface);
  display: none; pointer-events: none;
}
.map-node--lod2 .map-attn,
.map-node--lod2 .map-attn-count { display: block; }

/* Freshness halo — the 073c tiers on map bodies. Warm = full voice, soft = an
   agent reading (half voice), glow = the minutes-long cooling tail. */
.map-halo { fill: none; stroke: var(--accent-green); opacity: 0; transition: opacity .5s ease; }
.map-node.is-warm .map-halo { opacity: .9; stroke-width: 2; }
.map-node.is-warm--soft .map-halo { opacity: .45; stroke-width: 1.5; }
.map-node.is-glow .map-halo { opacity: .22; stroke-width: 1.5; transition: opacity 2s ease; }
.map-ring.is-warm, .map-ring.is-warm--soft { stroke: color-mix(in oklch, var(--accent-green) 45%, var(--line)); }
.map-ring.is-glow { stroke: color-mix(in oklch, var(--accent-green) 22%, var(--line-soft)); }

/* Agent presence dots (075b): named, travelling to what they touch. */
.map-agent { opacity: 1; transition: opacity .6s ease; pointer-events: none; }
.map-agent--fading { opacity: 0; }
.map-agent__dot { fill: var(--ink); stroke: var(--surface); stroke-width: 1.5; }
.map-agent--write .map-agent__dot { fill: var(--accent-green); }
.map-agent__name {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--mono-tracking);
  fill: var(--ink); paint-order: stroke; stroke: var(--surface); stroke-width: 3px;
}

/* Insight overlay (075c): faint duplicate ties + stale dimming. */
.map-tie { stroke: var(--ink-soft); stroke-width: 1; stroke-dasharray: 3 4; opacity: .45; transition: opacity .22s ease; }
/* 058 — explicit entry links: solid + a touch stronger than the dashed inferred ties
   (intent over resemblance), still calm enough to sit under the bodies. */
.map-tie--link { stroke-dasharray: none; opacity: .6; stroke-width: 1.2; }
/* Contextual focus lens (issue-199): with a focused section/space, every tie fades
   almost away and the focused neighborhood's ties come back up — hover, proximity,
   keyboard focus, and the open popover (selected node) all drive the same classes. */
.map-layer-ties.ties-focus .map-tie { opacity: .07; }
.map-layer-ties.ties-focus .map-tie.is-hot { opacity: .85; }
.map-layer-ties.ties-focus .map-tie--link.is-hot { opacity: .95; }
.map-node--stale { opacity: .3; }

/* Attention lens (075f): spotlight what needs the owner. Active only while the
   lens is on (.map-wrap.attn-on). Calm nodes dim; nodes with open tasks or
   unresolved comments carry one blinking marker; fresh/actionable nodes stay lit. */
.map-attn { fill: var(--accent-amber); stroke: var(--surface); stroke-width: 1.5; display: none; pointer-events: none; }
.map-wrap.attn-on .map-node:not(.map-node--bright) .map-body { opacity: .12; }
.map-wrap.attn-on .map-node:not(.map-node--bright) .map-node-label,
.map-wrap.attn-on .map-node:not(.map-node--bright) .map-overflow-label { opacity: .3; }
.map-wrap.attn-on .map-node--bright.map-node--entry .map-body { opacity: .9; }
.map-wrap.attn-on .map-attn { display: block; animation: map-attn-blink 1.15s ease-in-out infinite; }
@keyframes map-attn-blink { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { .map-wrap.attn-on .map-attn { animation: none; } }
.map-pop__attn { color: var(--accent-amber); }

.map-tip {
  position: absolute; z-index: 4; max-width: 240px; pointer-events: none;
  font-family: var(--font-mono); font-size: var(--type-meta); letter-spacing: var(--mono-tracking);
  color: var(--ink); background: var(--surface); border: var(--border) solid var(--line);
  border-radius: var(--radius); padding: 4px 8px;
}
.map-pop {
  position: absolute; z-index: 5; width: 240px;
  background: var(--surface); border: var(--border) solid var(--line); border-radius: var(--radius);
  padding: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2);
}
.map-pop__head { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.map-pop__dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.map-pop__title { font-size: var(--type-ui-compact); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.map-pop__meta { color: var(--muted); }
.map-pop__open {
  align-self: flex-start; margin-top: var(--space-1); padding: 3px 10px; cursor: pointer;
  font-family: var(--font-mono); font-size: var(--type-meta); letter-spacing: var(--mono-tracking);
  background: var(--ink); color: var(--surface); border: var(--border) solid var(--ink); border-radius: var(--radius);
}

/* Reduced motion: a static map — freshness stays as (static) opacity, hover
   scaling and travel animation drop. Agent dots appear attached (JS side). */
@media (prefers-reduced-motion: reduce) {
  .map-node .map-body, .map-halo, .map-agent { transition: none; }
  .map-node:hover .map-body, .map-node:focus-visible .map-body { transform: none; }
}

/* ===== Boot loader ==============================================================
   Ships in index.html inside #app so it shows before app.js even runs; the first
   mount() replaces it. Ato files a stray capture while we fetch (spec:
   documents/ato-mascot.md — integer scales only; 96×72 = 8px cells). The fade-in
   is delayed so fast loads never flash it; reduced-motion users get the static
   sprite via the <picture> source in index.html. */
.boot {
  min-height: 100vh; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: var(--space-4);
  opacity: 0; animation: boot-in 200ms ease-out 400ms forwards;
}
.boot__sprite { width: 96px; height: 72px; image-rendering: pixelated; }
.boot__label {
  margin: 0; font: 500 var(--text-xs)/1 var(--font-mono);
  letter-spacing: var(--mono-tracking-wide); text-transform: uppercase; color: var(--muted);
}
@keyframes boot-in { to { opacity: 1; } }

/* ===== App-shell responsive overrides ==========================================
   Relocated to the file end so they win on source order — media queries don't
   raise specificity, so the twin block near the top of this file was defeated by
   the later base `.shell__nav` / `.top-bar` / `.panel` / … rules (the same cascade
   trap that already forced grids + the editor down here; issue-156). At ≤720px the
   fixed 240px sticky sidebar became a full-width top bar, but the base width/position
   overrode it, leaving the nav a viewport-tall column that pushed the main content
   off-screen. These rules restore the intended stacked layout. */
@media (max-width: 720px) {
  /* Nav → a compact full-width top bar that flows with the page (no sticky 240px
     column). Items lay out in a wrapping row so it stays short instead of a tall
     vertical stack, and the account zone sits inline at the end. */
  .shell__body { flex-direction: column; }
  .shell__nav {
    width: 100%; height: auto; position: static; overflow: visible;
    border-right: 0; border-bottom: var(--border) solid var(--line-soft);
    flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: space-between;
    gap: var(--space-2) var(--space-4); padding: var(--space-3) var(--space-4);
  }
  .shell__nav-top { overflow: visible; display: flex; flex-flow: row wrap; align-items: center; gap: var(--space-2) var(--space-3); }
  .account-zone { flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); border-top: 0; padding-top: 0; }
  /* The account links are a vertical menu on desktop; inline them so the bar stays short. */
  .account-menu { flex-flow: row wrap; align-items: center; gap: var(--space-1) var(--space-3); }
  .account-menu__item { padding: 2px 0; }
  .shell__main { padding: var(--space-4); }
  .space-layout { margin: calc(-1 * var(--space-4)); }
  .top-bar { flex-wrap: wrap; height: auto; padding: 10px var(--space-4); }
  .collection-bar { flex-wrap: wrap; }
  .collection-bar__filter { flex: 1 1 100%; width: auto; }
  .panel { width: 100%; }
  .dialog, .version-modal { width: calc(100vw - 24px); }
  .auth__card { width: 100%; }
  /* Issue 219: keep cells on one line when narrow — the horizontal scroll lives on
     .admin__table-scroll (a labelled local region), NEVER on the table/page. The old
     `display:block; overflow-x:auto` on the table itself let descendants escape into
     page-level scroll at 320px. */
  .admin__table { white-space: nowrap; }
}

/* ================================================================
   UX-review fix batch (2026-07-06) — one labelled section per fix
   cluster; each agent appends ONLY inside its own section.
   ================================================================ */

/* --- fix-cluster A: entry details rail + comments copy --- */
/* Details-rail icon heading now uses the picker-head row (label left, "No icon" chip
   right — the space-settings pattern). Keep the rail's 10px heading rhythm, and zero
   the heading's own bottom margin so both flex items sit on one centered line. */
.details__section .picker-head { margin-bottom: 10px; }
.details__section .picker-head .details__heading { margin-bottom: 0; }
/* Cover caption: one line with a title-attr tooltip holding the full explainer. */
.details__hint[title] { cursor: help; }

/* --- fix-cluster B: settings (agent keys, usage, account) --- */

/* Usage: over-quota is a warning state, not decoration — red bar fill + red count,
   plus a one-line note under the affected meter/row (settings-view.ts adds these
   classes only when used > limit). */
.usage-bar__fill--over { background: var(--accent-red); }
.usage-over { color: var(--accent-red); }

/* Account: display-name auto-save flash. The old markup reused .editor__status —
   a 7px CSS dot from the entry editor — so its "Saved" text was invisible. This is
   a plain mono flash next to the field that fades back out after a save. */
.settings-save-flash { opacity: 0; transition: opacity .25s ease; white-space: nowrap; }
.settings-save-flash.is-visible { opacity: 1; }
.settings-save-flash--error { color: var(--accent-red); }

/* --- fix-cluster C: map (labels, locale, insights) --- */

/* Space names now sit ON their ring (JS picks a body-dodging angle + text-anchor),
   so the label reads outward from the ring instead of stacking down the old centre
   column. dominant-baseline centres the text on its on-ring anchor point. */
.map-ring-label { dominant-baseline: middle; }

/* Insight / attention notes are now per-chip so each carries its own hover tooltip.
   Keep the compact mono look — the chip is just an inline span; the separator is
   muted; the whole chip shows a help cursor to advertise the explanation on hover. */
.map-note-chip { cursor: help; }
.map-note-sep { color: var(--line); }

/* --- fix-cluster D: workspace inbox file button --- */

/* --- fix-cluster E: panel open animation opacity --- */
/* Backdrop entrances animate the dim only: background-color from transparent up to
   the element's own computed background (`to` omitted on purpose). Never animate
   `opacity` on a backdrop — the panel/modal surface is a CHILD of it, so a parent
   opacity fade made the surface see-through while opening and background text bled
   through the controls for the length of the animation. */
@keyframes a-dim { from { background-color: transparent; } }

/* --- fix-cluster F: route-transition feedback --- */

/* The defect: a route click left the OLD view frozen for 1–3s with no feedback.
   The top progress bar *was* wired (api client), but its 9s linear-ish ramp to
   85% meant it had crept only a few percent in the first second — invisibly slow,
   so the click read as dead. Here we (a) give the bar a fast initial climb that
   then decelerates (real NProgress feel), and (b) paint an immediate pressed
   state on the clicked control while the next view's data loads. The swap itself
   stays fetch-then-swap (main.ts), so the old view is interactive the whole time. */

/* (a) Snappier progress ramp. Same start (0) / cap (~90%) as before, but a
   keyframe curve: a visible jump to ~28% in the first 120ms, then a long slow
   creep — so >150ms transitions read instantly, sub-150ms ones barely register
   (settled and hidden before they'd matter). Overrides the shared --active ramp
   by source order; --done still owns the finish. Slightly bolder (accent + 3px)
   so it's legible against any view. */
.progress-bar { height: 3px; background: var(--accent-blue); }
.progress-bar--active { width: 90%; transition: none; animation: f-progress 9s cubic-bezier(.15,.85,.5,1) forwards; }
.progress-bar--done { animation: none; } /* let the --done width/opacity transition run */
@keyframes f-progress {
  0%   { width: 0; }
  4%   { width: 28%; }  /* ~120ms in: the fast, reassuring first jump */
  30%  { width: 62%; }
  100% { width: 90%; }  /* asymptote — never 100% until the swap completes (--done) */
}
@media (prefers-reduced-motion: reduce) {
  /* No creep animation; just a static, clearly-visible bar that the swap clears. */
  .progress-bar--active { animation: none; width: 40%; }
}

/* (b) Immediate pressed state on the clicked control (set synchronously in
   navigate() before any fetch). Keyed off [data-nav-pressed], cleared centrally
   when the new view mounts. Generic so it covers nav rows, entry/space/section
   cards, account-menu items and breadcrumb targets without touching their view
   renderers. Reuses each control's existing "engaged" look (the active nav-row
   fill / the card's ink border) plus a tiny press displacement. */
[data-nav-pressed] { transition: transform .04s ease; }
.nav-row[data-nav-pressed], .nav-row[data-nav-pressed]:hover { background: var(--surface-3); border-left-color: var(--ink); }
.entry-card[data-nav-pressed], .space-card[data-nav-pressed], .section-card[data-nav-pressed] { border-color: var(--ink); transform: translateY(0) scale(0.995); }
.account-menu__item[data-nav-pressed] { background: var(--surface-3); }
/* A control the router is navigating away from shouldn't invite a second click. */
[data-nav-pressed] { cursor: default; }

/* --- fix-cluster G: search snippets --- */

/* Matched query terms in ⌘K palette rows (title + excerpt). Rendered as real <mark>
   nodes (XSS-safe — see highlightNodes), so they need their own paint: a soft accent
   wash + inherited colour, no default browser yellow. On the selected (inverted) row
   the wash flips to a translucent light so it stays legible on the dark background. */
.palette__item mark.hl {
  background: color-mix(in srgb, var(--accent, #6366f1) 22%, transparent);
  color: inherit;
  border-radius: 3px;
  padding: 0 1px;
}
.palette__item.is-selected mark.hl {
  background: var(--on-ink-wash);
  color: var(--on-ink);
}
/* The excerpt line was clipped to one line (nowrap + ellipsis); give a match-centred
   excerpt a touch more room and let it wrap to two lines so the highlighted term isn't
   pushed off the end. Still capped so a long entry can't balloon the row. */
.palette__item-snippet {
  white-space: normal;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  line-clamp: 2;
}

/* Key-kind label in the agents popover ("OAuth" / "atm_xxxx…"). It sat unconstrained
   and got squeezed, clipping to "OAUTH…"; keep it on one line and let the agent name
   column (agents-popover__main) do the shrinking instead. */
.agents-popover__kind { flex-shrink: 0; white-space: nowrap; }

/* --- fix-cluster N1: left-nav structure (back row, pinned, account zone, sticky header) --- */

/* Back row: "‹ Spaces" — reads as "up one level", not a section. Quiet muted ink,
   same row metrics as other nav rows, with a hairline setting it off from the
   SECTIONS group below. */
.nav-back { color: var(--muted); margin-bottom: 6px; padding-bottom: 9px; border-bottom: var(--border) solid var(--line-soft); border-radius: 0; }
.nav-back:hover { color: var(--ink); background: var(--surface-3); }
.nav-back__chev { display: inline-flex; justify-content: center; width: 14px; flex-shrink: 0; font-size: 15px; line-height: 1; }
/* issue-162: the back row now names the immediate parent (space/section), which can be long —
   let the label SHRINK so it ellipsis-truncates (base .nav-row__name carries min-width:0 +
   overflow/ellipsis; the full title stays in the title attr + accessible label). */
.nav-back .nav-row__name { flex: 0 1 auto; }

/* Sticky group headers: the SECTIONS "+" header (and the PINNED toggle) stay put as
   the section list scrolls inside .shell__nav-top. Opaque background so rows don't
   show through; a hairline underline once content scrolls beneath keeps it legible. */
.nav-section--sticky, .nav-section--toggle { position: sticky; top: 0; z-index: 1; background: var(--surface); }

/* PINNED disclosure header: a full-width button styled like a section header, with a
   caret on the right. Collapsed-mode only; the workspace keeps a plain (non-button) header. */
.nav-section--toggle { width: 100%; border: 0; cursor: pointer; font: inherit; color: inherit; text-align: left; }
.nav-section--toggle:hover { background: var(--surface-3); }
.nav-pinned__caret { color: var(--muted-2); font-size: 12px; line-height: 1; }

/* --- fix-cluster N2: entry view rail + entries panel --- */

/* 1a — the rail's "All spaces" home button + hairline divider, crowning the section icons.
   Matches the .iconnav__section footprint (34px, same radius) but reads as the way "up". */
.iconnav__home { flex-shrink: 0; width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center; border: var(--border) solid transparent; background: none; border-radius: var(--radius); color: var(--ink-soft); cursor: pointer; }
.iconnav__home:hover { background: var(--surface-3); color: var(--ink); }
.iconnav__divider { flex-shrink: 0; width: 20px; height: 0; border-top: var(--border) solid var(--line); margin: 2px 0; }

/* 1b — hand scrolling to the INNER icon scroller so the home button + divider stay pinned above
   it. The rail's outer .shell__nav-top scrolls the whole column by default (global rule); disable
   that here and let .shell__nav-items fill the height so the inner scroller can size + scroll. */
.shell__nav--rail .shell__nav-top { overflow: hidden; }
.shell__nav--rail .shell__nav-items { flex: 1 1 auto; min-height: 0; width: 100%; }

/* section-icon scroller: the icons scroll HERE (under the pinned home button), so a long space no
   longer overflows invisibly. A thin scrollbar on hover + top/bottom fade masks that toggle via
   .has-fade-* (set from a passive scroll handler). The fades are white→transparent masks
   (monochrome system — no shadows); they clip the icons as they enter/leave the scroller. */
.iconnav__scroll {
  flex: 1 1 auto; min-height: 0; width: 100%;
  display: flex; flex-direction: column; align-items: center; gap: var(--space-1);
  overflow-y: auto; overflow-x: hidden;
  scrollbar-width: thin; scrollbar-color: transparent transparent;
}
.iconnav__scroll:hover { scrollbar-color: var(--line) transparent; }
.iconnav__scroll::-webkit-scrollbar { width: 4px; }
.iconnav__scroll::-webkit-scrollbar-thumb { background: transparent; border-radius: 4px; }
.iconnav__scroll:hover::-webkit-scrollbar-thumb { background: var(--line); }
/* The fade is a CSS mask that fades the top/bottom edge to transparent — only where there's
   clipped content in that direction. Both edges can be active at once (scrolled mid-list). */
.iconnav__scroll.has-fade-top { -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 20px); mask-image: linear-gradient(to bottom, transparent 0, #000 20px); }
.iconnav__scroll.has-fade-bottom { -webkit-mask-image: linear-gradient(to top, transparent 0, #000 20px); mask-image: linear-gradient(to top, transparent 0, #000 20px); }
.iconnav__scroll.has-fade-top.has-fade-bottom { -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 20px, #000 calc(100% - 20px), transparent 100%); mask-image: linear-gradient(to bottom, transparent 0, #000 20px, #000 calc(100% - 20px), transparent 100%); }

/* 2 — entries-panel filter: a quiet full-width inline filter, shown only past 12 entries.
   Reuses the collection-bar__filter visual language (section view) at rail width. */
.entries-col__filter-row { padding: 0 12px 6px; }
.entries-col__filter { width: 100%; height: 30px; }
.entries-col__filter-count { color: var(--muted); }
.entries-col__item--filtered { display: none; }
/* No matches: a calm mono note so the empty list doesn't read as "no entries". */
.entries-col__list.is-empty-filter::after { content: "No matching entries"; display: block; padding: 12px 11px; color: var(--muted); font-family: var(--font-mono); font-size: var(--type-meta); }

/* 3 — entry-row metadata on ONE line: the type/label shrinks with an ellipsis, the age stays
   fully visible. A flex row: type flex-shrinks, separator + age hold their size. */
.entries-col__meta { display: flex; align-items: baseline; gap: 4px; min-width: 0; white-space: nowrap; }
.entries-col__meta-type { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.entries-col__meta-sep, .entries-col__meta-age { flex-shrink: 0; }

/* --- Story 109: the dynamic home — intent zones on one grid (102's boards, split) --- */

/* Home grid: six intent zones auto-placed on two EQUAL columns with one center seam
   page-long — capture · resume / active spaces (full width) / needs-you · notes /
   archive (full width). Needs-you and Briefing are STABLE boards — always present so
   the review row never jumps (issue-177). Only Resume/Archive collapse (:empty →
   display:none) when they hold nothing; a missing resume trail lets the capture card
   span the row alone (the :has rule — the 102 idiom). */
.home-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); align-items: start; margin-bottom: var(--space-4); }
.home-grid > .home-active, .home-grid > .home-archive { grid-column: 1 / -1; min-width: 0; }
.home-grid > .home-capture { margin: 0; min-width: 0; align-self: stretch; display: flex; flex-direction: column; }
.home-grid > .home-resume, .home-grid > .home-needs, .home-grid > .home-notes { min-width: 0; }
.home-grid > .home-resume:empty, .home-grid > .home-archive:empty { display: none; }
.home-grid:has(> .home-resume:empty) > .home-capture { grid-column: 1 / -1; }
.home-grid .collection-bar { margin: 0 0 var(--space-3); }

/* Capture fills its stretched box (story 109): the composer grows to the card
   height (matched to the Resume board in row 1) so the writing area is generous.
   The JS auto-grow still sets an inline height as you type — flex-grow adds the
   free space on top of that basis, and the field scrolls once content exceeds. */
.home-capture .inbox__composer { flex: 1 1 auto; display: flex; flex-direction: column; }
.home-capture .inbox__field { flex: 1 1 auto; }

/* Board feet: the overflow doors ("All N ›" · "Past briefings · N ›"). */
.board__foot { border: 0; border-top: var(--border) solid var(--line-soft); background: none; padding: 7px var(--space-3); font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); text-align: left; cursor: pointer; }
.board__foot:hover { color: var(--ink); background: var(--surface-3); }

/* Resume rows lead with their context chips; the title takes the slack. */
.hb-row--resume .hb-row__prov { flex: 0 1 auto; }
.hb-row--resume .hb-row__text { flex: 1 1 auto; }

/* Overflow popover (story 109, lib/popover.ts) — the captures-pop idiom, board-anchored. */
.overflow-pop { position: fixed; z-index: 90; width: 440px; max-width: calc(100vw - 24px); display: flex; flex-direction: column; max-height: min(72vh, 620px); background: var(--surface); border: var(--border) solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-menu); overflow: hidden; animation: a-pop .12s ease; }
.overflow-pop:focus { outline: 0; }
.overflow-pop__head { flex-shrink: 0; padding: var(--space-3) var(--space-3) var(--space-2); }
.overflow-pop__body { flex: 1; min-height: 0; overflow-y: auto; padding: 0 0 var(--space-2); scrollbar-width: thin; }
.overflow-pop__body .hb-row:first-child { border-top: 0; }
/* Reading surface: the row TEXT wins the space fight; provenance yields. */
.overflow-pop__body .hb-row__text { flex: 1 1 auto; }
.overflow-pop__body .hb-row__prov { flex: 0 1 auto; }
.overflow-pop__body .hb-note__history-item:first-child { border-top: 0; }
.overflow-pop__body .hb-note__history-item { padding-right: var(--space-3); padding-left: var(--space-3); }

/* Resume board (space view): the shared shell (.board) already styles the frame + rows. */
.board--resume { align-self: stretch; }

/* Resume rows carry a space › section context lead; keep the chips tight and let
   them shrink (with ellipsis) so the title still gets room on a narrow column. */
.resume-lead { display: inline-flex; align-items: center; gap: 6px; min-width: 0; flex-shrink: 1; overflow: hidden; }
.resume-chip--space { color: var(--muted); }
.resume-lead .resume-chip { min-width: 0; }
.resume-lead .resume-chip > span:not(.resume-chip__sep) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Header metadata: the away chip's old data, absorbed — "since Fri · your last visit". */
.hb-since { margin-left: auto; font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); white-space: nowrap; }
/* Issue 218 (WCAG reflow): at narrow widths the nowrap recency line was wider than
   the header and dragged the whole document into horizontal scroll — drop it onto
   its own row under the title instead of letting it propagate width. */
@media (max-width: 480px) {
  .board__head { flex-wrap: wrap; }
  .hb-since { flex-basis: 100%; margin-left: 0; white-space: normal; }
}

/* (a) DATA rows — compact single line, five slots: glyph · text · provenance · time ·
   (hide × lands in story 103; the slot is omitted, not dead). Same hairline-row idiom
   as .board__row; buttons navigate to their entry like Resume rows did. */
.hb-data { display: flex; flex-direction: column; }
/* The row is a flex CONTAINER; its clickable content is the inner .hb-row__main
 * (a button when the row has a target), so the hide × (story 103) is a real
 * sibling button — never a button nested inside a button. */
.hb-row { display: flex; align-items: center; gap: 8px; width: 100%; min-width: 0; padding: 8px var(--space-3); border-top: var(--border) solid var(--line-soft); }
.hb-row:hover { background: var(--surface-3); }
.hb-row--inert:hover { background: none; }
.hb-row__main { display: flex; align-items: center; gap: 8px; flex: 1 1 auto; min-width: 0; text-align: left; font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
.hb-row--inert .hb-row__main { cursor: default; }
/* Hide × — quiet, revealed on row hover/keyboard focus (the .inbox__delete idiom);
 * always shown on touch (no hover to reveal it). */
.hb-row__hide { flex-shrink: 0; border: 0; background: none; cursor: pointer; color: var(--muted); font-size: var(--text-md); line-height: 1; padding: 2px 4px; border-radius: var(--radius); opacity: 0; transition: opacity 0.12s ease; }
.hb-row:hover .hb-row__hide, .hb-row:focus-within .hb-row__hide, .hb-row__hide:focus-visible { opacity: 1; }
.hb-row__hide:hover { color: var(--ink); background: var(--surface-3); }
@media (hover: none) { .hb-row__hide { opacity: 1; } }
.hb-row__glyph { flex-shrink: 0; width: 15px; text-align: center; color: var(--muted); font-size: var(--text-sm); }
.hb-row__text { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; font-size: var(--type-ui-compact); }
.hb-row__text--quiet { font-weight: 400; color: var(--ink-soft); }
.hb-soft { font-weight: 400; color: var(--ink-soft); }
.hb-row__prov { flex: 1 1 auto; min-width: 0; display: inline-flex; align-items: center; gap: 4px; overflow: hidden; white-space: nowrap; }
.hb-row__prov .resume-chip { min-width: 0; max-width: 22ch; }
.hb-row__prov .resume-chip > span:not(.resume-chip__sep) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hb-row__prov--surface { justify-content: flex-end; font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted); }
.hb-row__time { flex-shrink: 0; margin-left: auto; font-family: var(--font-mono); font-size: var(--type-meta); color: var(--muted); }
/* Paging: the standard reveal button rides the same hairline-row rhythm. */
.hb-data > .show-more { border-top: var(--border) solid var(--line-soft); }

/* (b) NOTE rows — softer multi-line blocks (curator prose · surprises): mono byline,
   body inset behind a hairline left rule, expand › for the collapsed curator note.
   The gift ≠ duty distinction lives in this styling (surprises are always last). */
.hb-note { position: relative; padding: 9px var(--space-3) 10px; border-top: var(--border) solid var(--line-soft); background: var(--surface-2); }
.board__body > .hb-note:first-child, .board__body > .hb-data:first-child > .hb-row:first-child { border-top: 0; }
.hb-note__byline { display: flex; align-items: center; gap: 7px; font-family: var(--font-mono); font-size: 10px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); margin-bottom: 5px; }
.hb-note__body { margin: 0; padding-left: 10px; border-left: 2px solid var(--line); font-size: var(--type-body); line-height: 1.6; color: var(--ink-soft); white-space: pre-line; }
.hb-note__body--preview { white-space: normal; }
.hb-note__body .briefing__body { white-space: normal; }
.hb-note__img { max-width: 100%; max-height: 220px; display: block; border: var(--border) solid var(--line-soft); border-radius: var(--radius); }
.hb-note__expand { border: 0; background: none; padding: 0; cursor: pointer; font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; color: var(--muted); white-space: nowrap; }
.hb-note__expand:hover { color: var(--ink); }
.hb-note__foot { display: flex; align-items: baseline; gap: var(--space-4); margin-top: 6px; padding-left: 10px; }
/* The relocated Past-briefings link + its lazy history list, inside the expanded note. */
.hb-note__past { border: 0; background: none; padding: 0; cursor: pointer; font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
.hb-note__past:hover { color: var(--ink); text-decoration: underline; }
.hb-note__history { margin-top: var(--space-2); }
.hb-note__history[hidden] { display: none; }
.hb-note__history-item { padding: var(--space-2) 0 var(--space-2) 10px; border-top: var(--border) solid var(--line-soft); opacity: 0.85; }
/* The surprise ×: the old "Nice" (mark seen) — quiet until hovered, like .inbox__delete. */
.hb-note__hide { position: absolute; top: 8px; right: 10px; border: 0; background: none; cursor: pointer; color: var(--muted); font-size: var(--text-md); line-height: 1; padding: 2px 4px; border-radius: var(--radius); }
.hb-note__hide:hover { color: var(--ink); background: var(--surface-3); }
.hb-note--surprise .hb-note__byline, .hb-note--curator .hb-note__byline { padding-right: 18px; }

/* Narrow/mobile: one column, re-ordered by intent for a check-in device — capture
   FIRST (compose-first, the phone is a capture device), then duty (needs-you), the
   notes, the trail, the spaces. Same DOM, CSS `order` only; provenance chips drop
   on narrow data rows — the row still navigates to its entry. */
@media (max-width: 760px) {
  .home-grid { grid-template-columns: 1fr; }
  .home-grid > .home-capture { order: 1; }
  .home-grid > .home-needs { order: 2; }
  .home-grid > .home-notes { order: 3; }
  .home-grid > .home-resume { order: 4; }
  .home-grid > .home-active { order: 5; }
  .home-grid > .home-archive { order: 6; }
  .hb-row__prov { display: none; }
  .hb-row__text { flex: 1 1 auto; }
}

@media (max-width: 560px) {
  .home-grid { gap: var(--space-3); }
}

/* --- fix-cluster W: workspace-wide Activity on home --- */
/* The workspace feed leads each row with its space name — a quiet mono label, no accent
   colour (spaces read as context, sections keep their coloured icon marker). Sits in the
   same meta line as the section marker, mirroring the section idiom. */
.activity__where--space {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--mono-tracking);
  color: var(--muted);
  text-transform: uppercase;
}

/* --- fix-cluster S: settings panels auto-save --- */

/* The space + section settings panels auto-save every control (no "Save changes" button).
   A shared save-status flash sits at the top of the panel body — the flash element carries
   .label (mono uppercase) + .settings-save-flash (the account display-name idiom: opacity fade,
   red on failure). The row reserves a fixed line so the flash doesn't nudge the controls when it
   appears/disappears, and right-aligns it under the panel head. .panel-save-flash is a hook for
   any future per-panel tuning; the base classes carry the look. */
.panel-save-row { display: flex; justify-content: flex-end; align-items: center; min-height: 16px; margin-top: calc(var(--space-2) * -1); }
/* Inside panels the picker heading is a flex row, so the entry rail's float collapses
   and "ICON"+"SAVED" touch — space the per-control flash instead of floating it. */
.panel .details__saved { float: none; margin-left: 8px; }

/* --- fix-cluster V: responsive pass (mobile nav, top bar, editor stack) ---------------
   Live-sweep defects at 500/768/1024px. These live at the file end so they win on source
   order over the base .shell__nav / .top-bar / .entries-col rules (media queries don't
   raise specificity — the same cascade trap the app-shell block above already navigates).
   The mobile-nav guards below are covered by responsive-css.test.ts.
   ====================================================================================== */

/* Finding 5 — collection-bar controls must not wrap INTERNALLY: "+ New space" split over
   two lines, "Sort: Recent" wrapped, the "10 / 20 SPACES" count broke mid-phrase. Each
   control stays a whole unit; the BAR wraps between them (its flex-wrap is set ≤720). This
   is width-independent (a control should never wrap its own label), so it's not gated behind
   a media query. Applies to the shared .collection-bar (workspace + section views). */
.collection-bar > .btn,
.collection-bar__btn,
.collection-bar > .label { white-space: nowrap; }
/* …and the bar itself may wrap at ANY width (desktop never triggers it) — without this the
   nowrap trailing count clips at the container edge between 721 and ~900px. */
.collection-bar { flex-wrap: wrap; row-gap: var(--space-2); }

/* The mobile nav header bar + its toggle exist only ≤720 (finding 1) — hidden by default so
   the desktop sidebar layout is untouched. Shown by the ≤720 rules below. */
.shell__navbar, .shell__nav-toggle { display: none; }

/* Finding 4 — Resume rows: the TITLE lost to the context lead at narrow widths (the title
   truncated to one glyph while "Space › Section ›" kept full width). Priority: the context
   lead truncates FIRST, the title keeps a sane minimum, the meta never wraps. The lead is
   allowed to shrink to nothing; the title floors at 40% so it always reads. (CSS-only — no
   Resume.ts markup change.) */
.board__row > .resume-lead { flex: 0 1 auto; min-width: 0; }
.board__primary { flex: 1 1 40%; min-width: 40%; }
/* Each context chip caps + ellipsizes so a long space/section name yields room first. */
.resume-lead .resume-chip { max-width: 18ch; }

@media (max-width: 720px) {
  /* Finding 1 — mobile nav disclosure. The full nav (back row/Spaces/Map + pinned rows +
     account card) renders statically ABOVE the content ≤720, so every page began with the
     whole nav ("1.5 screens" of scroll-past). Collapse it behind a ☰ Menu toggle in a
     compact header row; closed by default (chrome() ships it collapsed on each navigation —
     no persistence). The account zone stays reachable inside the expanded nav. The rail
     variant (entry editor) has no toggle — its horizontal icon strip is already short. */
  .shell__navbar { display: flex; align-items: center; padding: var(--space-2) var(--space-4); border-bottom: var(--border) solid var(--line-soft); background: var(--surface); }
  .shell__nav-toggle {
    display: inline-flex; align-items: center; gap: var(--space-2);
    height: 32px; padding: 0 var(--space-3);
    border: var(--border) solid var(--line); border-radius: var(--radius);
    background: var(--surface); color: var(--ink); cursor: pointer;
    font-family: var(--font-mono); font-size: var(--text-xs);
    text-transform: uppercase; letter-spacing: var(--mono-tracking-wide);
  }
  .shell__nav-toggle:hover { background: var(--surface-3); }
  .shell__nav-toggle__glyph { font-size: 14px; line-height: 1; }
  /* Collapsed is the default (the class is absent until you open it): hide the nav block. */
  .shell__nav:not(.shell__nav--open):not(.shell__nav--rail) { display: none; }
  /* Open: the existing ≤720 full-width wrapping nav (app-shell block above) already lays it
     out; nothing more needed here beyond letting it show. */

  /* Finding 2 — a deliberate compact mobile top bar. It was wrapping to two ragged rows with
     the agents chip orphaned bottom-left, and half-overlapping content mid-scroll. Keep it
     ONE row: the breadcrumb takes the slack and truncates (its middle crumbs already collapse
     to "…" ≤640), the right-side controls stay clustered and don't wrap. The bar keeps its
     opaque background + bottom border while sticky, so nothing bleeds underneath. */
  .top-bar { flex-wrap: nowrap; height: 53px; padding: 0 var(--space-4); gap: var(--space-2); }
  .top-bar__breadcrumb { flex: 1 1 auto; min-width: 0; overflow: hidden; white-space: nowrap; }
  /* The last (current) crumb carries the ellipsis so a long title truncates instead of
     shoving the controls off-row. */
  .top-bar__breadcrumb .top-bar__crumb--current { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
  /* Drop the ⌘K label — the glyph alone is the affordance at phone width (Activity is
     already icon-only ≤640; the agents cluster is compact). Right controls never wrap. */
  .cmdk .label { display: none; }
  .cmdk, .top-bar__actions, .agents-cluster { flex-shrink: 0; }
  .top-bar__spacer { flex: 0 1 auto; }
}

/* Finding 3 — sibling-entries panel as a full-width collapsible block. The mechanics live
   OUTSIDE the ≤720 query (they run at both ≤1024 and ≤720) so the tablet stack and the phone
   rail-strip share one implementation. Guarded to ≤1024 so the desktop Miller column ignores
   `.entries-col--collapsed` entirely (it's always the open side column there). */
@media (max-width: 1024px) {
  /* Full width in the stacked layout. This MUST live here (file end): the identical override
     in the early ≤1024 block is defeated by the base `.entries-col { width: 264px }` that
     appears LATER in source order — the exact media-cascade trap responsive-css.test.ts guards. */
  .entries-col { width: 100%; border-right: 0; border-bottom: var(--border) solid var(--line-soft); }
  /* One-row header that toggles: section icon + name + count + "+", with the disclosure caret
     leading. On desktop this chrome is hidden (below). */
  .entries-col__disclosure { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; flex-shrink: 0; border: 0; background: none; cursor: pointer; color: var(--ink-soft); padding: 0; }
  .entries-col__disclosure:hover { color: var(--ink); }
  .entries-col__disclosure-caret { font-size: 11px; line-height: 1; transition: transform .15s ease; }
  .entries-col[class]:not(.entries-col--collapsed) .entries-col__disclosure-caret { transform: rotate(90deg); }
  .entries-col__head-count, .entries-col__head-add { display: inline-flex; }
  .entries-col__head-count { margin-left: auto; }
  /* Collapsed: only the head row shows — the __sub, filter row and the list are gone, so the
     editor starts right after the header (no void, no clipped island). */
  .entries-col--collapsed .entries-col__sub,
  .entries-col--collapsed .entries-col__filter-row,
  .entries-col--collapsed .entries-col__list { display: none; }
  /* Open: the list is full-width with a bounded height and clean overflow — rows never cut
     mid-item the way the old fixed 220px island did. */
  .entries-col:not(.entries-col--collapsed) .entries-col__list { max-height: 46vh; overflow-y: auto; }
}
@media (min-width: 1025px) {
  /* Desktop: the entries column is the always-open Miller side column. Hide the mobile-only
     disclosure chrome and never honour the collapsed state. Restore each element's INTENDED
     display — `display: revert` would roll a div back to `block`, which flattened the __sub
     header's flex row so the "Entries" label, count and "+" stacked vertically (Issue 2). */
  .entries-col__disclosure, .entries-col__head-count, .entries-col__head-add { display: none; }
  .entries-col--collapsed .entries-col__sub { display: flex; }
  .entries-col--collapsed .entries-col__filter-row,
  .entries-col--collapsed .entries-col__list { display: block; }
}

/* --- fix-cluster C2: connect-a-tool readability ---------------------------------
   The "Connect a tool" panel, redesigned for a 3-action task: three sentence-case
   primary steps (Inter body type, not the all-caps .label mono), a full-width copy
   box that never clips the URL, one quiet OAuth caption, then everything else folded
   into closed-by-default disclosures. A live agent_presence event (033c) swaps the
   steps for a green confirmation. Monochrome + the existing --accent-green success
   token; no fixed widths, so it stacks full-width on the ≤720 mobile panel. */

/* Primary path — the swappable slot (steps → live confirmation). */
.connect-primary { display: flex; flex-direction: column; gap: var(--space-3); }
.connect-primary__steps { display: flex; flex-direction: column; gap: var(--space-4); }

/* A numbered step in readable BODY type (Inter, sentence case). The number is
   styled; the text is prose — the opposite of the old all-caps mono label. */
.primary-step { display: flex; align-items: flex-start; gap: var(--space-3); }
.primary-step__num {
  flex: none; display: inline-grid; place-items: center;
  width: 22px; height: 22px; margin-top: 1px; border-radius: 50%;
  background: var(--ink); color: var(--surface);
  font-size: var(--type-ui-compact); font-weight: 600; line-height: 1;
}
.primary-step__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.primary-step__text { margin: 0; color: var(--ink); font-size: var(--type-body); line-height: 1.5; }
/* The copy box under a step takes the full available width — the URL never clips. */
.primary-step__body .copy-block { width: 100%; }

/* The single quiet OAuth caption + the green expected-result lead-in. */
.connect-caption { margin: 0; }
.connect-primary .connect-success { margin: 0; }

/* Live success (033c): the steps are replaced by a green confirmation. */
.connect-confirm { display: flex; flex-direction: column; gap: var(--space-2); }
.connect-confirm__line { margin: 0; color: var(--accent-green); font-size: var(--type-ui-compact); font-weight: 600; line-height: 1.5; }

/* Disclosures — native <details>, restyled: sentence-case summary + a caret, and a
   readable inner body. Retargets the old boxed idiom to a quiet, foldable row. */
.connect-disclosure { border-top: var(--border) solid var(--line-soft); }
.connect-disclosure__summary {
  cursor: pointer; list-style: none; user-select: none;
  display: flex; align-items: center; gap: 6px;
  padding: var(--space-3) 0; color: var(--ink-soft);
  font-family: var(--font-ui); font-size: var(--type-ui-compact); text-transform: none; letter-spacing: normal;
}
.connect-disclosure__summary::-webkit-details-marker { display: none; }
.connect-disclosure__summary::before { content: "›"; display: inline-block; transition: transform .12s ease; color: var(--muted-2); }
.connect-disclosure[open] > .connect-disclosure__summary::before { transform: rotate(90deg); }
.connect-disclosure[open] > .connect-disclosure__summary { color: var(--ink); }
.connect-disclosure__summary:hover { color: var(--ink); }
.connect-disclosure__summary:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; border-radius: var(--radius); }
.connect-disclosure__inner { display: flex; flex-direction: column; gap: var(--space-2); padding: 0 0 var(--space-3); }
.connect-disclosure__inner .copy-block { width: 100%; }

/* Code/prompt boxes: full available width; short strings (the URL) sit un-clipped,
   longer ones (curl, the test prompt) scroll with a visible thin scrollbar. */
/* Issue 27: the full-width + Copy-below anatomy is now the .copy-block BASE
   (issue 222 extended it to /docs/mcp); panels keep only their tighter padding. */
.connect-panel .copy-block { width: 100%; }
.connect-panel .copy-block .docs-code { padding: var(--space-2) var(--space-3); } /* wrap comes from the base .docs-code */

/* The advanced static-key / manual flows still stack a .label over a copy box; the
   onboarding card's later inline-flex .connect-step must not flatten them here. */
.connect-panel .connect-step { display: flex; flex-direction: column; align-items: stretch; gap: var(--space-2); }

/* --- Inline connect card (story 123, mockup scene 1) ----------------------------
   With 0 connections the connect card IS the Your agent page — same component as
   the drawer body, framed as a card at the content column's width. The drawer
   classes below (.connect-h, .tool-grid, .prompt-card, …) are unscoped, so the
   card needs only a frame here. */
.connect-inline { margin: var(--space-4) 0 var(--space-6); }
.connect-inline .connect-drawer__step { border: var(--border) solid var(--line); border-radius: var(--radius); padding: var(--space-5); background: var(--surface); }
@media (max-width: 720px) {
  .connect-inline { margin: var(--space-3) 0 var(--space-5); }
  .connect-inline .connect-drawer__step { padding: var(--space-4); }
}

/* Slimmed MCP-endpoint reference row (Advanced fold). */
.mcp-guide--slim .copy-block { width: 100%; }

/* --- fix-cluster K: letter-field covers --- */
/* An opt-in animated header built entirely of a page's own letters (waves / grass motifs). The
   canvas physics live in components/cover/*; here is just the bordered mount + the compact picker.
   Monochrome by construction (ink glyphs at varying alpha on white) — matches the design system. */

/* The bordered canvas wrapper. Bounded, no shadows/gradients; the canvas sets its own height. */
.cover { position: relative; width: 100%; overflow: hidden; border-radius: var(--radius); background: var(--surface); border: var(--border) solid var(--line-soft); }
.cover__canvas { display: block; width: 100%; }

/* Header mount: a quiet banner above the title/header (entry editor + space/section views). */
.cover-mount { margin: 0 0 var(--space-4); }
.cover-mount:empty { display: none; margin: 0; }
/* The SPACE + SECTION cover is a first-class full-width top surface: it bleeds out of the main
   column's var(--space-6) padding so it starts flush at the upper-left (next to the nav, below the
   top bar) and spans the full content width, dropping the card border/radius. */
.cover-mount--space { margin: calc(-1 * var(--space-6)) calc(-1 * var(--space-6)) var(--space-5); }
.cover-mount--space .cover { border: 0; border-radius: 0; background: var(--surface); }
.cover-mount--space:empty { margin: 0; }
/* The ENTRY cover is a first-class full-width header too (matches the space cover): it stretches
   past the editor__main reading width and bleeds out of the var(--space-6) padding to span the
   full column flush at the top, dropping the card border/radius. The :not() keeps its specificity
   above the reading-width / align variants on .editor__main > * so it wins regardless of order. */
.editor__main > .cover-mount:not(.cover-mount--space) {
  align-self: flex-start; /* opt out of the column's align-items:center so it doesn't recentre */
  max-width: none;
  width: calc(100% + 2 * var(--space-6)); /* fill the reading column PLUS both padding insets */
  margin: calc(-1 * var(--space-6)) 0 var(--space-5) calc(-1 * var(--space-6));
}
.editor__main > .cover-mount:not(.cover-mount--space) .cover { border: 0; border-radius: 0; }
.editor__main > .cover-mount:empty { margin: 0; }

/* The picker (entry Details · space + section settings): two segmented rows, Cover then Field,
   in the app's segmented-toggle idiom. Field appears only when a motif is chosen. */
.cover-picker { display: flex; flex-direction: column; gap: var(--space-2); }
.cover-picker__row { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
/* The head names the control (label left) + carries the "No cover motif" chip (right). Its own
   picker-head margin-bottom would double the flex gap, so zero it — the column gap owns spacing.
   Two-class selector so it also beats `.details__section .picker-head` (10px) in the entry rail. */
.cover-picker .cover-picker__head { margin-bottom: 0; }
/* The motif seg holds 6 fixed-width options — let it WRAP to a second row instead of
   clipping past a 320px viewport with no scroll path (issue-217 v378 retest). */
.cover-picker__seg { flex: 0 1 auto; min-width: 0; flex-wrap: wrap; }
/* Shrink-wrapped segments need their own horizontal padding — the base .segmented__item
   is padding:0/flex:1 (sized by a full-width container), which jams the labels together
   ("OffWavesGrass") when the container hugs its content. */
.cover-picker__seg .segmented__item { flex: 0 0 auto; padding: 0 12px; }

/* ≤720: the base entry-cover bleed above uses the desktop var(--space-6) inset; on a phone the
   editor drops to a var(--space-4) inset, so match the bleed to it (else it overshoots the panel
   edge and scrolls horizontally). This override sits AFTER the base rule so it wins — media queries
   don't raise specificity, and the base was moved to the end of this section. */
@media (max-width: 720px) {
  .editor__main > .cover-mount:not(.cover-mount--space) {
    width: calc(100% + 2 * var(--space-4));
    margin-top: calc(-1 * var(--space-4));
    margin-left: calc(-1 * var(--space-4));
  }
}

/* --- Settings › Appearance (documents/themes.md, phase 2) ---------------------------------
   Theme radio cards (System · Paper · Ink) + the global code-theme select's discoverable
   home. Tokens only — the mini previews' colors are inline styles set by settings-view.ts
   from THEME_PREVIEW (lib/theme.ts): a swatch is a PICTURE of its theme and must not follow
   the active theme's tokens (the Paper card stays paper-colored while Ink is active). */
.theme-picker { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-3); max-width: 560px; }
.theme-card { display: flex; flex-direction: column; border: var(--border) solid var(--line); border-radius: var(--radius); background: var(--surface); padding: 0; text-align: left; cursor: pointer; font: inherit; overflow: hidden; }
.theme-card:hover { border-color: var(--muted-2); }
.theme-card:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.theme-card.is-selected { border-color: var(--ink); }
.theme-card__preview { display: flex; height: 56px; }
.theme-card__pane { flex: 1; min-width: 0; padding: 8px 8px 0; display: block; }
.theme-card__mini { display: flex; flex-direction: column; gap: 3px; height: 100%; border-width: var(--border); border-style: solid; padding: 6px; border-bottom: 0; }
.theme-card__bar { display: block; height: 3px; flex-shrink: 0; }
/* Accent strip in a swatch whose identity is its color (Vivid) — the 7 markers, full-bleed. */
.theme-card__accents { display: flex; gap: 0; height: 4px; margin: -6px -6px 4px; flex-shrink: 0; }
.theme-card__accents i { flex: 1; display: block; }
.theme-card__name { display: flex; align-items: center; gap: var(--space-2); padding: 8px 10px; border-top: var(--border) solid var(--line-soft); font-size: var(--type-ui-compact); font-weight: 600; color: var(--ink); }
.theme-card__dot { width: 12px; height: 12px; flex-shrink: 0; border-radius: 50%; border: 1.5px solid var(--line); display: inline-flex; align-items: center; justify-content: center; }
.theme-card.is-selected .theme-card__dot { border-color: var(--ink); }
.theme-card.is-selected .theme-card__dot::after { content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--ink); }
.theme-card__tag { margin-left: auto; }
.appearance-note { max-width: 560px; }
.appearance-code__select { height: 32px; min-width: 280px; padding: 0 var(--space-3); border: var(--border) solid var(--line); border-radius: var(--radius); background: var(--surface); color: var(--ink); font-family: var(--font-ui); font-size: var(--type-ui-compact); }
@media (max-width: 560px) { .theme-picker { grid-template-columns: 1fr; } }

/* --- Ato/brand sprites on Ink (themes.md hazard #2) ----------------------------------------
   The Ato poses are pure-monochrome ink-on-transparent pixel drawings, referenced as external
   <img> assets (so currentColor can't reach them). For a greyscale sprite, invert(1) IS the
   theme-correct re-ink — light body, dark face — and keeps one canonical asset per pose
   (documents/ato-mascot.md). Scoped per usage site, NOT blanket: the landing's Ato never
   matches (the landing is Paper-locked), and the error toast's sprite is exempt — it sits in
   its own white chip (.toast__sprite) by design, theme-stable like a photo. */
:root[data-theme="ink"] .boot__sprite,
:root[data-theme="ink"] .empty-state__sprite,
:root[data-theme="ink"] .blog-feature__ato,
:root[data-theme="ink"] .blog-signoff__ato { filter: invert(1); }

/* --- Ink: dark-mode fix for the two LARGE surfaces that fake "a dark region" with
   background:var(--ink) (a deliberate dark band / dark code block on light themes). On Ink,
   var(--ink) flips light, so they'd become bright slabs on the dark page. Re-cast them as
   elevated DARK panels with light text. (Small controls that use var(--ink) — selected
   chips, avatars, badges — correctly stay light-on-dark: that's the active-state signal, not
   a bug, so they're untouched.) The tinted light themes keep the inverted dark band, matching
   Paper — only the true dark theme needs this. Shown on /docs/mcp (the .lp-connect band + its
   nested lp-steps) and Settings › Agent keys & MCP (.docs-code); the landing is Paper-locked. */
:root[data-theme="ink"] .lp-connect {
  background: var(--surface-2); color: var(--ink);
  border: var(--border) solid var(--line);
}
:root[data-theme="ink"] .lp-connect__title,
:root[data-theme="ink"] .lp-step__title { color: var(--ink); }
:root[data-theme="ink"] .lp-connect__lead,
:root[data-theme="ink"] .lp-step__body { color: var(--ink-soft); }
:root[data-theme="ink"] .lp-connect__kicker,
:root[data-theme="ink"] .lp-step__n { color: var(--muted); }
:root[data-theme="ink"] .docs-code {
  background: var(--surface-3); color: var(--ink);
  border: var(--border) solid var(--line);
}

/* --- Vivid (story 109): the new meaning-bearing color duties. Each reads a section's
   accent from a --sec custom prop set at the render site (section-view header, shell nav
   rows) — where --sec isn't set these selectors don't match — or a label's --chip. Every
   value is a color-mix of that accent with the theme surface, so the SAME rule works for
   all 7 hues. Confined to [data-theme="vivid"]; other themes read none of this. Buttons and
   body text are untouched — actions stay ink. ------------------------------------------- */
/* Section header: a section-colored wash band with the accent as a left rule (echoes nav). */
:root[data-theme="vivid"] .space-head:has(.section-head__title) {
  background: linear-gradient(to right, color-mix(in oklch, var(--sec) 9%, var(--surface)), var(--surface) 62%);
  border-left: 3px solid var(--sec);
  border-radius: 0 var(--radius) var(--radius) 0;
  margin-top: 0;
  padding: var(--space-3) var(--space-4);
}
/* Active section in the rail: its own color instead of grey + ink. */
:root[data-theme="vivid"] .nav-row--active {
  background: color-mix(in oklch, var(--sec) 8%, var(--surface));
  border-left-color: var(--sec);
}
/* Label chips go from outlined-with-a-dot to a confident tinted pill. The name deepens
   toward ink so it stays AA on the faint fill; the dot keeps the full accent. */
:root[data-theme="vivid"] .label-chip {
  background: color-mix(in oklch, var(--chip, var(--accent-blue)) 14%, var(--surface));
  color: color-mix(in oklch, var(--chip, var(--accent-blue)) 70%, var(--ink));
}
:root[data-theme="vivid"] .label-chip--more {
  background: var(--surface-3); color: var(--ink-soft);
}

/* --- issue-159: collapsible home review boards (Needs you · Briefing) --- */
/* A heading-wrapped disclosure button toggles the board body; the header stays a
   compact clickable row with a chevron affordance. Reset the button to inherit the
   board title's type (monochrome, no new colour — design system). */
.board__head--collapsible { cursor: pointer; }
.board__title .board__toggle {
  display: inline-flex; align-items: center; gap: var(--space-2);
  border: 0; background: none; padding: 0; margin: 0; cursor: pointer;
  font: inherit; letter-spacing: inherit; color: inherit; text-align: left;
}
.board__chevron { font-family: var(--font-mono); font-size: 12px; line-height: 1; color: var(--muted-2); }
.board__toggle:hover .board__chevron, .board__head--collapsible:hover .board__chevron { color: var(--ink); }
.board__toggle:focus-visible { outline-offset: 2px; border-radius: var(--radius); } /* colour from the global :focus-visible */

/* --- issue-161: always-visible Resume / Open-actions panels (empty state) --- */
/* Shared Ato empty state for the space-dashboard boards. It fills the panel body and
   holds a min-height so an empty panel keeps roughly a populated panel's stature — and
   when it sits beside a populated sibling, flex-stretch equalises the two exactly. */
.panel-empty { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--space-2); text-align: center; padding: var(--space-5) var(--space-4); color: var(--ink-soft); }
/* 12×9 sprite at a 4px integer cell scale, pixelated so the blocks stay crisp
   (spec: documents/ato-mascot.md — same pose the empty section view greets with). */
.panel-empty__sprite { width: 48px; height: 36px; image-rendering: pixelated; opacity: 0.9; }
.panel-empty__msg { margin: 0; font-size: var(--type-ui-compact); color: var(--muted); }
.board__body--empty, .open-actions__list--empty { flex: 1; display: flex; min-height: 148px; }
/* --- end issue-161 --- */

/* ===================================================================
 * Agent connections v2 (mockup agent_connections_v2): a calm management
 * surface + a Choose→Connect→Verify drawer + a per-agent Manage panel.
 * Token-only so it adapts to every theme. Reuses .agent-list/.panel/.copy-block.
 * =================================================================== */

/* Overview header: lead on the left, usage + primary action on the right. */
.agents-head { display: flex; align-items: flex-start; gap: var(--space-4); margin-bottom: var(--space-5); }
.agents-head__lead { flex: 1; min-width: 0; margin: 0; }
.agents-head__actions { display: flex; align-items: center; gap: var(--space-3); flex-shrink: 0; }
.agents-head__usage { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted); letter-spacing: var(--mono-tracking); }

/* Summary strip: active now / connections / slot left. */
.agents-summary { display: grid; grid-template-columns: repeat(3, 1fr); border: var(--border) solid var(--line); border-radius: var(--radius); margin-bottom: var(--space-5); }
.agents-summary__cell { padding: var(--space-3) var(--space-4); border-left: var(--border) solid var(--line); }
.agents-summary__cell:first-child { border-left: 0; }
.agents-summary__value { font-size: var(--text-lg); font-weight: 600; margin-bottom: 2px; }
.agents-summary__label { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: var(--mono-tracking); text-transform: uppercase; color: var(--muted); }

/* Section head with a right-aligned help link. */
.agents-conn-head { display: flex; align-items: center; margin-bottom: var(--space-2); }
.agents-conn-head__help { margin-left: auto; background: none; border: 0; border-bottom: var(--border) solid var(--line); padding: 0; color: var(--ink-soft); font-size: var(--type-body); cursor: pointer; }
.agents-conn-head__help:hover { color: var(--ink); border-color: var(--muted); }

/* Connection rows: avatar · identity · one contextual action. */
.conn-list { border: var(--border) solid var(--line); border-radius: var(--radius); }
.conn-row { display: grid; grid-template-columns: 36px minmax(0, 1fr) auto; gap: var(--space-3); align-items: center; padding: var(--space-3) var(--space-4); border-top: var(--border) solid var(--line-soft); }
.conn-row:first-child { border-top: 0; }
.conn-avatar { width: 34px; height: 34px; border: var(--border) solid var(--line); border-radius: var(--radius); display: flex; align-items: center; justify-content: center; font: 600 var(--text-xs)/1 var(--font-mono); background: var(--surface-2); color: var(--ink-soft); }
.conn-row__main { min-width: 0; }
.conn-name { display: flex; align-items: center; gap: var(--space-2); font-size: var(--type-ui-compact); font-weight: 600; margin-bottom: 4px; }
.conn-meta { font-family: var(--font-mono); font-size: var(--type-meta); line-height: 1.45; letter-spacing: var(--mono-tracking); color: var(--muted); overflow-wrap: anywhere; }
/* Meaningful guidance PROSE in settings (issue-217 v378 retest): body role, UI face —
   .conn-meta stays for true metadata (key prefixes, stamps, history values). */
.conn-guide { font-size: var(--type-body); line-height: 1.55; color: var(--ink-soft); overflow-wrap: anywhere; }

/* Status pill — mono, tinted per state (all theme tokens). */
.conn-status { display: inline-flex; align-items: center; gap: 5px; padding: 2px 7px; border-radius: var(--radius); font: 500 var(--text-xs)/1.3 var(--font-mono); letter-spacing: var(--mono-tracking); text-transform: uppercase; }
.conn-status--ok { background: color-mix(in oklch, var(--accent-green) 12%, var(--surface)); border: var(--border) solid color-mix(in oklch, var(--accent-green) 40%, var(--surface)); color: var(--accent-green); }
.conn-status--idle { background: var(--surface-3); border: var(--border) solid var(--line); color: var(--muted); }
.conn-status--pending { background: color-mix(in oklch, var(--accent-amber) 14%, var(--surface)); border: var(--border) solid color-mix(in oklch, var(--accent-amber) 40%, var(--surface)); color: var(--accent-amber); }
.conn-status--warn { background: color-mix(in oklch, var(--accent-red) 12%, var(--surface)); border: var(--border) solid color-mix(in oklch, var(--accent-red) 40%, var(--surface)); color: var(--accent-red); }

/* Foot row: durable learning link + endpoint hint. */
.agents-foot { display: flex; align-items: flex-start; gap: var(--space-5); margin-top: var(--space-4); padding-top: var(--space-3); border-top: var(--border) solid var(--line-soft); }
.agents-foot__link { background: none; border: 0; border-bottom: var(--border) solid var(--line); padding: 0; font-size: var(--type-ui-compact); font-weight: 500; color: var(--ink); cursor: pointer; }
.agents-foot__link:hover { border-color: var(--muted); }
.agents-foot__copy { font-size: var(--type-ui-compact); color: var(--muted); line-height: 1.4; margin-top: 2px; }
/* Endpoint hint: meta role (it's meaningful metadata — AA --muted), and it must WRAP at
   narrow widths — nowrap clipped it past the 320px viewport with no scroll path (issue-217). */
.agents-foot__endpoint { margin-left: auto; min-width: 0; font-family: var(--font-mono); font-size: var(--type-meta); letter-spacing: var(--mono-tracking); text-transform: uppercase; color: var(--muted); text-align: right; overflow-wrap: anywhere; }

/* "Agent instructions" inventory (story 113) — the workspace's briefs in one filterable
   list at the end of Settings → Agents. Shares the conn-list frame but NOT the conn-row
   grid (that one leads with a 36px avatar column these rows don't have): two columns,
   content + action. The instruction text clamps to two lines so a long brief can't
   balloon the table. */
.instr-block { margin-top: var(--space-6); padding-top: var(--space-4); border-top: var(--border) solid var(--line-soft); }
.instr-filter { display: flex; align-items: center; gap: var(--space-2); margin: var(--space-3) 0; flex-wrap: wrap; }
.instr-filter__search { flex: 1; min-width: 180px; max-width: 320px; margin-left: auto; }
.instr-list .conn-row { grid-template-columns: minmax(0, 1fr) auto; align-items: start; }
.instr-row__level { border: var(--border) solid var(--line-soft); border-radius: var(--radius); padding: 1px 6px; color: var(--muted); flex-shrink: 0; }
.instr-row .conn-name { font-size: var(--type-ui-compact); margin-bottom: 6px; flex-wrap: wrap; }
.instr-row__text { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; white-space: pre-line; color: var(--ink-soft); margin-bottom: 4px; }
/* Icon breadcrumb: space › section › entry, each chip an optional marker + name. */
.instr-crumb { display: inline-flex; align-items: center; gap: 5px; flex-wrap: wrap; min-width: 0; font-weight: 500; }
.instr-crumb__part { display: inline-flex; align-items: center; gap: 4px; }
.instr-crumb__sep { color: var(--muted-2); }

/* Editor slide-over (wide panel): a roomy field so a full brief is comfortable to write. */
.instr-editor__crumb { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; margin-bottom: var(--space-2); font-size: var(--type-meta); }
.instr-editor__field { min-height: 320px; }

/* Wide panel — content-heavy flows (Connect drawer, instructions editor, jobs); standard panels are 460px (issue 25). */
.panel--wide { width: 600px; }
@media (max-width: 640px) { .panel--wide { width: 100%; } }

/* Three-step drawer stepper. */
.connect-stepper { display: grid; grid-template-columns: repeat(3, 1fr); margin-top: var(--space-4); }
.connect-stepper__step { padding: var(--space-2) 0; border-bottom: 2px solid var(--line); font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: var(--mono-tracking); text-transform: uppercase; color: var(--muted); }
.connect-stepper__step.is-active { color: var(--ink); border-bottom-color: var(--ink); font-weight: 600; }
.connect-stepper__step.is-done { color: var(--accent-green); border-bottom-color: color-mix(in oklch, var(--accent-green) 55%, var(--surface)); }

/* Drawer body scaffolding. */
.connect-eyebrow { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: var(--mono-tracking); text-transform: uppercase; color: var(--muted); margin-bottom: var(--space-2); }
.connect-h { margin: 0 0 var(--space-1); font-size: var(--type-heading-sm); letter-spacing: -0.01em; }
.connect-lead { margin: 0 0 var(--space-4); font-size: var(--type-body); line-height: 1.5; color: var(--muted); }

/* Choose grid: recognizable apps, plain-language method line. */
.tool-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); }
.tool-card { text-align: left; min-height: 62px; border: var(--border) solid var(--line); border-radius: var(--radius); padding: 10px 11px; background: var(--surface); cursor: pointer; }
.tool-card:hover { background: var(--surface-3); }
.tool-card.is-selected { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); background: var(--surface-3); }
.tool-card__name { font-size: var(--type-ui-compact); font-weight: 600; margin-bottom: 4px; color: var(--ink); }
.tool-card__method { font-size: var(--text-xs); line-height: 1.35; color: var(--muted); }
.tool-card__caveat { display: inline-block; margin-top: 6px; padding: 1px 5px; border-radius: var(--radius); background: color-mix(in oklch, var(--accent-amber) 14%, var(--surface)); border: var(--border) solid color-mix(in oklch, var(--accent-amber) 40%, var(--surface)); color: var(--accent-amber); font: 500 10px/1.3 var(--font-mono); letter-spacing: var(--mono-tracking); text-transform: uppercase; }

/* Capability strip — four calm cells. */
.cap-strip { display: grid; grid-template-columns: repeat(4, 1fr); border: var(--border) solid var(--line); border-radius: var(--radius); margin-top: var(--space-4); }
.cap { padding: 10px; border-left: var(--border) solid var(--line-soft); min-width: 0; }
.cap:first-child { border-left: 0; }
.cap__name { font-size: var(--type-ui-compact); font-weight: 600; margin-bottom: 2px; }
.cap__copy { font-size: var(--type-meta); line-height: 1.35; color: var(--muted); }

/* Boxed note (security / control) — icon + copy. */
.connect-callout { display: grid; grid-template-columns: auto 1fr; gap: var(--space-2); padding: var(--space-3); background: var(--surface-3); border: var(--border) solid var(--line-soft); border-radius: var(--radius); font-size: var(--type-ui-compact); line-height: 1.45; color: var(--muted); margin-top: var(--space-4); }
.connect-callout strong { color: var(--ink); }

/* Setup-prompt preview card (shortened preview; Copy takes the full prompt). */
.prompt-card { border: var(--border) solid var(--ink); border-radius: var(--radius); margin: var(--space-4) 0 var(--space-3); }
.prompt-card__head { display: flex; align-items: center; gap: var(--space-2); padding: 10px 12px; border-bottom: var(--border) solid var(--line); }
.prompt-card__title { font-size: var(--type-ui-compact); font-weight: 600; }
.prompt-card__meta { margin-left: auto; display: flex; align-items: center; gap: var(--space-3); font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--mono-tracking); text-transform: uppercase; color: var(--muted); }
.prompt-preview { margin: 0; padding: 13px 14px; max-height: 240px; overflow: auto; background: var(--ink); color: var(--on-ink); font: 400 var(--text-xs)/1.55 var(--font-mono); white-space: pre-wrap; word-break: break-word; }
.prompt-omitted { display: block; color: var(--on-ink-faint); margin-top: 7px; }
.prompt-card__actions { display: flex; align-items: center; gap: var(--space-3); padding: 10px 12px; }
/* Issue 26 follow-up: the note reads at the house small size (no 10px one-offs
   beside a 13px button), the copy button keeps its full label width. */
.prompt-card__note { font-size: var(--type-ui-compact); color: var(--muted); line-height: 1.45; min-width: 0; }
.prompt-card__actions .btn { margin-left: auto; flex-shrink: 0; }
.text-btn { background: none; border: 0; border-bottom: var(--border) solid var(--muted-2); padding: 0; color: var(--ink-soft); font-size: var(--type-meta); font-weight: 500; cursor: pointer; }
.text-btn:hover { color: var(--ink); }

/* Verify sub-card + the "why this test" note, side by side. */
.connect-lower { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: var(--space-2); margin-bottom: var(--space-2); }
.connect-verify { border: var(--border) solid var(--line); border-radius: var(--radius); padding: var(--space-3); }
.connect-verify__head { display: flex; align-items: center; gap: var(--space-2); font-size: var(--type-ui-compact); font-weight: 600; margin-bottom: 6px; }
.connect-verify__pulse { width: 8px; height: 8px; border: 2px solid var(--ink); border-radius: 50%; box-shadow: 0 0 0 3px var(--surface-3); }
.connect-verify__copy { font-size: var(--type-ui-compact); line-height: 1.5; color: var(--muted); padding-left: 16px; }
.test-inline { font: 400 var(--text-xs) var(--font-mono); color: var(--ink-soft); background: var(--surface-3); border: var(--border) solid var(--line-soft); border-radius: var(--radius); padding: 8px 9px; margin-top: 8px; overflow-wrap: anywhere; }
.learn-note { border: var(--border) solid var(--line); border-radius: var(--radius); padding: var(--space-3); }
.learn-note__title { font-size: var(--type-ui-compact); font-weight: 600; margin-bottom: 5px; }
.learn-note__copy { font-size: var(--type-meta); line-height: 1.45; color: var(--muted); }

/* Verified step — success mark + first-task cards. */
.connect-success-mark { width: 42px; height: 42px; border: var(--border) solid color-mix(in oklch, var(--accent-green) 50%, var(--surface)); background: color-mix(in oklch, var(--accent-green) 12%, var(--surface)); color: var(--accent-green); display: flex; align-items: center; justify-content: center; font-size: 20px; border-radius: var(--radius); margin-bottom: var(--space-3); }
.task-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-2); margin: var(--space-3) 0; }
.task-card { border: var(--border) solid var(--line); border-radius: var(--radius); padding: var(--space-3); display: flex; flex-direction: column; min-height: 140px; }
.task-card__kind { font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--mono-tracking); text-transform: uppercase; color: var(--muted); margin-bottom: 7px; }
.task-card__name { font-size: var(--type-ui-compact); font-weight: 600; margin-bottom: 5px; }
.task-card__prompt { font-size: var(--type-meta); line-height: 1.45; color: var(--muted); margin-bottom: 10px; flex: 1; }

/* Manage panel blocks. */
.manage-status { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3); border: var(--border) solid var(--line); border-radius: var(--radius); margin-bottom: var(--space-4); }
.manage-status__main { flex: 1; min-width: 0; }
.manage-block { border-top: var(--border) solid var(--line); padding: var(--space-4) 0; }
.manage-block:first-of-type { border-top: 0; padding-top: 0; }
.manage-block__title { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: var(--mono-tracking); text-transform: uppercase; color: var(--muted); margin-bottom: var(--space-3); }
.manage-block__title .saved { float: right; color: var(--accent-green); text-transform: uppercase; letter-spacing: var(--mono-tracking); }
.detail-row { display: flex; gap: var(--space-3); margin-top: 9px; font-size: var(--type-ui-compact); color: var(--muted); }
.detail-row .k { width: 92px; flex: none; color: var(--muted); }
.detail-row .v { min-width: 0; overflow-wrap: anywhere; }
.manage-action { display: flex; align-items: center; gap: var(--space-4); }
.manage-action__copy { flex: 1; font-size: var(--type-ui-compact); line-height: 1.45; color: var(--muted); }

/* Footer: the primary (solid) action sits bottom-right; Cancel / the "what can it do"
 * link stays left. Scoped to the agent-settings surfaces so app-wide panels are unchanged. */
.connect-drawer .panel__footer .btn--solid,
.connect-panel .panel__footer .btn--solid { margin-left: auto; }
/* The Connections header reuses .section-title (which carries top/bottom margins) inside a
 * flex row — reset them so the header is a tight single row, spaced by the strip above. */
.agents-conn-head .section-title { margin: 0; }

/* ————— Flowchart block (story 127) —————
   Free-canvas SVG flowchart: monochrome, token-driven, one text style for element
   AND arrow labels. Edit mode = focus within (dot grid + toolbar); view/Read mode
   always fits the whole chart. The label editor is seamless: no box, same font. */
.block-flow { position: relative; }
.block-flow__toolbar { display: none; flex-wrap: wrap; align-items: center; gap: var(--space-1); padding: var(--space-1); border-bottom: var(--border) solid var(--line-soft); }
.block-flow.is-editing .block-flow__toolbar { display: flex; }
.block-flow__spacer { flex: 1; }
.block-flow__sep { width: var(--border); align-self: stretch; background: var(--line-soft); margin: 0 var(--space-1); }
.block-flow__btn { min-height: 28px; padding: 2px 10px; background: var(--surface); border: var(--border) solid var(--line); border-radius: var(--radius); cursor: pointer; }
.block-flow__btn:hover { background: var(--surface-3); }
.block-flow__btn[aria-pressed="true"] { background: var(--ink); color: var(--surface); border-color: var(--ink); }
.block-flow__chip { display: inline-flex; align-items: center; gap: 7px; min-height: 28px; padding: 2px 10px; background: var(--surface); border: var(--border) solid var(--line); border-radius: var(--radius); cursor: grab; touch-action: none; user-select: none; }
.block-flow__chip:active { cursor: grabbing; }
.block-flow__chip-icon { fill: var(--surface); stroke: var(--ink); }
.block-flow__ghost { position: fixed; z-index: 300; pointer-events: none; opacity: .85; }
.block-flow__canvas { position: relative; }
.block-flow__svg { display: block; width: 100%; touch-action: none; }
.block-flow:not(.block-flow--read):not(.is-editing) .block-flow__svg { cursor: pointer; }
.block-flow.is-editing .block-flow__svg { height: 440px; cursor: default;
  background-image: radial-gradient(var(--line-soft) 1px, transparent 1px); background-size: 24px 24px; }
/* contextual strips FLOAT at the selected element (positioned inline by flow-block.ts);
   centered above the selection via the transform, dropped below when the top would clip */
.block-flow__ctx { display: none; position: absolute; z-index: 4; align-items: center; gap: var(--space-1); padding: 4px 6px; background: var(--surface); border: var(--border) solid var(--line); transform: translate(-50%, -100%); box-shadow: var(--shadow-menu); }
.block-flow__ctx.is-on { display: flex; }
.block-flow__ctx.is-below { transform: translate(-50%, 0); }
.block-flow__canvas.is-dragging .block-flow__ctx.is-on { visibility: hidden; } /* still while moving */
.block-flow__ctx-sep { width: var(--border); align-self: stretch; background: var(--line-soft); }
/* the 7 workspace accents as one-click dots (+ the no-colour dot) */
.block-flow__dot { width: 16px; height: 16px; border-radius: 50%; padding: 0; border: var(--border) solid var(--line); background: var(--flow-c, var(--surface)); cursor: pointer; }
.block-flow__dot--none { background: linear-gradient(135deg, transparent 44%, var(--line) 44%, var(--line) 56%, transparent 56%); }
.block-flow__dot[aria-pressed="true"] { outline: 2px solid var(--ink); outline-offset: 1px; }
.block-flow__viewchips { position: absolute; right: 10px; bottom: 10px; display: none; gap: var(--space-1); }
.block-flow:not(.is-editing):hover .block-flow__viewchips { display: flex; }
.block-flow__hint { display: none; padding: var(--space-1) var(--space-2); color: var(--muted); }
.block-flow.is-editing .block-flow__hint { display: block; }
/* seamless in-place label editing: same typography as the rendered text, no box */
.block-flow__labeledit { position: absolute; display: none; z-index: 3; border: 0; outline: none; background: var(--surface); padding: 0; margin: 0; font-family: var(--font-ui); text-align: center; color: var(--ink); resize: none; overflow: hidden; white-space: pre; box-sizing: border-box; }
/* svg parts */
.block-flow__shape { fill: var(--surface); stroke: var(--ink); stroke-width: 1; }
/* coloured elements: accent border, soft tint fill, ink-mixed accent label (AA on the tint) */
.block-flow__node.is-colored .block-flow__shape { stroke: var(--flow-c); fill: color-mix(in srgb, var(--flow-c) 10%, var(--surface)); }
.block-flow__node.is-colored .block-flow__node-label { fill: color-mix(in srgb, var(--flow-c) 72%, var(--ink)); }
.block-flow__node { cursor: grab; }
.block-flow--read .block-flow__node { cursor: default; }
.block-flow__node.is-sel .block-flow__shape { stroke-width: 2; }
.block-flow__node.is-target .block-flow__shape { stroke-width: 2; stroke-dasharray: 3 3; }
.block-flow__node-label, .block-flow__edge-label { font-family: var(--font-ui); font-size: var(--text-md); fill: var(--ink); user-select: none; } /* one text style everywhere */
.block-flow__edge-line { fill: none; stroke: var(--ink); stroke-width: 1; }
.block-flow__edge.is-dashed .block-flow__edge-line { stroke-dasharray: 5 4; }
.block-flow__edge.is-sel .block-flow__edge-line { stroke-width: 2; }
.block-flow__edge-hit { fill: none; stroke: transparent; stroke-width: 12; cursor: pointer; }
.block-flow--read .block-flow__edge-hit { cursor: default; }
.block-flow__halo { fill: var(--canvas); }
.block-flow__arrowhead { fill: var(--ink); }
.block-flow__port { fill: var(--surface); stroke: var(--ink); stroke-width: 1; opacity: 0; cursor: crosshair; }
.block-flow.is-editing .block-flow__node:hover .block-flow__port,
.block-flow.is-editing .block-flow__node.is-target .block-flow__port { opacity: 1; }
.block-flow__rubber { stroke: var(--ink); stroke-dasharray: 4 4; fill: none; }
/* endpoint handles of the selected arrow — drag one onto a node side to re-anchor.
   The grab circle is invisible and generous; the visible dot ignores pointers. */
.block-flow__endpoint { fill: transparent; stroke: none; cursor: grab; }
.block-flow__endpoint:active { cursor: grabbing; }
.block-flow__endpoint-dot { fill: var(--surface); stroke: var(--ink); stroke-width: 1.5; pointer-events: none; }
/* full-screen expand: the block body reparents into a body-level overlay */
.block-flow__overlay { position: fixed; inset: 0; z-index: 220; display: flex; padding: var(--space-4); }
.block-flow__scrim { position: absolute; inset: 0; background: var(--overlay-modal); }
.block-flow.is-expanded { position: relative; flex: 1; display: flex; flex-direction: column; min-width: 0; background: var(--surface); border: var(--border) solid var(--ink); z-index: 1; }
.block-flow.is-expanded .block-flow__canvas { flex: 1; min-height: 0; }
.block-flow.is-expanded .block-flow__svg { height: 100%; }

/* Crawlable boot content (index.html) — honest mini-landing during the sub-second
   boot; app.js replaces it. Never display:none (that would be cloaking). */
.boot-seo { max-width: 640px; margin: 24px auto 60px; padding: 0 20px; color: var(--ink-soft, #444); }
.boot-seo h1 { font-size: 24px; letter-spacing: -0.02em; color: var(--ink, #111); }
.boot-seo h2 { font-size: 15px; }
.boot-seo li { margin: 4px 0; line-height: 1.5; }
.boot-seo a { color: inherit; }
