/* Fusee. The shared tokens (--steel, --ballast, --signal-*, --page, ...) and
   fonts come from design-system.css, loaded first; only what is Fusee's own
   lives here. */
:root {
  --fusee-ember: #B4552D;

  /* Issue-list row geometry. The row's checkbox cell and the severity glyph
     each centre a box --issue-glyph-box tall, inset from the row's top edge by
     --issue-row-pad-y, so the checkbox and the icon share one centre line
     whatever the glyph's font metrics turn out to be. Change these together. */
  --issue-row-pad-y: 0.75rem;
  --issue-row-pad-x: 0.75rem;
  --issue-glyph-box: 1.5rem;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  font-family: var(--font-sans);
  background: var(--page);
  color: var(--steel);
  line-height: 1.5;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
.page-main { flex: 1 0 auto; padding-bottom: 2.5rem; }

/* Site footer — keeps the last row of content off the browser edge. */
.site-footer {
  flex-shrink: 0;
  border-top: 1px solid var(--rule);
  background: var(--page);
  padding: 1rem 0 1.25rem;
  margin-top: 2rem;
}
.site-footer-inner {
  display: flex;
  align-items: center;
  gap: 1rem;
  font-size: 0.72rem;
  color: var(--ballast);
  font-family: var(--font-mono);
  letter-spacing: 0.2px;
}
.site-footer-brand {
  color: var(--steel);
  font-weight: 600;
}
.site-footer-mode {
  text-transform: uppercase;
  font-size: 0.62rem;
  letter-spacing: 0.6px;
  background: var(--rule);
  color: var(--ballast);
  padding: 0.1rem 0.45rem;
  border-radius: 3px;
}
.site-footer-version {
  font-size: 0.65rem;
  color: var(--ballast);
  opacity: 0.7;
}
.site-footer-spacer { flex: 1; }
.site-footer-link {
  color: var(--ballast);
  text-decoration: none;
}
.site-footer-link:hover {
  color: var(--steel);
  text-decoration: underline;
}

a { color: var(--steel); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Layout — container widened to 1440px so wide displays (1440/1920+)
   stop wasting half the viewport on side rails. Reading-width caps
   on prose-heavy elements (.settings-form, .dsn-text, .form-hint, etc.)
   keep text columns from sprawling, so this only widens the chrome
   and grid surfaces that benefit from the extra room. */
.container { max-width: 1440px; margin: 0 auto; padding: 0 1.5rem; }
@media (min-width: 1024px) {
  .container { padding: 0 2rem; }
}
@media (min-width: 1440px) {
  .container { padding: 0 3rem; }
}

/* Base card (fl-zim). Dashboard templates use `.card` as a default
   surface around tables, stat rows, and form blocks, but the
   stylesheet only defined variants (.project-card, .db-card,
   .section-card). Bare `<div class="card">` landed flat on the
   background, which read as "overflow" compared to the styled
   landing-page cards. Variants still add their own background /
   shadow — this rule only kicks in when no variant is present, so
   nothing that was already styled changes. */
.card {
  background: white;
  border-radius: var(--radius);
  box-shadow: 0 1px 3px rgba(0,0,0,0.06);
  overflow-x: auto; /* horizontal scroll on wide tables inside cards */
}

.nav {
  background: var(--steel);
  color: var(--surface);
  padding: 0.65rem 0;
  position: sticky;
  top: 0;
  z-index: 100;
}
.nav-inner {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  position: relative;
}
.nav-brand {
  font-family: var(--font-mono);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--surface);
  letter-spacing: -0.5px;
  white-space: nowrap;
}
.nav-brand:hover { text-decoration: none; }
.nav-links {
  display: flex;
  gap: 1.25rem;
  align-items: center;
  flex: 1;
}
.nav-links a {
  color: var(--surface);
  opacity: 0.75;
  font-size: 0.875rem;
  padding: 0.25rem 0;
}
.nav-links a:hover {
  opacity: 1;
  text-decoration: none;
}
.nav-right {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-left: auto;
}

/* Cloud link — "faultline.live" pill with a pulsing dot so the
   affordance reads as "go to the hosted instance" rather than
   just another nav entry. Only rendered in local mode. */
.nav-live {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.65rem;
  border: 1px solid rgba(250, 248, 245, 0.18);
  border-radius: 999px;
  color: var(--surface);
  font-size: 0.78rem;
  font-family: var(--font-mono);
  letter-spacing: 0.02em;
  transition: border-color 0.15s, background 0.15s;
}
.nav-live:hover {
  border-color: rgba(250, 248, 245, 0.45);
  background: rgba(250, 248, 245, 0.06);
  text-decoration: none;
}
.nav-live-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--signal-green);
  box-shadow: 0 0 0 0 rgba(5, 150, 105, 0.55);
  animation: navLivePulse 2.4s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.nav-live-arrow {
  opacity: 0.55;
  font-size: 0.72rem;
}
@keyframes navLivePulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(5, 150, 105, 0.55); }
  50%      { box-shadow: 0 0 0 5px rgba(5, 150, 105, 0);   }
}

/* Account dropdown — <details>/<summary> so the whole thing works
   without JS. Clicking outside closes via JS that toggles the
   [open] attribute (see script at the bottom of the file). */
.nav-account {
  position: relative;
}
.nav-account > summary {
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0.4rem 0.25rem 0.25rem;
  border-radius: 999px;
  cursor: pointer;
  color: var(--surface);
  font-size: 0.85rem;
  border: 1px solid transparent;
}
.nav-account > summary:hover {
  border-color: rgba(250, 248, 245, 0.2);
}
.nav-account > summary::-webkit-details-marker { display: none; }
.nav-account[open] > summary {
  background: rgba(250, 248, 245, 0.08);
  border-color: rgba(250, 248, 245, 0.25);
}
.nav-account-avatar {
  width: 28px; height: 28px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--fusee-ember), var(--fusee-ember));
  color: var(--sleeper);
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.78rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.nav-account-name {
  max-width: 14ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.nav-account-caret {
  font-size: 0.6rem;
  opacity: 0.65;
  transition: transform 0.15s;
}
.nav-account[open] .nav-account-caret { transform: rotate(180deg); }

.nav-account-menu {
  position: absolute;
  top: calc(100% + 0.45rem);
  right: 0;
  min-width: 220px;
  background: #fff;
  color: var(--steel);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  box-shadow: 0 12px 32px -8px rgba(15, 23, 42, 0.18), 0 2px 6px rgba(15, 23, 42, 0.06);
  padding: 0.35rem 0;
  z-index: 110;
}
.nav-account-header {
  padding: 0.65rem 0.9rem 0.8rem;
  border-bottom: 1px solid var(--coal);
  margin-bottom: 0.25rem;
}
.nav-account-header-name {
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--steel);
}
.nav-account-header-email {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ballast);
  margin-top: 0.15rem;
  word-break: break-all;
}
.nav-account-header-role {
  display: inline-block;
  margin-top: 0.4rem;
  font-family: var(--font-mono);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ballast);
  background: var(--coal);
  border: 1px solid var(--rule);
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
}
.nav-account-section {
  padding: 0.55rem 0.9rem 0.2rem;
  font-family: var(--font-mono);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ballast);
}
.nav-account-item {
  display: block;
  padding: 0.45rem 0.9rem;
  font-size: 0.86rem;
  color: var(--steel);
}
.nav-account-item:hover {
  background: var(--coal);
  text-decoration: none;
  color: var(--fusee-ember);
}
.nav-account-divider {
  height: 1px;
  background: var(--coal);
  margin: 0.3rem 0;
}
.nav-account-logout {
  color: var(--signal-red);
}
.nav-account-logout:hover {
  background: #fcf0f0;
  color: var(--signal-red);
}

/* Tools dropdown — left-side <details> menu in .nav-links, mirroring
   .nav-account. The trigger reads like a nav link (not a pill); the
   popover reuses .nav-account-menu's chrome but anchors left instead
   of right. Menu body reuses .nav-account-item/-divider/-section. */
.nav-tools {
  position: relative;
}
.nav-tools > summary {
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  cursor: pointer;
  color: var(--surface);
  opacity: 0.75;
  font-size: 0.875rem;
  padding: 0.25rem 0;
}
.nav-tools > summary:hover { opacity: 1; }
.nav-tools > summary::-webkit-details-marker { display: none; }
.nav-tools[open] > summary { opacity: 1; }
.nav-tools-caret {
  font-size: 0.6rem;
  opacity: 0.65;
  transition: transform 0.15s;
}
.nav-tools[open] .nav-tools-caret { transform: rotate(180deg); }
.nav-tools-menu {
  position: absolute;
  top: calc(100% + 0.45rem);
  left: 0;
  min-width: 220px;
  background: #fff;
  color: var(--steel);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  box-shadow: 0 12px 32px -8px rgba(15, 23, 42, 0.18), 0 2px 6px rgba(15, 23, 42, 0.06);
  padding: 0.35rem 0;
  z-index: 110;
}
/* Items in the Tools menu lay out as a row so the ↗ external marker
   can push to the trailing edge. */
.nav-tools-menu .nav-account-item {
  display: flex;
  align-items: center;
  /* The Tools menu lives inside .nav-links, whose `a` rule paints links white
     (var(--surface)) at 0.75 opacity with `padding: 0.25rem 0` for the dark
     header bar — invisible and cramped on this white dropdown. Restore the
     menu's own dark, full-opacity sans text + padding here; this selector's
     (0,2,0) specificity beats `.nav-links a` (0,1,1). */
  color: var(--steel);
  opacity: 1;
  font-family: var(--font-sans);
  font-size: 0.86rem;
  padding: 0.45rem 0.9rem;
}
.nav-tools-menu .nav-account-item:hover {
  /* Match the account menu's hover; (0,3,0) beats .nav-links a:hover. */
  background: var(--coal);
  color: var(--fusee-ember);
  opacity: 1;
}
.nav-tools-ext {
  margin-left: auto;
  padding-left: 0.75rem;
  opacity: 0.5;
  font-size: 0.72rem;
}

/* Hamburger — hidden on desktop; on mobile it replaces .nav-links
   with a dropdown panel. Checkbox hack keeps the toggle CSS-only. */
.nav-toggle { display: none; }
.nav-burger { display: none; }

@media (max-width: 768px) {
  .nav-inner {
    flex-wrap: wrap;
    gap: 0.75rem;
  }
  .nav-burger {
    display: inline-flex;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    width: 36px; height: 36px;
    padding: 7px 8px;
    cursor: pointer;
    border-radius: var(--radius);
    order: 3;
    margin-left: auto;
  }
  .nav-burger span {
    display: block;
    height: 2px;
    background: var(--page);
    border-radius: 2px;
    transition: transform 0.2s, opacity 0.2s;
    transform-origin: 50% 50%;
  }
  .nav-burger:hover { background: rgba(250, 248, 245, 0.08); }
  .nav-toggle:checked ~ .nav-burger span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
  .nav-toggle:checked ~ .nav-burger span:nth-child(2) { opacity: 0; }
  .nav-toggle:checked ~ .nav-burger span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

  .nav-right {
    order: 4;
    margin-left: 0;
  }
  .nav-live-label { display: none; }
  .nav-live { padding: 0.3rem 0.45rem; }

  .nav-links {
    order: 5;
    flex-basis: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    display: none;
    padding: 0.25rem 0 0.5rem;
    border-top: 1px solid rgba(250, 248, 245, 0.12);
    margin-top: 0.5rem;
  }
  .nav-toggle:checked ~ .nav-links { display: flex; }
  .nav-links a {
    padding: 0.6rem 0;
    opacity: 0.85;
    font-size: 0.95rem;
    border-bottom: 1px solid rgba(250, 248, 245, 0.06);
  }
  .nav-links a:last-child { border-bottom: none; }

  .nav-account-name { display: none; }
  .nav-account-menu {
    right: auto;
    left: 0;
    min-width: 240px;
  }

  /* Tools dropdown in the mobile drawer: the trigger reads like the
     other stacked links, and the menu expands inline (static) as a
     white card rather than floating over the drawer. */
  .nav-tools { width: 100%; }
  .nav-tools > summary {
    padding: 0.6rem 0;
    opacity: 0.85;
    font-size: 0.95rem;
    border-bottom: 1px solid rgba(250, 248, 245, 0.06);
  }
  .nav-tools-menu {
    position: static;
    min-width: 0;
    box-shadow: none;
    margin: 0.4rem 0 0.6rem;
  }
}

/* Filters */
.filters {
  display: flex; gap: 0.5rem; padding: 1rem 0;
  flex-wrap: wrap; align-items: center;
}
.filter-tab {
  padding: 0.375rem 0.75rem;
  border-radius: var(--radius);
  font-size: 0.8rem;
  background: transparent;
  border: 1px solid transparent;
  color: var(--ballast);
  cursor: pointer;
}
.filter-tab:hover { background: var(--coal); }
.filter-tab.active { background: var(--steel); color: var(--surface); }
.filter-tab.filter-sm { font-size: 0.7rem; padding: 0.25rem 0.5rem; }
.filter-separator { width: 1px; height: 1rem; background: #e2e0dd; margin: 0 0.25rem; }
.sort-label { font-size: 0.7rem; color: var(--ballast); }
.project-platform-tag {
  font-size: 0.7rem;
  font-weight: 400;
  color: var(--ballast);
  margin-left: 0.5rem;
}

/* Issue cards */
.issue-list { display: flex; flex-direction: column; gap: 1px; background: var(--rule); border-radius: var(--radius); overflow: hidden; }

.issue-card-row {
  display: grid;
  /* checkbox cell | issue card | per-row triage actions. With only two tracks
     the cloud row's trailing triage forms wrapped into the implicit second row
     under track 1, which sized that track to the width of the buttons and left
     a wide empty gap between the checkbox and the severity icon. */
  grid-template-columns: auto minmax(0, 1fr) auto;
  background: white;
  align-items: start;
}
.issue-card-row:hover { background: var(--page); }
/* Placed explicitly so a row that omits the checkbox cell or the actions (the
   cloud shadow list renders the card alone) still puts the card in the
   flexible middle track instead of sliding into track 1. */
.issue-card-row > .bulk-checkbox { grid-column: 1; }
.issue-card-row > .issue-card { grid-column: 2; }
.issue-card-row > .cloud-issue-row-actions { grid-column: 3; }

.bulk-checkbox {
  display: flex;
  align-items: center;
  justify-content: center;
  /* Fixed width because a resolved row renders this label empty (resolved
     issues are not bulk-selectable) — without it the severity column shifts
     left on those rows. */
  width: calc(var(--issue-row-pad-x) + var(--issue-glyph-box));
  /* Border-box, so the content box this centres the checkbox in is exactly
     --issue-glyph-box tall: the same box the severity glyph centres in, at the
     same offset from the row's top edge. */
  min-height: calc(var(--issue-row-pad-y) * 2 + var(--issue-glyph-box));
  padding: var(--issue-row-pad-y) 0 var(--issue-row-pad-y) var(--issue-row-pad-x);
  cursor: pointer;
}
.bulk-checkbox input[type="checkbox"] {
  width: 1rem;
  height: 1rem;
  cursor: pointer;
  accent-color: var(--stratum, #5a544c);
}

.issue-card {
  background: transparent;
  padding: var(--issue-row-pad-y) 1rem;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 0 0.75rem;
  align-items: start;
  cursor: pointer;
  transition: background 0.1s;
}
.issue-card:hover { background: var(--page); }
/* Behind a checkbox cell the card drops its left padding, so the checkbox and
   the severity icon are adjacent instead of separated by an empty strip. The
   cell's own trailing space and the glyph box's centring give the pair the gap
   it needs; a row with no checkbox keeps the padding. */
.bulk-checkbox + .issue-card { padding-left: 0; }

.bulk-action-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 1rem;
  background: #3d3831;
  color: var(--coal);
  border-radius: var(--radius) var(--radius) 0 0;
  font-size: 0.8rem;
  position: sticky;
  top: 0;
  z-index: 10;
}
.bulk-select-info {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.bulk-select-info input[type="checkbox"] {
  accent-color: var(--coal);
}
.bulk-actions {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}
.bulk-actions .btn-sm {
  padding: 0.25rem 0.6rem;
  font-size: 0.7rem;
  border: 1px solid rgba(255,255,255,0.2);
  background: transparent;
  color: var(--coal);
  cursor: pointer;
  border-radius: 3px;
}
.bulk-actions .btn-sm:hover {
  background: rgba(255,255,255,0.1);
}
.bulk-actions .btn-resolve { border-color: #7caa6e; color: #a5d698; }
.bulk-actions .btn-resolve:hover { background: rgba(124,170,110,0.2); }
.bulk-actions .btn-ignore { border-color: #b8a67e; color: #d4c59d; }
.bulk-actions .btn-ignore:hover { background: rgba(184,166,126,0.2); }
.bulk-actions .btn-unresolve { border-color: #c4847a; color: #e0a79f; }
.bulk-actions .btn-unresolve:hover { background: rgba(196,132,122,0.2); }
.bulk-actions .btn-snooze { border-color: #8b8bf0; color: #a5a5f7; }
.bulk-actions .btn-snooze:hover { background: rgba(99,102,241,0.2); }
.bulk-actions .btn-unsnooze { border-color: #8b8bf0; color: #a5a5f7; }
.bulk-actions .btn-unsnooze:hover { background: rgba(99,102,241,0.2); }
.bulk-assign-select {
  padding: 0.2rem 0.4rem;
  font-size: 0.7rem;
  background: transparent;
  border: 1px solid rgba(255,255,255,0.2);
  color: var(--coal);
  border-radius: 3px;
  cursor: pointer;
}
.bulk-assign-select option { background: #3d3831; color: var(--coal); }

.issue-severity {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--issue-glyph-box);
  height: var(--issue-glyph-box);
  font-size: 1.1rem;
  /* line-height is pinned to 1 and the glyph centred by flexbox instead: a
     line box plus .ui-icon's vertical-align put the icon's centre a
     font-metric-dependent distance down, which is what knocked it off the
     checkbox's centre line. */
  line-height: 1;
}

.issue-title {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  font-weight: 600;
  line-height: 1.4;
  word-break: break-word;
}
.issue-culprit {
  font-size: 0.75rem;
  color: var(--ballast);
  font-family: var(--font-mono);
}
.issue-meta {
  font-size: 0.7rem;
  color: var(--ballast);
  margin-top: 0.25rem;
}

.issue-stats {
  text-align: right;
  white-space: nowrap;
}
.issue-count {
  font-size: 0.8rem;
  font-weight: 600;
}
/* Lifecycle stage indicators on issue list */
.issue-lifecycle {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.25rem;
  font-size: 0.7rem;
}
.lifecycle-stage {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  padding: 0.1rem 0.4rem;
  border-radius: 3px;
  font-weight: 500;
  white-space: nowrap;
}
.stage-detected { background: #f0e8df; color: #8a7a6a; }
.stage-picked-up { background: #e6f0ff; color: #3570b0; }
.stage-dispatched { background: #e0f5ec; color: #1a7a4a; }
.stage-escalated { background: #ffeedd; color: #b06020; }
.stage-resolved { background: #e0f5e4; color: #1a6a30; }
.stage-regressed { background: #fde8e8; color: #a03030; }
.stage-snoozed { background: #ededff; color: #6366f1; }
.lifecycle-actor {
  color: var(--ballast);
  font-family: var(--font-mono);
  font-size: 0.65rem;
}
.lifecycle-when {
  color: var(--ballast);
  font-size: 0.65rem;
}

/* Severity colors */
.severity-warning { color: var(--signal-amber); }
.severity-error { color: var(--signal-red); }
.severity-fatal { color: var(--fusee-ember); }
.severity-dormant { color: var(--signal-green); }
/* Resolution overlays — when an issue is fixed or has regressed,
   the status overrides the level-based tint so the row reads as
   "closed out" or "back from the dead" at a glance. */
.severity-fixed {
  /* Resolved recent-faults: tint the severity glyph green. The "✓" overlay
     that used to sit after it was a second icon next to the "FIXED" pill —
     dropped (operator request: one icon per resolved fault). */
  color: var(--signal-green);
}
.severity-regressed {
  color: var(--signal-red);
  filter: drop-shadow(0 0 4px rgba(220, 38, 38, 0.45));
}

/* Small state pill next to the meta text on a recent-fault row.
   "fixed" picks up the dormant green; "regressed" the rupture
   red — mirrors the severity overlay so the two cues reinforce. */
.station-recent-state {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.05rem 0.4rem;
  border-radius: 999px;
  margin-right: 0.4rem;
  border: 1px solid transparent;
}
.station-recent-state-fixed {
  color: var(--signal-green);
  background: #e7f6ee;
  border-color: #c9e6d7;
}
.station-recent-state-regressed {
  color: var(--signal-red);
  background: #fef0f0;
  border-color: #f2c7c7;
}

/* Status badges */
.badge {
  display: inline-block;
  padding: 0.125rem 0.5rem;
  border-radius: 999px;
  font-size: 0.65rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.3px;
}
.badge-active { background: #fef2f2; color: var(--signal-red); }
.badge-fixing { background: #fef3c7; color: #92400e; }
.badge-resolved { background: #ecfdf5; color: var(--signal-green); }
.badge-regressed { background: #fff7ed; color: var(--fusee-ember); }
.badge-snoozed { background: #f0f0ff; color: #6366f1; }
.badge-platform { background: #f0f4ff; color: #3b5998; }
.badge-assignee { background: #f0fdf4; color: #166534; }

/* Assignment widget */
.assignment-widget { padding: 0.75rem 0; border-bottom: 1px solid var(--rule); display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }
.assignment-current { color: var(--text-secondary); font-size: 0.9rem; }
.assign-select { padding: 0.25rem 0.5rem; border: 1px solid #d1d5db; border-radius: 4px; font-size: 0.85rem; background: #fff; }

/* Detail page */
.detail-header { padding: 1.5rem 0 1rem; border-bottom: 1px solid var(--rule); }
.detail-title {
  font-family: var(--font-mono);
  font-size: 1.2rem;
  font-weight: 700;
  margin-bottom: 0.5rem;
}
.detail-meta { display: flex; gap: 1.5rem; font-size: 0.8rem; color: var(--ballast); flex-wrap: wrap; }

.detail-body { padding: 1.5rem 0; }
.detail-section { margin-bottom: 2rem; }
.detail-section h3 {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--ballast);
  margin-bottom: 0.75rem;
}

/* Stack trace */
.stack-frame {
  background: var(--sleeper);
  color: #e2e8f0;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  border-radius: var(--radius);
  overflow: hidden;
  margin-bottom: 0.5rem;
}
.frame-header {
  padding: 0.5rem 0.75rem;
  background: rgba(255,255,255,0.05);
  color: var(--fusee-ember);
  font-size: 0.72rem;
}
.frame-code {
  padding: 0.5rem 0;
}
.frame-line {
  padding: 0 0.75rem;
  line-height: 1.6;
  white-space: pre;
}
.frame-line.active {
  background: rgba(220, 38, 38, 0.15);
  border-left: 3px solid var(--signal-red);
}
.line-num {
  display: inline-block;
  width: 3rem;
  color: var(--ballast);
  text-align: right;
  margin-right: 1rem;
  user-select: none;
}

/* Raw JSON */
.raw-json {
  background: var(--sleeper);
  color: #e2e8f0;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  padding: 1rem;
  border-radius: var(--radius);
  overflow-x: auto;
  max-height: 400px;
  overflow-y: auto;
  white-space: pre-wrap;
  word-break: break-all;
}

/* Events table (still used by containers / databases / service / other views) */
.events-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8rem;
}
.events-table th {
  text-align: left;
  padding: 0.5rem;
  border-bottom: 2px solid var(--rule);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  color: var(--ballast);
}
.events-table td {
  padding: 0.5rem;
  border-bottom: 1px solid #f0edea;
  font-family: var(--font-mono);
  font-size: 0.78rem;
}
.events-table tr:hover { background: var(--page); }

/* Live-refresh indicator dot — signals that a section is self-updating
   via HTMX polling. Subtle pulse keeps it from being a distraction. */
.gt-section-live {
  display: inline-block;
  vertical-align: 0.15em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  margin-left: 0.45rem;
  background: var(--signal-green);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--signal-green) 40%, transparent);
  animation: gt-section-live-pulse 2.4s ease-in-out infinite;
}
@keyframes gt-section-live-pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--signal-green) 40%, transparent); opacity: 0.85; }
  50%      { box-shadow: 0 0 0 4px color-mix(in srgb, var(--signal-green) 0%, transparent);  opacity: 1;    }
}
@media (prefers-reduced-motion: reduce) {
  .gt-section-live { animation: none; }
}

/* Section header count pill */
.section-count {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 500;
  color: var(--ballast);
  background: var(--rule);
  border-radius: 999px;
  padding: 0.1rem 0.55rem;
  margin-left: 0.4rem;
  vertical-align: 0.15em;
  letter-spacing: 0.2px;
}

/* ---------- Events list (redesigned from table) ---------- */
.events-list {
  list-style: none;
  padding: 0;
  margin: 0;
  border-top: 1px solid #ece7e1;
}
.events-row {
  border-bottom: 1px solid #ece7e1;
}
.events-link {
  display: grid;
  grid-template-columns: 70px minmax(0, 1fr) auto auto 80px;
  gap: 0.75rem;
  align-items: center;
  padding: 0.55rem 0.5rem;
  font-size: 0.78rem;
  color: var(--steel);
  transition: background 0.1s ease;
}
.events-link:hover {
  background: var(--page);
  text-decoration: none;
}
.events-level {
  justify-self: start;
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  padding: 0.15rem 0.5rem;
  border-radius: 3px;
  background: var(--rule);
  color: var(--ballast);
  border: 1px solid transparent;
}
.events-level--debug   { background: #eef2f7; color: var(--ballast); }
.events-level--info    { background: #e7efe9; color: #1f6b4b; }
.events-level--warning { background: #fef3c7; color: #92400e; }
.events-level--error   { background: #fee2e2; color: var(--signal-red); }
.events-level--fatal   { background: var(--sleeper); color: #fff; }
.events-message {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--sleeper);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.events-badges {
  display: inline-flex;
  gap: 0.35rem;
  align-items: center;
  flex-shrink: 0;
}
.events-platform {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  color: var(--ballast);
  text-transform: lowercase;
}
.events-time {
  font-size: 0.72rem;
  color: var(--ballast);
  white-space: nowrap;
  justify-self: end;
  font-variant-numeric: tabular-nums;
}
.events-id {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  color: var(--ballast);
  justify-self: end;
  background: #f5f1eb;
  padding: 0.1rem 0.35rem;
  border-radius: 3px;
}
.events-note {
  font-size: 0.7rem;
  font-weight: 400;
  color: var(--ballast);
  margin-left: 0.35rem;
}
@media (max-width: 720px) {
  .events-link {
    grid-template-columns: 55px minmax(0, 1fr) auto;
    grid-template-rows: auto auto;
    row-gap: 0.2rem;
  }
  .events-badges { grid-column: 2 / 4; }
  .events-time   { grid-column: 3; grid-row: 1; }
  .events-id     { display: none; }
}

/* ---------- Lifecycle timeline (redesigned) ---------- */
.lifecycle-timeline {
  list-style: none;
  padding: 0;
  margin: 0;
  position: relative;
}
.lifecycle-timeline::before {
  content: '';
  position: absolute;
  left: 11px;
  top: 0.85rem;
  bottom: 0.85rem;
  width: 2px;
  background: linear-gradient(to bottom, var(--rule) 0%, var(--rule) 100%);
  border-radius: 1px;
}
.lifecycle-entry {
  display: grid;
  grid-template-columns: 24px 1fr;
  gap: 0.75rem;
  padding: 0.55rem 0;
  position: relative;
}
.lifecycle-entry + .lifecycle-entry { border-top: 1px solid #f0edea; }
.lifecycle-node {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--page);
  border: 2px solid #d6cfc6;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1;
  margin-top: 0.15rem;
  box-shadow: 0 0 0 3px var(--page);
  transition: border-color 0.15s ease;
}
.lifecycle-icon {
  font-size: 0.75rem;
  line-height: 1;
}
/* fa-rl6: larger timeline icons (operator request) — ~2x the base so the
   lifecycle glyphs read at a glance; the node circle grows to fit. These
   override the .lifecycle-node / .lifecycle-icon rules above, and the grid
   column + connector line are re-offset so the bigger node doesn't cover the
   entry content (was sized for the 24px node). */
.lifecycle-node { width: 42px; height: 42px; }
.lifecycle-entry { grid-template-columns: 42px 1fr; }
.lifecycle-timeline::before { left: 20px; }
.lifecycle-icon { font-size: 1.5rem; }
.lifecycle-icon .ui-icon { vertical-align: -0.2em; }
/* Color the timeline glyphs by event type — red for alerts, yellow for
   notify/slow-burn, orange for escalation, green for CI/commit; the resolved
   node has a solid green fill so its check goes white. */
.lifecycle-node--regression .ui-icon,
.lifecycle-node--fix_failed .ui-icon     { color: var(--signal-red); }
.lifecycle-node--slow_burn_bead .ui-icon,
.lifecycle-node--notified .ui-icon       { color: var(--signal-amber); }
.lifecycle-node--escalation .ui-icon     { color: var(--fusee-ember); }
.lifecycle-node--commit_detected .ui-icon,
.lifecycle-node--ci_green .ui-icon       { color: var(--signal-green); }
.lifecycle-node--resolved .ui-icon       { color: var(--surface); }
/* Event-recorded nodes use the rec-button glyph — red, like a record button. */
.lifecycle-node--event .ui-icon          { color: var(--signal-red); }
.lifecycle-node--detection       { border-color: var(--ballast); }
.lifecycle-node--bead_filed      { border-color: var(--fusee-ember); background: #fdf6ec; }
.lifecycle-node--slow_burn_bead  { border-color: var(--signal-amber); background: #fef3c7; }
.lifecycle-node--dispatched      { border-color: var(--fusee-ember); }
.lifecycle-node--notified        { border-color: var(--fusee-ember); }
.lifecycle-node--assigned        { border-color: var(--fusee-ember); }
.lifecycle-node--commit_detected { border-color: var(--signal-green); background: #ecfdf4; }
.lifecycle-node--ci_green        { border-color: var(--signal-green); background: #ecfdf4; }
.lifecycle-node--resolved        { border-color: var(--signal-green); background: var(--signal-green); }
.lifecycle-node--resolved .lifecycle-icon { filter: grayscale(0); }
.lifecycle-node--regression      { border-color: var(--signal-red); background: #fee2e2; }
.lifecycle-node--fix_failed      { border-color: var(--signal-red); background: #fee2e2; }
.lifecycle-node--escalation      { border-color: var(--fusee-ember); background: #ffedd5; }
.lifecycle-node--snoozed         { border-color: var(--ballast); background: #eef2f7; }
.lifecycle-node--unsnoozed       { border-color: var(--ballast); background: var(--page); }
.lifecycle-node--ignored         { border-color: var(--ballast); }

.lifecycle-content { min-width: 0; }
.lifecycle-headline {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.4rem 0.55rem;
}
.lifecycle-label {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--sleeper);
  letter-spacing: -0.1px;
}
.lifecycle-chip {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  font-weight: 500;
  padding: 0.1rem 0.45rem;
  border-radius: 3px;
  letter-spacing: 0.2px;
  background: var(--rule);
  color: var(--ballast);
  border: 1px solid #e0dbd3;
  text-transform: lowercase;
  line-height: 1.4;
}
.lifecycle-chip--trigger  { background: #f1f5f9; color: var(--steel); }
.lifecycle-chip--quiet    { background: #ecfdf4; color: #1f6b4b; border-color: #c8eed7; }
.lifecycle-chip--verified { background: var(--signal-green); color: #fff; border-color: transparent; }
.lifecycle-time {
  margin-left: auto;
  font-size: 0.7rem;
  color: var(--ballast);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.lifecycle-reason {
  margin-top: 0.2rem;
  font-size: 0.78rem;
  color: var(--steel);
  line-height: 1.45;
}
.lifecycle-reason--solution {
  color: #1f6b4b;
  font-style: italic;
}
.lifecycle-meta {
  margin-top: 0.25rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.75rem;
  font-size: 0.7rem;
  color: var(--ballast);
}
.lifecycle-meta-item { white-space: nowrap; }
.lifecycle-meta-item code,
.lifecycle-reason code {
  font-family: var(--font-mono);
  background: #f5f1eb;
  padding: 0.05rem 0.35rem;
  border-radius: 3px;
  font-size: 0.68rem;
  color: var(--sleeper);
}
.lifecycle-meta .lifecycle-sha {
  background: #ecfdf4;
  color: #1f6b4b;
  border: 1px solid #c8eed7;
}

/* Page header */
.page-header { padding: 1.5rem 0 1rem; }
.page-header h2 { font-size: 1.2rem; font-weight: 700; }
.page-subtitle { font-size: 0.85rem; color: var(--ballast); margin-top: 0.25rem; }

/* Project grid: a FIXED 3 cards per row at desktop, 2 at tablet, 1 at
   mobile. Fixed columns (not auto-fill/auto-fit) so each card is always
   one-third width and the grid stays a stable 3 per line regardless of
   project count OR card content: a 1–2 project tenant no longer pins
   narrow cards to the left with phantom tracks, and an issue-free
   dashboard (cards carrying no issue rows) no longer reflows to one card
   per row. Three is the right density — room for the title, status pill,
   stat row, and tags without reading as a giant directory. Shared by
   local (.project-grid) and faultline.live (the cloud index reuses this
   same class), so both keep parity. */
.project-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.25rem;
  padding-bottom: 2rem;
}
@media (max-width: 1080px) {
  .project-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 720px) {
  .project-grid { grid-template-columns: minmax(0, 1fr); }
}
.project-card {
  background: white;
  border-radius: var(--radius);
  box-shadow: 0 1px 3px rgba(0,0,0,0.08);
  transition: box-shadow 0.15s, transform 0.15s;
  display: block;
  overflow: hidden;
}
.project-card:hover {
  box-shadow: 0 4px 12px rgba(0,0,0,0.12);
  transform: translateY(-2px);
  text-decoration: none;
}
.card-status-bar {
  height: 4px;
  width: 100%;
}
.bar-green { background: var(--signal-green); }
.bar-yellow { background: var(--signal-amber); }
.bar-stale { background: var(--signal-amber); opacity: 0.6; }
.bar-red { background: var(--signal-red); animation: pulse-bar 2s infinite; }
.bar-unmonitored { background: var(--ballast); }
@keyframes pulse-bar {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.6; }
}
.card-body { padding: 1rem 1.25rem; }
.card-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.25rem;
}
.project-name {
  font-size: 1rem;
  font-weight: 700;
}
.project-desc {
  font-size: 0.75rem;
  color: var(--ballast);
  margin-bottom: 0.625rem;
}
.project-running {
  font-size: 0.65rem;
  color: var(--signal-green);
  font-weight: 600;
  white-space: nowrap;
}
.project-stopped {
  font-size: 0.65rem;
  color: var(--ballast);
  white-space: nowrap;
}
.sparkline-container { margin: 0.4rem 0; color: var(--ballast); }
.sparkline-container.sparkline-alert { color: var(--signal-red); }
.sparkline { display: block; }
.stat-uptime-good { color: var(--signal-green); }
.stat-uptime-warn { color: var(--signal-amber); }
.project-down {
  font-size: 0.65rem;
  color: var(--signal-red);
  font-weight: 600;
  white-space: nowrap;
}

/* Live stream */
.live-controls {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.5rem 0 1rem;
}
.live-status {
  font-size: 0.75rem;
  font-weight: 600;
}
.live-connected { color: var(--signal-green); }
.live-connecting { color: var(--signal-amber); }
.live-disconnected { color: var(--ballast); }
.live-count {
  font-size: 0.7rem;
  color: var(--ballast);
  font-family: var(--font-mono);
}
.live-feed {
  display: flex;
  flex-direction: column;
  gap: 0;
  max-height: 80vh;
  overflow-y: auto;
}
.live-event {
  display: grid;
  grid-template-columns: 1.5rem 8rem 1fr auto;
  gap: 0.5rem;
  align-items: center;
  padding: 0.4rem 0.5rem;
  border-bottom: 1px solid var(--coal);
  font-size: 0.8rem;
  animation: fadeIn 0.3s ease;
}
@keyframes fadeIn {
  from { opacity: 0; background: #fffbeb; }
  to { opacity: 1; background: transparent; }
}
.live-event-icon { font-size: 0.85rem; text-align: center; }
.live-event-project {
  font-weight: 600;
  font-size: 0.7rem;
  color: var(--steel);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.live-event-msg {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--ballast);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.live-event-time {
  font-size: 0.65rem;
  color: var(--ballast);
  font-family: var(--font-mono);
  white-space: nowrap;
}
.project-remote {
  font-size: 0.65rem;
  color: var(--fusee-ember);
  font-weight: 600;
  white-space: nowrap;
}
.project-infra {
  display: flex;
  gap: 0.375rem;
  margin-bottom: 0.75rem;
}
.infra-chip {
  font-size: 1rem;
  width: 2rem;
  height: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f1f5f9;
  border-radius: var(--radius);
  cursor: default;
  text-decoration: none;
}
a.infra-link {
  cursor: pointer;
  background: #e6f0ff;
  transition: background 0.15s;
}
a.infra-link:hover {
  background: #cce0ff;
}

/* Dolt chip on the faultline project card. Uses the same pulse-dot
   legend as the station hero so the chip's health reading lines up
   visually with what the project's own overview page would show. */
.infra-chip.infra-dolt {
  position: relative;
  background: var(--coal);
}
.infra-chip.infra-dolt .infra-chip-dot {
  position: absolute;
  top: 0.3rem;
  right: 0.3rem;
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--ballast);
}
.infra-chip.infra-dolt-healthy .infra-chip-dot { background: var(--signal-green); }
.infra-chip.infra-dolt-faults  .infra-chip-dot { background: var(--signal-amber); }
.infra-chip.infra-dolt-down    .infra-chip-dot { background: var(--signal-red); }
.infra-chip.infra-dolt-silent  .infra-chip-dot { background: var(--ballast); }

/* Slug subhead on the cloud project card — sits in the .project-desc
   slot but reads as a slug, not free-form text. Slightly muted +
   monospace-leaning so the operator's eye lands on it as an identifier. */
.cloud-card-slug {
  color: var(--text-muted, #64748b);
  font-size: 0.8125rem;
}
.card-envs {
  display: flex;
  gap: 0.375rem;
  padding-top: 0.625rem;
  border-top: 1px solid var(--coal);
}
.env-badge {
  font-size: 0.6rem;
  padding: 0.2rem 0.5rem;
  border-radius: 3px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  font-weight: 600;
}
.env-production { background: #ecfdf5; color: var(--signal-green); }
.env-staging { background: #fffbeb; color: #b45309; }
.env-development { background: #f1f5f9; color: var(--ballast); }

/* Problem & Resolution boxes */
.problem-box {
  background: #fef2f2;
  border-left: 3px solid var(--signal-red);
  padding: 0.75rem 1rem;
  border-radius: 0 var(--radius) var(--radius) 0;
}
.problem-type {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.375rem;
}
.problem-type code {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  background: rgba(220,38,38,0.1);
  padding: 0.1rem 0.4rem;
  border-radius: 3px;
  color: var(--signal-red);
}
.problem-platform {
  font-size: 0.7rem;
  color: var(--ballast);
}
.problem-message {
  font-size: 0.85rem;
  font-weight: 500;
  word-break: break-word;
  margin-bottom: 0.25rem;
}
.problem-culprit {
  font-size: 0.75rem;
  color: var(--ballast);
}
.problem-culprit code {
  font-family: var(--font-mono);
  font-size: 0.7rem;
}
.problem-impact {
  font-size: 0.7rem;
  color: var(--ballast);
  margin-top: 0.375rem;
}
.resolution-box {
  background: #ecfdf5;
  border-left: 3px solid var(--signal-green);
  padding: 0.75rem 1rem;
  border-radius: 0 var(--radius) var(--radius) 0;
  display: flex;
  gap: 0.5rem;
  align-items: flex-start;
}
.resolution-box.regressed {
  background: #fff7ed;
  border-left-color: var(--fusee-ember);
}
.resolution-icon { font-size: 1rem; }
.resolution-text { font-size: 0.85rem; font-weight: 500; white-space: pre-line; }
.resolve-form textarea {
  width: 100%;
  font-family: var(--font-sans);
  font-size: 0.85rem;
  padding: 0.5rem;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  resize: vertical;
}
.resolve-form textarea:focus {
  outline: none;
  border-color: var(--steel);
}
.resolve-form h3 { margin-bottom: 0.75rem; }
.resolve-form .form-group { margin-bottom: 0.75rem; }
.resolve-form label {
  display: block;
  font-size: 0.8rem;
  font-weight: 600;
  margin-bottom: 0.25rem;
  color: var(--steel);
}
.resolution-bead {
  font-size: 0.7rem;
  color: var(--ballast);
  margin-top: 0.25rem;
}
.resolution-bead code {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  background: rgba(5,150,105,0.1);
  padding: 0.1rem 0.3rem;
  border-radius: 3px;
}
.resolution-details {
  background: #f0f9ff;
  border-left: 3px solid var(--info, #3b82f6);
  padding: 0.75rem 1rem;
  border-radius: 0 4px 4px 0;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.resolution-detail-label {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ballast);
  margin-bottom: 0.15rem;
}
.resolution-detail-text {
  font-size: 0.85rem;
  white-space: pre-line;
}
.resolution-detail-text code {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  background: rgba(59,130,246,0.1);
  padding: 0.1rem 0.3rem;
  border-radius: 3px;
}

/* Learnings panel (continuous-learning feature). Learning items reuse the
   .resolution-detail-* styling; these add the intro note, the "from this
   issue" tag, and the muted meta line (date / source / source-issue link). */
.learnings-note {
  font-size: 0.8rem;
  color: var(--ballast);
  margin-bottom: 0.6rem;
}
.learning-item {
  margin-bottom: 0.75rem;
}
.learning-tag {
  display: inline-block;
  margin-left: 0.4rem;
  padding: 0.05rem 0.4rem;
  border-radius: 0.6rem;
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--signal-green);
  background: rgba(5, 150, 105, 0.12);
  text-transform: none;
}
.learning-meta {
  margin-top: 0.25rem;
  font-size: 0.72rem;
  color: var(--ballast);
}
.learning-meta a {
  color: var(--ballast);
  text-decoration: underline;
}
.learning-meta > * + * {
  margin-left: 0.4rem;
}
.project-stats {
  display: flex;
  gap: 1.25rem;
  margin-bottom: 0.75rem;
}
.project-stat { display: flex; flex-direction: column; }
.stat-value {
  font-size: 1.1rem;
  font-weight: 700;
  font-family: var(--font-mono);
  line-height: 1.2;
}
.stat-value.stat-alert { color: var(--signal-amber); }
.stat-value.stat-danger { color: var(--signal-red); }
.stat-value.stat-muted {
  font-size: 0.7rem;
  font-weight: 500;
  color: var(--ballast);
}
.stat-label {
  font-size: 0.6rem;
  color: var(--ballast);
  text-transform: uppercase;
  letter-spacing: 0.3px;
}

/* Auth pages */
.auth-page {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  gap: 3rem;
  padding: 2rem;
  background: linear-gradient(135deg, var(--sleeper) 0%, var(--steel) 50%, #2d3a4f 100%);
}
.auth-hero {
  max-width: 420px;
  color: var(--surface);
}
.auth-logo {
  font-family: var(--font-mono);
  font-size: 2.5rem;
  font-weight: 700;
  letter-spacing: -1px;
  margin-bottom: 0.75rem;
}
.auth-tagline {
  font-size: 1.1rem;
  line-height: 1.5;
  color: #94a3b8;
  margin-bottom: 2rem;
}
.auth-features { display: flex; flex-direction: column; gap: 1rem; }
.auth-feature {
  display: flex; flex-direction: column; gap: 0.125rem;
}
.auth-feature strong { font-size: 0.85rem; color: var(--surface); }
.auth-feature span { font-size: 0.8rem; color: #94a3b8; }
.auth-card {
  background: white;
  padding: 2rem;
  border-radius: var(--radius);
  box-shadow: 0 4px 24px rgba(0,0,0,0.3);
  width: 100%;
  max-width: 380px;
  flex-shrink: 0;
}
.auth-card h1.auth-logo {
  font-size: 1.6rem;
  margin-bottom: 0.5rem;
  color: var(--steel);
}
.auth-card h2 {
  font-family: var(--font-mono);
  font-size: 1.25rem;
  margin-bottom: 0.25rem;
}
.auth-card h2 span { color: var(--signal-red); }
.auth-card-sub { color: var(--ballast); font-size: 0.85rem; margin-bottom: 1.5rem; }
.auth-card p { color: var(--ballast); font-size: 0.85rem; margin-bottom: 1.5rem; }
.auth-card p.auth-link { margin: 1rem 0 0; text-align: center; }
.auth-divider {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 1rem 0;
  color: var(--ballast);
  font-size: 0.8rem;
}
.auth-divider::before,
.auth-divider::after { content: ""; flex: 1; border-top: 1px solid var(--rule); }
.auth-version {
  margin-top: 1.25rem;
  font-size: 0.72rem;
  color: var(--ballast);
  opacity: 0.6;
  font-family: var(--font-mono);
  text-align: center;
}

@media (max-width: 768px) {
  .auth-page { flex-direction: column; gap: 2rem; }
  .auth-hero { text-align: center; }
  .auth-logo { font-size: 2rem; }
}

.form-group { margin-bottom: 1rem; }
.form-group label {
  display: block;
  font-size: 0.8rem;
  font-weight: 600;
  margin-bottom: 0.25rem;
}
.form-group input {
  width: 100%;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--border-input);
  border-radius: var(--radius);
  font-size: 0.875rem;
  font-family: var(--font-sans);
}
.form-group input:focus { outline: 2px solid var(--steel); outline-offset: -1px; }

/* Buttons share the same visual height as form inputs/selects (font
   0.875rem, padding 0.5rem 0.75rem) so a button next to a dropdown
   reads as one control row instead of two mismatched widgets. The
   .btn-sm variant is now slightly smaller for tight contexts (table
   row actions) but still tall enough to read alongside form-inline
   controls. */
.btn {
  display: inline-block;
  padding: 0.5rem 1.25rem;
  border-radius: var(--radius);
  font-size: 0.875rem;
  font-weight: 600;
  border: none;
  cursor: pointer;
  font-family: var(--font-sans);
  line-height: 1.4;
}
.btn-primary { background: var(--steel); color: var(--surface); }
.btn-primary:hover { background: var(--sleeper); }
.btn-notify { background: #e6f0ff; color: #3570b0; border: 1px solid #b0cee8; }
.btn-notify:hover { background: #cce0ff; }
.action-buttons { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.btn-sm {
  padding: 0.5rem 0.85rem;
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.4;
  background: var(--coal);
  color: var(--ballast);
  text-decoration: none;
}
.btn-sm:hover { background: var(--rule); color: var(--steel); }
.btn-full { width: 100%; }

.alert { padding: 0.75rem; border-radius: var(--radius); font-size: 0.8rem; margin-bottom: 1rem; }
.alert-error { background: #fef2f2; color: var(--signal-red); }

/* Settings form */
.settings-form { max-width: 32rem; }

/* Cloud-better banner at the top of the local-mode Integrations
   tab. Steers operators toward faultline.live for integrations that
   need always-on infrastructure. */
.settings-cloud-banner {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  padding: 0.85rem 1rem;
  background: #f4f7fb;
  border: 1px solid #d6dfee;
  border-left: 3px solid #4a6fa5;
  border-radius: var(--radius);
  margin: 0 0 1.25rem;
}
.settings-cloud-banner-icon {
  font-size: 1.4rem;
  color: #4a6fa5;
  line-height: 1;
}
.settings-cloud-banner-body { flex: 1; min-width: 0; }
.settings-cloud-banner-body strong {
  display: block;
  font-size: 0.92rem;
  margin-bottom: 0.3rem;
}
.settings-cloud-banner-body p {
  margin: 0 0 0.5rem;
  font-size: 0.82rem;
  color: var(--ballast);
  line-height: 1.45;
}
.settings-cloud-banner-link {
  display: inline-block;
  font-size: 0.82rem;
  font-weight: 600;
  color: #4a6fa5;
}
.settings-cloud-banner-link:hover {
  color: var(--steel);
  text-decoration: none;
}

/* Cloud-better integration sections collapse via <details> so they
   don't crowd the local-DSN + Cloud-Relay sections that operators
   actually use day-to-day. Configured-on-this-project sections stay
   open by default (open?={...} in templ); fresh installs see a
   clean compact list of disclosure rows. */
.settings-cloud-better {
  margin: 0.6rem 0;
  padding: 0;
  border: 1px solid #ece7df;
  border-radius: var(--radius);
  background: white;
}
.settings-cloud-better > summary {
  cursor: pointer;
  user-select: none;
  list-style: none;
  padding: 0.6rem 0.85rem;
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-size: 0.9rem;
}
.settings-cloud-better > summary::-webkit-details-marker { display: none; }
.settings-cloud-better > summary::before {
  content: '▸';
  font-size: 0.7rem;
  color: var(--ballast);
  transition: transform 0.15s;
}
.settings-cloud-better[open] > summary::before { transform: rotate(90deg); }
.settings-cloud-better-title { font-weight: 600; }
.settings-cloud-better-hint {
  color: var(--ballast);
  font-size: 0.78rem;
  font-weight: 400;
}
.settings-cloud-better[open] > .settings-form,
.settings-cloud-better[open] > p,
.settings-cloud-better[open] > table {
  padding: 0 1rem 0.85rem;
}

.settings-form select {
  width: 100%;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--border-input);
  border-radius: var(--radius);
  font-size: 0.875rem;
  font-family: var(--font-sans);
  background: white;
}
.settings-form select:focus { outline: 2px solid var(--steel); outline-offset: -1px; }
.form-hint { display: block; font-size: 0.7rem; color: var(--ballast); margin-top: 0.2rem; }
.form-actions { display: flex; gap: 0.5rem; margin-top: 1.5rem; }
.form-actions .btn { text-decoration: none; text-align: center; }
.page-header-row { display: flex; justify-content: space-between; align-items: flex-start; flex-wrap: wrap; gap: 0.75rem; }

/* Pagination */
.pagination { display: flex; gap: 0.5rem; padding: 1rem 0; justify-content: center; }
.pagination a, .pagination span {
  padding: 0.375rem 0.75rem;
  border-radius: var(--radius);
  font-size: 0.8rem;
}
.pagination a { background: white; border: 1px solid var(--border-input); }
.pagination a:hover { background: var(--coal); text-decoration: none; }
.pagination .current { background: var(--steel); color: var(--surface); }

/* Release badges */
.release-badge {
  display: inline-block;
  background: #e8e0d6;
  color: var(--steel);
  padding: 0.15em 0.5em;
  border-radius: 4px;
  font-size: 0.78rem;
  font-family: monospace;
  white-space: nowrap;
}
.release-badge.release-sm { font-size: 0.72rem; padding: 0.1em 0.4em; }
.project-release { margin: 0.3rem 0; }
.problem-releases { margin: 0.5rem 0; display: flex; gap: 1rem; flex-wrap: wrap; font-size: 0.85rem; color: var(--ballast); }

/* Merge UI */
.merge-banner {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  background: #f0f4f8;
  border: 1px solid #ccd5de;
  border-radius: 6px;
}
.merge-icon { font-size: 1.3rem; }
.merge-text { font-weight: 500; }
.merge-text a { color: var(--steel); text-decoration: underline; }
.merge-detail { font-size: 0.82rem; color: var(--ballast); margin-top: 0.2rem; }
.merge-warning { font-size: 0.85rem; color: var(--ballast); margin-bottom: 0.75rem; padding: 0.5rem; background: #fff8e1; border-radius: 4px; border: 1px solid #ffe082; }
.merge-form { background: var(--page); padding: 1rem; border-radius: 6px; border: 1px solid #e0d6cc; }
.merge-results {
  max-height: 200px;
  overflow-y: auto;
  border: 1px solid #e0d6cc;
  border-radius: 4px;
  margin-top: 0.25rem;
}
.merge-results:empty { border: none; }
.merge-result-item {
  padding: 0.5rem 0.75rem;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid #f0ebe4;
}
.merge-result-item:last-child { border-bottom: none; }
.merge-result-item:hover { background: var(--coal); }
.merge-result-title { font-size: 0.9rem; }
.merge-result-meta { font-size: 0.78rem; color: var(--ballast); }
.merge-result-empty { padding: 0.5rem 0.75rem; color: var(--ballast); font-size: 0.85rem; }
.merge-selected {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  background: #e8f5e9;
  border-radius: 4px;
  margin-bottom: 0.75rem;
  font-size: 0.9rem;
}
.merged-children { display: flex; flex-direction: column; gap: 0.4rem; }
.merged-child {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.4rem 0.6rem;
  background: var(--coal);
  border-radius: 4px;
}
/* Cloud merge form (fa-75t.2): inside a .cloud-action-disclosure the search +
   results + selected + submit stack vertically, overriding the flex-row of the
   sibling snooze/archive forms. */
.cloud-merge-form {
  flex-direction: column;
  align-items: stretch;
  min-width: 18rem;
}
.merge-search-wrap { width: 100%; }
.cloud-merge-form input[type="text"] { width: 100%; min-width: 0; }
/* Resolve (stabilize) form (fa-75t.3): the cause/fix textareas + commit input
   stack vertically inside the disclosure. */
.cloud-resolve-form {
  flex-direction: column;
  align-items: stretch;
  min-width: 20rem;
}
.cloud-resolve-form label { font-size: 0.8rem; color: var(--ballast); margin-top: 0.25rem; }
.cloud-resolve-form textarea {
  width: 100%;
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--border-input);
  border-radius: 4px;
  font: inherit;
  font-size: 0.85rem;
  resize: vertical;
}
.cloud-resolve-form input[type="text"] { width: 100%; min-width: 0; }
/* Result rows are <button> (keyboard-accessible) — strip the native chrome so
   they read like the list rows, keeping the row separator. */
button.merge-result-item {
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: 0;
  border-bottom: 1px solid #f0ebe4;
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
}
.cloud-merged-children { margin-top: 1rem; }
.cloud-merged-children-list {
  list-style: none;
  padding: 0;
  margin: 0.5rem 0 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.cloud-merged-children-list li {
  padding: 0.4rem 0.6rem;
  background: var(--coal);
  border-radius: 4px;
  font-size: 0.9rem;
}
/* Project identity hero (fa-75t.5): live status pulse + identity meta line. */
.cloud-project-title { display: flex; align-items: center; gap: 0.5rem; }
.cloud-pulse {
  display: inline-block;
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 50%;
  background: var(--ballast);
  flex: none;
}
.cloud-pulse-green { background: #2e7d32; color: #2e7d32; animation: cloud-pulse-anim 2s infinite; }
.cloud-pulse-red { background: #c62828; color: #c62828; animation: cloud-pulse-anim 2s infinite; }
.cloud-pulse-yellow { background: #f9a825; }
.cloud-pulse-idle { background: #9e9e9e; }
.cloud-pulse-stale { background: #ef6c00; }
@keyframes cloud-pulse-anim {
  0% { box-shadow: 0 0 0 0 currentcolor; }
  70% { box-shadow: 0 0 0 0.5rem rgba(0, 0, 0, 0); }
  100% { box-shadow: 0 0 0 0 rgba(0, 0, 0, 0); }
}
.cloud-project-identity {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0.3rem 0 0;
  font-size: 0.85rem;
}
.cloud-identity-status { font-weight: 600; }
.cloud-identity-status-green { color: #2e7d32; }
.cloud-identity-status-red { color: #c62828; }
.cloud-identity-status-yellow { color: #b06f00; }
.cloud-identity-status-idle { color: var(--ballast); }
.cloud-identity-status-stale { color: #b35309; }
.cloud-identity-chip {
  color: var(--ballast);
  background: var(--coal);
  border: 1px solid var(--rule);
  border-radius: 999px;
  padding: 0.1rem 0.5rem;
  font-size: 0.78rem;
}
.cloud-identity-chip code { font-size: 0.78rem; }
/* Hero description + repo URL chips (fa-75t.5 follow-up). */
.cloud-project-description {
  margin: 0.35rem 0 0;
  font-size: 0.9rem;
  color: var(--ballast);
  max-width: 70ch;
}
a.cloud-identity-repo { text-decoration: none; transition: border-color 0.12s; }
a.cloud-identity-repo:hover { border-color: var(--ballast); text-decoration: none; }
@media (prefers-reduced-motion: reduce) {
  .cloud-pulse-green, .cloud-pulse-red { animation: none; }
}
/* Project systems grid (fa-75t.7): a nav hub of subsystem cards. */
.cloud-systems-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 0.75rem;
  margin: 1rem 0;
}
.cloud-system-card {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  padding: 0.75rem 0.9rem;
  background: #fff;
  border: 1px solid var(--rule);
  border-radius: 8px;
  text-decoration: none;
  color: var(--steel);
  transition: border-color 0.12s, box-shadow 0.12s;
}
a.cloud-system-card:hover {
  border-color: var(--ballast);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
  text-decoration: none;
}
.cloud-system-label {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ballast);
}
.cloud-system-name {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 600;
  font-size: 1rem;
}
.cloud-system-meta { font-size: 0.78rem; color: var(--ballast); }
/* 24h event sparkline (fa-75t.8). */
.cloud-sparkline-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0.5rem 0 1rem;
  color: #4a7a63;
}
.cloud-sparkline-label {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ballast);
}
.cloud-sparkline-row .sparkline { display: block; }
.merged-child a { color: var(--steel); text-decoration: underline; }
.merged-child-count { font-size: 0.8rem; color: var(--ballast); }

/* Snooze */
.snooze-info { font-size: 0.85rem; color: var(--steel); }
.snooze-reason { margin-top: 0.25rem; color: var(--ballast); font-style: italic; }

/* Empty state */
.empty { text-align: center; padding: 3rem 1rem; color: var(--ballast); }
.empty p { font-size: 0.9rem; }

/* Onboarding card — shown on empty projects page and after creating a project */
.onboarding {
  max-width: 44rem;
  margin: 1rem 0 2rem;
}
.onboarding-header {
  margin-bottom: 1.5rem;
}
.onboarding-header h3 {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--steel);
}
.onboarding-header p {
  font-size: 0.85rem;
  color: var(--ballast);
  margin-top: 0.25rem;
}
.onboarding-tier {
  background: white;
  border: 1px solid #e8e3dc;
  border-left: 3px solid var(--fusee-ember);
  border-radius: var(--radius);
  padding: 1rem 1.25rem;
  margin-bottom: 1rem;
}
.onboarding-tier-label {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--fusee-ember);
  margin-bottom: 0.4rem;
}
.onboarding-tier h4 {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--steel);
  margin-bottom: 0.4rem;
}
.onboarding-tier p {
  font-size: 0.82rem;
  color: var(--steel);
  margin: 0.4rem 0;
}
.onboarding-tier code {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  background: #f4f0ea;
  padding: 0.05em 0.3em;
  border-radius: 3px;
}
.onboarding-code {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  background: var(--sleeper);
  color: #e2e8f0;
  padding: 0.75rem 1rem;
  border-radius: var(--radius);
  margin: 0.5rem 0;
  overflow-x: auto;
  white-space: pre;
  line-height: 1.5;
}
.onboarding-hint {
  font-size: 0.75rem !important;
  color: var(--ballast) !important;
  margin-top: 0.5rem !important;
}
.onboarding-footer {
  text-align: center;
  padding: 0.75rem;
  font-size: 0.8rem;
  color: var(--ballast);
}
.onboarding-footer a {
  color: var(--steel);
  text-decoration: underline;
}
.onboarding-copyrow {
  display: flex;
  gap: 0.5rem;
  margin: 0.5rem 0;
}
.onboarding-copyinput {
  flex: 1;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--border-input);
  border-radius: var(--radius);
  font-family: var(--font-mono);
  font-size: 0.78rem;
  background: #f9f7f4;
  color: var(--steel);
}

/* Cloud-mode empty-state: two parallel paths (solo MCP vs fleet) so a new
   user picks an approach before they hit "+ New project". */
.onboarding-paths {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  margin-bottom: 1rem;
}
@media (min-width: 980px) {
  .onboarding-paths { grid-template-columns: 1fr 1fr; }
}
.onboarding-path {
  background: white;
  border: 1px solid #e8e3dc;
  border-top: 3px solid var(--fusee-ember);
  border-radius: var(--radius);
  padding: 1.25rem 1.25rem 1rem;
  display: flex;
  flex-direction: column;
}
.onboarding-path-fleet { border-top-color: var(--fusee-ember); }
.onboarding-path-label {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--fusee-ember);
  margin-bottom: 0.5rem;
}
.onboarding-path-fleet .onboarding-path-label { color: var(--fusee-ember); }
.onboarding-path h4 {
  font-size: 1rem;
  font-weight: 600;
  color: var(--steel);
  margin: 0 0 0.5rem;
}
.onboarding-path p {
  font-size: 0.82rem;
  color: var(--steel);
  margin: 0.4rem 0;
  line-height: 1.5;
}
.onboarding-path code {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  background: #f4f0ea;
  padding: 0.05em 0.3em;
  border-radius: 3px;
}
.onboarding-steps {
  font-size: 0.82rem;
  color: var(--steel);
  margin: 0.4rem 0 0.4rem 1.1rem;
  padding: 0;
  line-height: 1.55;
}
.onboarding-steps li { margin-bottom: 0.25rem; }
.onboarding-step-text {
  font-size: 0.82rem;
  color: var(--steel);
  margin: 0.6rem 0 0.2rem;
}

/* Database monitoring cards */
.db-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1rem;
  margin-bottom: 2rem;
}
.db-card {
  background: white;
  border-radius: var(--radius);
  border: 1px solid var(--rule);
  overflow: hidden;
  transition: box-shadow 0.15s;
  text-decoration: none;
  color: var(--steel);
  display: block;
}
.db-card:hover { box-shadow: 0 2px 8px rgba(0,0,0,0.08); text-decoration: none; }
.db-card-status-bar { height: 3px; }
.db-bar-dormant { background: var(--signal-green); }
.db-bar-tremor { background: var(--signal-amber); }
.db-bar-rupture { background: var(--signal-red); }
.db-bar-sediment { background: var(--ballast); }
.db-card-body { padding: 1rem; }
.db-card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem; }
.db-card-name { font-weight: 600; font-size: 0.95rem; }
.db-status { font-size: 0.8rem; font-weight: 500; }
.db-status-dormant { color: var(--signal-green); }
.db-status-tremor { color: var(--signal-amber); }
.db-status-rupture { color: var(--signal-red); }
.db-status-sediment { color: var(--ballast); }
.db-card-meta { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; margin-bottom: 0.5rem; }
.db-type-badge {
  display: inline-block;
  background: #e8e0d6;
  color: var(--steel);
  padding: 0.1em 0.5em;
  border-radius: 4px;
  font-size: 0.75rem;
  font-family: monospace;
}
.db-type-badge.db-type-system {
  background: var(--steel);
  color: var(--surface);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 600;
}
.db-check-ago { font-size: 0.75rem; color: var(--ballast); }
.db-card-stats { display: flex; gap: 1rem; }

/* Database detail page */
.db-detail-summary {
  display: flex;
  gap: 2rem;
  align-items: flex-start;
  margin-bottom: 1.5rem;
  padding: 1rem;
  background: white;
  border-radius: var(--radius);
  border: 1px solid var(--rule);
}
.db-status-large { font-size: 1.3rem; font-weight: 600; }
.db-detail-meta {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.85rem;
}
.db-detail-meta code { font-size: 0.8rem; background: var(--coal); padding: 0.1em 0.3em; border-radius: 3px; }

/* Check history timeline */
.check-timeline { margin-bottom: 1rem; }
.check-timeline-svg { width: 100%; height: 40px; border-radius: 4px; background: var(--coal); }
.check-message { max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.8rem; color: var(--ballast); }

/* Badge variants */
.badge { display: inline-block; padding: 0.15em 0.5em; border-radius: 4px; font-size: 0.75rem; font-weight: 500; }
.badge-green { background: #e0f5ec; color: #1a7a4a; }
.badge-yellow { background: #fef3cd; color: #856404; }
.badge-red { background: #fde8e8; color: #c62828; }
.badge-muted { background: var(--coal); color: var(--ballast); }

/* Dolt health page */
.dolt-health-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 1rem;
  margin-top: 1rem;
}
.dolt-health-card {
  background: white;
  border-radius: var(--radius);
  border: 1px solid var(--rule);
  padding: 1.25rem;
  text-align: center;
}
.dolt-health-label { font-size: 0.8rem; color: var(--ballast); margin-bottom: 0.5rem; text-transform: uppercase; letter-spacing: 0.05em; }
.dolt-health-value { font-size: 1.5rem; font-weight: 700; font-family: var(--font-mono); }
.dolt-good { color: var(--signal-green); }
.dolt-warn { color: var(--signal-amber); }
.dolt-bad { color: var(--signal-red); }

/* Container monitoring cards */
.ct-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1rem;
  margin-bottom: 2rem;
}
.ct-card {
  background: white;
  border-radius: var(--radius);
  border: 1px solid var(--rule);
  overflow: hidden;
  transition: box-shadow 0.15s;
  text-decoration: none;
  color: inherit;
  display: block;
}
.ct-card:hover { box-shadow: 0 2px 8px rgba(0,0,0,0.08); text-decoration: none; }
.ct-card-status-bar { height: 3px; }
.ct-bar-dormant { background: var(--signal-green); }
.ct-bar-tremor { background: var(--signal-amber); }
.ct-bar-rupture { background: var(--signal-red); }
.ct-bar-sediment { background: var(--ballast); }
.ct-card-body { padding: 1rem; }
.ct-card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem; }
.ct-card-name { font-weight: 600; font-size: 0.95rem; }
.ct-status { font-size: 0.8rem; font-weight: 500; }
.ct-status-dormant { color: var(--signal-green); }
.ct-status-tremor { color: var(--signal-amber); }
.ct-status-rupture { color: var(--signal-red); }
.ct-status-sediment { color: var(--ballast); }
.ct-card-meta { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; margin-bottom: 0.5rem; }
.ct-service-badge {
  display: inline-block;
  background: #e0e8f0;
  color: var(--steel);
  padding: 0.1em 0.5em;
  border-radius: 4px;
  font-size: 0.75rem;
  font-weight: 500;
}
.ct-image-tag {
  font-size: 0.75rem;
  color: var(--ballast);
  font-family: var(--font-mono);
}
.ct-card-stats { display: flex; gap: 1rem; }

/* Container detail page */
.ct-detail-summary {
  display: flex;
  gap: 2rem;
  align-items: flex-start;
  margin-bottom: 1.5rem;
  padding: 1rem;
  background: white;
  border-radius: var(--radius);
  border: 1px solid var(--rule);
}
.ct-detail-meta {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.85rem;
}
.ct-detail-meta code { font-size: 0.8rem; background: var(--coal); padding: 0.1em 0.3em; border-radius: 3px; }

/* Docker settings threshold form */
.threshold-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin-bottom: 0.5rem;
}

/* Cloud-mode project index (fl-w94). */
.project-card-header { display: flex; align-items: center; justify-content: space-between; }
.project-card-tags { display: flex; gap: 0.375rem; margin-top: 0.5rem; }
.project-card-hint {
  margin-top: 0.5rem;
  padding: 0.4rem 0.75rem;
  background: var(--coal);
  border-radius: var(--radius);
  font-size: 0.7rem;
  color: var(--ballast);
}
.badge-tiny { font-size: 0.6rem; vertical-align: middle; }
.stat-online { color: var(--signal-green); }

/* Cloud-mode project detail two-column grid. Main column holds
   stats + tables, sidebar holds Connection (DSN), Slack status,
   and quick-link cards. Collapses to single column under 1024px
   so phones/tablets keep the original stacked flow. */
.cloud-detail-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
}
.cloud-detail-main { min-width: 0; }
.cloud-detail-side {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.cloud-detail-side .card { margin-bottom: 0; }
.cloud-detail-side .card-body { padding: 1rem 1.1rem; }
.cloud-side-card-label {
  font-size: 0.65rem;
  text-transform: uppercase;
  color: var(--ballast);
  letter-spacing: 0.6px;
  font-weight: 600;
  margin-bottom: 0.5rem;
}
.cloud-side-card-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  font-size: 0.85rem;
}
.cloud-side-card-row + .cloud-side-card-row { margin-top: 0.4rem; }
.cloud-side-meta {
  font-size: 0.72rem;
  color: var(--ballast);
  margin-top: 0.5rem;
  line-height: 1.45;
}
.cloud-side-link {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.78rem;
  color: var(--steel);
  font-weight: 500;
  margin-top: 0.6rem;
}
.cloud-side-link:hover { color: var(--signal-red); text-decoration: none; }
.cloud-side-link-arrow {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--ballast);
  transition: transform 0.15s, color 0.15s;
}
.cloud-side-link:hover .cloud-side-link-arrow {
  color: var(--signal-red);
  transform: translateX(2px);
}
.cloud-side-dsn details > summary {
  cursor: pointer;
  font-size: 0.78rem;
  color: var(--steel);
  user-select: none;
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}
.cloud-side-dsn details > summary::-webkit-details-marker { display: none; }
.cloud-side-dsn details > summary::after {
  content: '▾';
  font-size: 0.6rem;
  color: var(--ballast);
  transition: transform 0.15s;
}
.cloud-side-dsn details[open] > summary::after { transform: rotate(180deg); }
.cloud-side-dsn details > .dsn-block-inner {
  margin-top: 0.6rem;
}
.cloud-stale-prefix,
.cloud-stale-suffix {
  white-space: nowrap;
  font-size: 0.78rem;
  color: var(--steel);
}
.cloud-stale-input {
  width: 4rem;
  padding: 0.2rem 0.4rem;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  border: 1px solid #d6d2cc;
  border-radius: 4px;
  background: white;
}
.cloud-stale-input:focus {
  outline: none;
  border-color: var(--steel);
}

/* Collapsible Recent Events section on the project detail page.
   The events stream visually duplicates the Issues table (same
   shape, slightly different content) — keeping it collapsed by
   default lets Issues breathe. Disclosure triangle hidden so the
   summary reads as a regular section heading; counts in the
   summary so the operator sees activity without expanding. */
.cloud-events-details > summary {
  list-style: none;
  cursor: pointer;
  user-select: none;
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}
.cloud-events-details > summary::-webkit-details-marker {
  display: none;
}
.cloud-events-details > summary::before {
  content: "▸";
  font-size: 0.7rem;
  color: var(--ballast);
  transition: transform 0.15s ease;
  display: inline-block;
}
.cloud-events-details[open] > summary::before {
  transform: rotate(90deg);
}
.cloud-events-count {
  font-weight: 400;
  font-size: 0.75rem;
  text-transform: none;
  letter-spacing: 0;
  color: var(--ballast);
}

/* Bulk-actions toolbar — contextual. Hidden until at least one row
   is checked (cloudBulkUpdateCount toggles .cloud-bulk-active on
   the form). When it appears it slots in above the table without
   shifting the page, then snaps shut on Cancel or after submission.
   "Select all" lives in the table header, not here — standard
   table-selection idiom; this surface is purely for "do something
   with what you've selected." */
.cloud-bulk-toolbar {
  display: none;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.5rem 0.75rem;
  margin-bottom: 0.5rem;
  background: var(--surface-muted, #f8f6f1);
  border: 1px solid var(--surface-border, #e5e7eb);
  border-left: 3px solid var(--signal-red, #dc2626);
  border-radius: var(--radius);
  font-size: 0.85rem;
}
.cloud-bulk-toolbar.cloud-bulk-active {
  display: flex;
}
.cloud-bulk-selected-count {
  color: var(--steel);
  font-weight: 600;
  font-size: 0.85rem;
}
.cloud-bulk-action {
  padding: 0.25rem 0.4rem;
  font-size: 0.85rem;
}
.cloud-bulk-checkbox {
  cursor: pointer;
}

/* Compact info strip above the issues table on the project detail
   page. Replaces the right-side sidebar that used to eat ~320px of
   table width. Cards become inline chips that wrap onto multiple
   lines on narrow viewports but stay on one row at desktop width. */
.cloud-detail-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  margin: 0 0 1.25rem;
  align-items: stretch;
}
.cloud-strip-chip {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: white;
  border: 1px solid #ece7df;
  border-radius: var(--radius);
  padding: 0.55rem 0.85rem;
  font-size: 0.82rem;
  color: var(--steel);
  flex: 1 1 auto;
  min-width: 0;
}
.cloud-strip-label {
  font-size: 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--ballast);
  font-weight: 700;
  white-space: nowrap;
}
.cloud-strip-value {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
}
.cloud-strip-emoji {
  font-size: 0.95rem;
  line-height: 1;
}

/* Slack 4-square logo. Sized small enough to sit inline with the
   surrounding text on chips/badges; callers can override via a
   modifier class (.slack-icon-lg, .slack-icon-tiny) when a different
   scale fits better. */
.slack-icon {
  width: 0.95rem;
  height: 0.95rem;
  flex-shrink: 0;
  display: inline-block;
  vertical-align: -2px;
}
.slack-icon-tiny { width: 0.75rem; height: 0.75rem; vertical-align: -1px; }
.slack-icon-lg   { width: 1.25rem; height: 1.25rem; vertical-align: -3px; }
.slack-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}
.cloud-strip-link {
  color: var(--steel);
  font-weight: 500;
}
.cloud-strip-link:hover {
  color: var(--signal-red);
  text-decoration: none;
}

/* Connection chip uses <details> for the collapsible DSN body.
   Override the default disclosure marker with a small caret that
   matches the rest of the dashboard's iconography. */
.cloud-strip-dsn {
  display: block;
  padding: 0.4rem 0.85rem;
}
.cloud-strip-dsn > summary {
  cursor: pointer;
  user-select: none;
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.15rem 0;
}
.cloud-strip-dsn > summary::-webkit-details-marker { display: none; }
.cloud-strip-dsn > summary::after {
  content: '▾';
  font-size: 0.6rem;
  color: var(--ballast);
  transition: transform 0.15s;
}
.cloud-strip-dsn[open] > summary::after { transform: rotate(180deg); }
.cloud-strip-body {
  margin-top: 0.5rem;
}

/* Triage chip is a form, not a static block — needs the same chip
   chrome but with form fields laid out inline. */
.cloud-strip-triage {
  flex-wrap: wrap;
}
.cloud-strip-triage .btn {
  margin-left: auto;
}

/* Issue list filter bar — sits above the issues table on the project
   detail page. GET form with selects so server-side filtering keeps
   working without any JS state to sync. */
.cloud-issue-filter {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.75rem;
  flex-wrap: wrap;
}
.cloud-issue-filter-controls {
  display: flex;
  gap: 0.85rem;
  flex-wrap: wrap;
  align-items: flex-end;
}
.cloud-issue-filter label {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}
.cloud-issue-filter-label {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--ballast);
  font-weight: 600;
}
.cloud-issue-filter select {
  font-size: 0.78rem;
  padding: 0.3rem 0.5rem;
  border: 1px solid #d6d2cc;
  border-radius: 4px;
  background: white;
  color: var(--steel);
  font-family: var(--font-sans);
  min-width: 8.5rem;
}
.cloud-issue-filter select:focus {
  outline: none;
  border-color: var(--steel);
}
.cloud-issue-filter-summary {
  font-size: 0.75rem;
  color: var(--ballast);
  font-family: var(--font-mono);
  white-space: nowrap;
}

/* Issue-list sort control. The bar carries its own layout so the
   "Sort by" label does not sit against the first option, and each
   option is a chip with a border of its own — three separate
   controls rather than one run of words. The active chip is filled
   the way .filter-tab.active is on the local dashboard, so the two
   surfaces read the same. */
.cloud-issue-sort-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0 0 0.6rem;
}
.cloud-issue-sort-bar-label {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--ballast);
  font-weight: 600;
  margin-right: 0.15rem;
}
.cloud-issue-sort-link {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.25rem 0.65rem;
  border: 1px solid var(--rule);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--ballast);
  font-size: 0.72rem;
  line-height: 1.4;
  white-space: nowrap;
  text-decoration: none;
}
.cloud-issue-sort-link:hover {
  color: var(--fusee-ember);
  border-color: var(--fusee-ember);
  text-decoration: none;
}
.cloud-issue-sort-link-active {
  background: var(--steel);
  border-color: var(--steel);
  color: var(--surface);
  font-weight: 600;
}
.cloud-issue-sort-link-active:hover {
  background: var(--steel);
  border-color: var(--steel);
  color: var(--surface);
}
.cloud-issue-sort-arrow {
  font-size: 0.65em;
  color: inherit;
}

/* Pager footer below the issues table. */
.cloud-issue-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  margin: 0.85rem 0 0.25rem;
  font-size: 0.78rem;
  font-family: var(--font-mono);
}
.cloud-issue-pager-link {
  color: var(--steel);
  padding: 0.25rem 0.5rem;
  border-radius: 4px;
}
.cloud-issue-pager-link:hover {
  background: #efeae3;
  text-decoration: none;
}
.cloud-issue-pager-disabled {
  color: var(--ballast);
  cursor: default;
  pointer-events: none;
  opacity: 0.5;
}
.cloud-issue-pager-state {
  color: var(--ballast);
}

/* Snoozed rows render muted so a "snoozed" filter view reads as
   deferred work at a glance. The amber Snoozed badge already lives
   in the status column — this just adds a softer overall tone. */
.cloud-issue-row-snoozed td {
  color: var(--ballast);
  background: #fdfaf3;
}
.cloud-issue-row-snoozed .issue-title-link {
  color: var(--ballast);
}

/* The cloud issue row carries a third child that local's list does
   not: the per-row triage forms, which must stay outside the
   issue-card anchor to be valid HTML. Without a track of their own
   the actions auto-place into an implicit second grid row and sit
   BENEATH the issue, so .issue-card-row declares a track for each of
   the three children and the card takes minmax(0, 1fr) to yield the
   width the actions need instead of pushing them off. Restated here
   so the cloud row names the three-track shape it depends on, and so
   the breakpoint below has something of its own to override. */
.cloud-issue-card-row {
  grid-template-columns: auto minmax(0, 1fr) auto;
}

/* Two-action issue row (Resolve + Snooze) needs a tighter inline
   stack so the buttons stay on one line in their column. */
.cloud-issue-row-actions {
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 0.35rem;
  justify-content: flex-end;
  /* Track 3 of .issue-card-row — the same vertical inset as the card, taken
     from the shared row variable, so the buttons sit on the row's first line. */
  padding: var(--issue-row-pad-y) 1rem var(--issue-row-pad-y) 0;
}
.cloud-issue-row-actions .inline-form {
  display: inline-flex;
}

/* Below the tablet breakpoint there is no room for a third column:
   the actions drop under the issue they belong to, left-aligned with
   its title rather than with the checkbox gutter. */
@media (max-width: 768px) {
  .cloud-issue-card-row {
    grid-template-columns: auto minmax(0, 1fr);
  }
  .issue-card-row.cloud-issue-card-row > .cloud-issue-row-actions {
    grid-column: 2;
    justify-content: flex-start;
    padding: 0 1rem 0.75rem 0;
  }
}
.cloud-issue-snooze-btn {
  color: var(--ballast);
}
.cloud-issue-snooze-btn:hover {
  color: var(--steel);
}
@media (min-width: 1024px) {
  .cloud-detail-grid {
    grid-template-columns: minmax(0, 1fr) 320px;
    align-items: start;
  }
  .cloud-detail-side {
    position: sticky;
    top: 4.5rem;
  }
}

.cloud-stat-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}
.cloud-stat-body { padding: 0.75rem 1rem; }
.cloud-stat-label {
  font-size: 0.7rem;
  text-transform: uppercase;
  color: var(--ballast);
  letter-spacing: 0.5px;
}
.cloud-stat-number { font-size: 1.5rem; font-weight: 700; margin-top: 0.125rem; }
.cloud-stat-text { font-size: 0.875rem; margin-top: 0.25rem; }
.cloud-stat-sub { font-size: 0.7rem; color: var(--ballast); margin-top: 0.125rem; }

.cloud-banner {
  padding: 0.5rem 1rem;
  border-radius: var(--radius);
  margin-bottom: 1.5rem;
  font-size: 0.85rem;
  border-left: 3px solid;
}
.cloud-banner-warn {
  background: var(--coal);
  color: var(--ballast);
  border-left-color: var(--border-input);
}
.cloud-banner-ok {
  background: #f0fdf4;
  color: var(--signal-green);
  border-left-color: var(--signal-green);
}

.dsn-block { margin-bottom: 1.5rem; }
.dsn-label {
  font-size: 0.75rem;
  text-transform: uppercase;
  color: var(--ballast);
  letter-spacing: 0.5px;
  margin-bottom: 0.25rem;
}
.cloud-slack-summary {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-size: 0.85rem;
  margin-bottom: 0.5rem;
}
.section-card { margin-bottom: 1.5rem; }

.event-message {
  max-width: 350px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.event-platform { font-size: 0.8rem; }
.event-release { font-size: 0.75rem; color: var(--ballast); }
.event-when { font-size: 0.8rem; color: var(--ballast); }

/* Recent Events table on the cloud project detail page. All cells share
   one body font-size so the row reads as a unit; only the level pill
   and metadata columns shift to the muted color. Replaces the earlier
   patchwork of 0.75/0.8/default sizes that looked like a font soup. */
.cloud-events-table { font-size: 0.85rem; }
.cloud-events-table th {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--ballast);
  font-weight: 600;
}
.cloud-events-table td {
  vertical-align: middle;
  padding: 0.5rem 0.75rem;
}
.cloud-event-message {
  max-width: 360px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--sleeper);
}
.cloud-event-platform,
.cloud-event-release,
.cloud-event-when {
  font-size: 0.8rem;
  color: var(--ballast);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
/* Pill styling for the level cell — was unstyled before because the
   templ emitted .level-error et al but the stylesheet only had
   .events-level--error. Templ now emits both classes so this pill
   matches the events-list styling on the issue page. */
.events-level {
  display: inline-block;
  padding: 0.1rem 0.45rem;
  border-radius: 3px;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  font-weight: 600;
  background: var(--rule);
  color: var(--ballast);
}
.issue-title-cell {
  font-weight: 500;
  max-width: 300px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.issue-title-link { color: inherit; text-decoration: none; font-weight: 600; }
.row-action-btn { font-size: 0.65rem; padding: 0.15rem 0.5rem; }
.inline-form { display: inline; }
.push-right { margin-left: auto; }

.cloud-settings-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin-bottom: 1rem;
}
.form-sublabel { display: block; font-size: 0.8rem; font-weight: 600; margin-bottom: 0.25rem; }
.cloud-visibility-select { font-size: 0.85rem; padding: 0.35rem 0.5rem; max-width: 200px; }
.inline-code {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  background: var(--coal);
  padding: 0.1rem 0.3rem;
  border-radius: 3px;
}
.danger-title { color: #ef4444; }
.danger-card { border-color: #fecaca; }
.cloud-danger-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

/* Cloud-mode issue detail (fl-w94). */
.issue-title-heading { margin-top: 0.25rem; }
.cloud-issue-meta { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.cloud-issue-meta-text { color: var(--ballast); font-size: 0.85rem; }
.cloud-issue-actions { margin-left: auto; display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.5rem; }
/* Snooze/Archive reveal forms (fa-75t.1): a native <details> disclosure so the
   duration + reason inputs stay tucked behind a button until needed, no JS. */
.cloud-action-disclosure > summary { list-style: none; cursor: pointer; }
.cloud-action-disclosure > summary::-webkit-details-marker { display: none; }
.cloud-action-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.5rem;
  padding: 0.6rem;
  background: var(--coal);
  border: 1px solid var(--rule);
  border-radius: 6px;
}
.cloud-action-form label { font-size: 0.8rem; color: var(--ballast); }
.cloud-action-form input[type="text"] {
  min-width: 12rem;
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--border-input);
  border-radius: 4px;
  font-size: 0.85rem;
}
.cloud-action-form select {
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--border-input);
  border-radius: 4px;
  font-size: 0.85rem;
}
.cloud-event-meta {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  font-size: 0.85rem;
  color: var(--ballast);
  margin-bottom: 1rem;
}
.cloud-event-id { font-family: var(--font-mono); font-size: 0.75rem; }
.cloud-event-block { margin-bottom: 1rem; }
.cloud-event-label {
  font-size: 0.75rem;
  text-transform: uppercase;
  color: var(--ballast);
  letter-spacing: 0.5px;
  margin-bottom: 0.375rem;
}
.cloud-event-chips { display: flex; flex-wrap: wrap; gap: 0.375rem; }
.cloud-event-chip { font-size: 0.7rem; }
.cloud-stack {
  background: #1e1e1e;
  color: #d4d4d4;
  border-radius: var(--radius);
  padding: 1rem;
  overflow-x: auto;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  line-height: 1.8;
}
.cloud-stack-frame { margin-bottom: 0.25rem; }
.cloud-stack-fn { color: #569cd6; }
.cloud-stack-sep { color: #808080; }
.cloud-stack-file { color: #ce9178; }
.cloud-stack-context { color: #6a9955; padding-left: 1.5rem; }
.cloud-event-raw { margin-top: 1rem; }
.cloud-event-raw summary { cursor: pointer; font-size: 0.8rem; color: var(--ballast); }
.cloud-event-raw-pre {
  background: var(--coal);
  padding: 1rem;
  border-radius: var(--radius);
  overflow-x: auto;
  font-size: 0.7rem;
  margin-top: 0.5rem;
  max-height: 400px;
}
.cloud-history-body { padding: 0; }

/* Event history list — name-first row layout that replaces the
   prior 4-column table on the cloud issue detail page. Each event
   reads as: timestamp + environment badge + release SHA on top, with
   the event id as muted secondary mono text beneath. Counter-numbered
   so an operator can refer to "event #3 in the history." */
.cloud-event-list {
  list-style: decimal-leading-zero inside;
  margin: 0;
  padding: 0;
}
.cloud-event-list-item {
  padding: 0.65rem 1rem;
  border-bottom: 1px solid var(--surface-border, #e5e7eb);
}
.cloud-event-list-item:last-child {
  border-bottom: none;
}
.cloud-event-list-primary {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  font-size: 0.85rem;
}
.cloud-event-list-time {
  font-weight: 500;
}
.cloud-event-list-release {
  font-size: 0.75rem;
  color: var(--ballast);
}
.cloud-event-list-secondary {
  margin-top: 0.15rem;
  margin-left: 1.75rem;
  font-size: 0.72rem;
  color: var(--ballast);
}

/* Resolution callout (root_cause / fix_explanation / fix_commit /
   resolved_at) shown when an agent has marked the issue resolved
   via mark_resolved. On regressed issues the same card re-frames as
   the previous fix — see cloudIssueResolutionCard's status switch. */
.cloud-resolution-card .cloud-resolution-hint {
  margin: 0 0 0.75rem;
  padding: 0.5rem 0.75rem;
  background: rgba(245, 158, 11, 0.08);
  border-left: 3px solid var(--amber, #f59e0b);
  border-radius: 4px;
}
.cloud-resolution-block {
  margin-bottom: 0.85rem;
}
.cloud-resolution-block:last-child {
  margin-bottom: 0;
}
.cloud-resolution-label {
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--ballast);
  margin-bottom: 0.2rem;
}
.cloud-resolution-text {
  font-size: 0.9rem;
  line-height: 1.5;
}

/* Local-mode brand suffix to disambiguate from faultline.live (fl-w94). */
.nav-brand-suffix {
  font-size: 0.7rem;
  font-weight: 500;
  margin-left: 0.4rem;
  padding: 0.1rem 0.4rem;
  background: var(--ballast, #6b7280);
  color: white;
  border-radius: 3px;
  vertical-align: middle;
  letter-spacing: 0.5px;
  text-transform: uppercase;
}

/* ── Cloud pages — missing utilities ───────────────────────────── */

/* Section headings on cloud project/settings pages */
.section-title {
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--ballast);
  margin: 1.75rem 0 0.75rem;
}
.section-title:first-child { margin-top: 0; }

/* Sort toggle that lives at the top-right of the timeline section
   (fl-7ww). Small, muted, looks-like-a-link affordance — operators
   triaging an issue glance up-right to flip direction without
   leaving the page. Same shape on both cloud and local renders. */
.detail-section-head,
.section-title-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}
.timeline-sort-toggle {
  font-size: 0.75rem;
  color: var(--ballast);
  text-decoration: none;
  white-space: nowrap;
}
.timeline-sort-toggle:hover {
  color: var(--text-strong, #1f2937);
  text-decoration: underline;
}
.timeline-sort-arrow {
  margin-left: 0.25rem;
  font-weight: 600;
}

/* Breadcrumb text under page title */
.breadcrumb {
  font-size: 0.8rem;
  color: var(--ballast);
  margin-top: 0.2rem;
}
.breadcrumb a { color: var(--ballast); text-decoration: underline dotted; }
.breadcrumb a:hover { color: var(--steel); text-decoration: underline; }

/* Flash / success messages */
.flash {
  padding: 0.625rem 1rem;
  border-radius: var(--radius);
  font-size: 0.85rem;
  margin-bottom: 1rem;
  border-left: 3px solid;
}
.flash-success {
  background: #f0fdf4;
  color: var(--signal-green);
  border-left-color: var(--signal-green);
}
.flash-error {
  background: #fef2f2;
  color: var(--signal-red);
  border-left-color: var(--signal-red);
}
/* Warning flash — amber, matching the stale-banner palette. Used by the
   cloud-origin issue shadow when a live fetch fails and we offer a
   bounce link to faultline.live (a degraded view, not a hard error). */
.flash-warning {
  background: #fff1d6;
  color: #8a5a0c;
  border-left-color: #e5c89a;
}
.flash-warning a { color: #8a5a0c; font-weight: 600; }

/* Cloud-origin issue shadow (fl-x3v8.3): the "Origin: cloud" strip that
   sits under the page header, pairing the label with the shared
   project-origin-cloud badge + optional stale pill. */
.cloud-origin-strip {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 1rem;
}
.cloud-origin-label {
  font-size: 0.8rem;
  color: var(--ballast);
}

/* DSN copy widget */
.dsn-copy {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: var(--sleeper);
  border-radius: var(--radius);
  padding: 0.5rem 0.75rem;
  overflow-x: auto;
}
.dsn-text {
  flex: 1;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: #e2e8f0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.copy-btn {
  flex-shrink: 0;
  background: rgba(255,255,255,0.1);
  color: #e2e8f0;
  border: 1px solid rgba(255,255,255,0.2);
  border-radius: 4px;
  padding: 0.2rem 0.6rem;
  font-size: 0.7rem;
  cursor: pointer;
  font-family: var(--font-sans);
  font-weight: 600;
}
.copy-btn:hover { background: rgba(255,255,255,0.18); }
.copy-btn.copied {
  background: var(--signal-green);
  color: white;
  border-color: var(--signal-green);
}

/* Slack workspace cards on /dashboard/account/slack — reuses
   .project-card scaffolding so connected workspaces read like
   project entities (status bar, emoji-led title, meta row), not
   a plain admin table. */
.slack-workspace-card .card-body { padding: 1rem 1.25rem; }
.slack-workspace-name {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.slack-workspace-emoji {
  font-size: 1.1rem;
  line-height: 1;
}
.slack-workspace-actions {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--coal);
  display: flex;
  justify-content: flex-end;
}
.slack-disconnect-btn {
  color: var(--ballast);
}
.slack-disconnect-btn:hover {
  color: var(--signal-red);
  background: #fef2f2;
}

/* Project notifications table on /dashboard/account/slack — one row
   per project, channel mapping inline, action button on the right.
   Unconfigured rows get muted styling so the eye lands on configured
   (testable) channels first. */
.cloud-slack-mappings {
  width: 100%;
  border-collapse: collapse;
}
.cloud-slack-mappings th {
  text-align: left;
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--ballast);
  font-weight: 600;
  padding: 0.65rem 1rem 0.4rem;
  border-bottom: 1px solid var(--coal);
}
.cloud-slack-mappings td {
  padding: 0.7rem 1rem;
  border-bottom: 1px solid #f5f1ec;
  vertical-align: middle;
  font-size: 0.85rem;
}
.cloud-slack-mappings tr:last-child td { border-bottom: none; }
.cloud-slack-mapping-pending td { color: var(--ballast); }
.cloud-slack-mapping-project {
  color: var(--steel);
  font-weight: 600;
}
.cloud-slack-mapping-pending .cloud-slack-mapping-project {
  color: var(--steel);
  font-weight: 500;
}
.cloud-slack-mapping-channel {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
}
.cloud-slack-mapping-emoji {
  font-size: 0.95rem;
  line-height: 1;
}
.cloud-slack-mapping-empty {
  font-style: italic;
}
.cloud-slack-mapping-action {
  text-align: right;
  white-space: nowrap;
}

/* Project slug line under project name in cards */
.project-slug {
  font-size: 0.75rem;
  color: var(--ballast);
  font-family: var(--font-mono);
  margin-bottom: 0.625rem;
  display: flex;
  align-items: center;
  gap: 0.375rem;
}

/* Account meta DL (name / email / role grid) */
.account-meta {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.5rem 1.25rem;
  font-size: 0.875rem;
  align-items: baseline;
}
.account-meta dt {
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--ballast);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  white-space: nowrap;
}

/* Profile avatar on account settings page */
.account-profile-avatar-row {
  margin-bottom: 1.25rem;
}
.account-profile-avatar {
  width: 64px; height: 64px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--fusee-ember), var(--fusee-ember));
  color: var(--sleeper);
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 1.75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Header action toolbar (Slack link row on projects page) */
.header-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-top: 0.75rem;
}

/* Inline create form (new project) */
.inline-create-form {
  display: flex;
  align-items: flex-end;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.inline-create-form .form-group {
  margin-bottom: 0;
  flex: 1;
  min-width: 180px;
}

/* ── Monitoring-station hero on the project detail page ─────────── */
/* The hero leans hard on typography: a single oversized display name
   carries the page, with an overline slug above and a meta rule-line
   below that packs status/version/platform/deploy into a quiet row
   of mono beats. Vitals below use outsized tabular numbers against
   tiny small-caps labels so the eye goes to the numbers first. */
.station { margin: 1.25rem 0 1rem; }

.station-hero {
  position: relative;
  border-radius: var(--radius);
  background:
    radial-gradient(circle at 10% 120%, rgba(234, 88, 12, 0.12), transparent 55%),
    linear-gradient(120deg, var(--sleeper) 0%, var(--steel) 65%, #263244 100%);
  color: var(--surface);
  padding: 1.1rem 1.5rem 0.9rem;
  /* overflow stays visible so the +Add dropdown can hang below the
     hero. The seismograph trace does its own bottom-corner clipping
     via border-radius on .station-trace. */
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.08), 0 12px 28px -22px rgba(15, 23, 42, 0.55);
}

.station-hero-body {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1.5rem;
  position: relative;
  z-index: 1;
}

.station-hero-lead { min-width: 0; flex: 1; }

/* Overline: tiny, wide-tracked, all-caps. Exists so the headline has
   something to contrast against — the page title then hits harder. */
.station-overline {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  color: rgba(250, 248, 245, 0.5);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin-bottom: 0.45rem;
}
.station-overline a { color: rgba(250, 248, 245, 0.7); text-decoration: none; }
.station-overline a:hover { color: var(--surface); }
.station-overline .crumb-sep { color: rgba(250, 248, 245, 0.28); margin: 0 0.35em; }

.station-title {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  font-size: clamp(1.4rem, 2.4vw, 1.75rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin: 0;
}
.station-name {
  word-break: break-word;
  /* Subtle gradient off the surface color — keeps it legible on the
     obsidian band while giving the title a little shimmer against the
     radial magma accent behind it. */
  background: linear-gradient(180deg, var(--page) 0%, var(--rule) 100%);
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
          color: transparent;
}

/* Meta line: the row of quiet beats beneath the title. Mono + tight. */
.station-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem;
  margin-top: 0.45rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: rgba(250, 248, 245, 0.7);
  letter-spacing: 0.02em;
}
.station-meta-sep {
  color: rgba(250, 248, 245, 0.28);
}
.station-status-label {
  color: var(--surface);
  font-weight: 500;
  font-variant: small-caps;
  letter-spacing: 0.08em;
}
.station-version {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  padding: 0.12rem 0.5rem;
  border: 1px solid rgba(250, 248, 245, 0.18);
  border-radius: 999px;
  color: rgba(250, 248, 245, 0.82);
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.station-platform, .station-deploy { color: rgba(250, 248, 245, 0.78); }

.station-pulse {
  --pulse-color: var(--ballast);
  display: inline-block;
  width: 0.65rem;
  height: 0.65rem;
  border-radius: 999px;
  background: var(--pulse-color);
  box-shadow: 0 0 0 0 var(--pulse-color);
  animation: station-pulse 2.2s infinite cubic-bezier(0.4, 0, 0.6, 1);
  flex-shrink: 0;
  /* The pulse dot sits on the alphabetic baseline of the display type
     — visually it wants to land near the x-height of the first cap. */
  transform: translateY(-0.42em);
}
.station-pulse-healthy { --pulse-color: var(--signal-green); }
.station-pulse-faults  { --pulse-color: var(--signal-red); }
.station-pulse-silent  { --pulse-color: var(--ballast); animation: none; opacity: 0.55; }
.station-pulse-down    { --pulse-color: var(--fusee-ember); }

@keyframes station-pulse {
  0%   { box-shadow: 0 0 0 0 var(--pulse-color); }
  70%  { box-shadow: 0 0 0 0.55rem rgba(0, 0, 0, 0); }
  100% { box-shadow: 0 0 0 0 rgba(0, 0, 0, 0); }
}

/* Description: editorial, a little lighter than body copy, clamped
   so long descriptions don't stretch across the full hero. */
.station-description {
  margin-top: 0.6rem;
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: 0.9rem;
  line-height: 1.5;
  color: rgba(250, 248, 245, 0.8);
  max-width: 60ch;
}

.station-url {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.55rem;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: rgba(250, 248, 245, 0.78);
  text-decoration: none;
  padding: 0.35rem 0.7rem;
  border: 1px solid rgba(250, 248, 245, 0.16);
  border-radius: var(--radius);
  background: rgba(250, 248, 245, 0.04);
  transition: background 0.15s, border-color 0.15s, transform 0.15s;
  max-width: 100%;
  letter-spacing: 0.01em;
}
.station-url:hover {
  background: rgba(250, 248, 245, 0.1);
  border-color: rgba(250, 248, 245, 0.35);
  color: var(--surface);
  text-decoration: none;
  transform: translateX(1px);
}
.station-url-arrow { color: var(--fusee-ember); font-weight: 600; }
.station-url-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Compact URL chips — replaces the big station-url block when a
   project has one or more URLs. Each chip shows a short label
   (local / cloud / site) and the hostname, so a multi-service
   project can surface several endpoints in one row without taking
   over the hero. */
.station-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.55rem;
}
.station-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.2rem 0.55rem 0.2rem 0.35rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: rgba(250, 248, 245, 0.8);
  background: rgba(250, 248, 245, 0.05);
  border: 1px solid rgba(250, 248, 245, 0.18);
  border-radius: 999px;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
  text-decoration: none;
  max-width: 100%;
}
.station-chip:hover {
  background: rgba(250, 248, 245, 0.1);
  border-color: rgba(250, 248, 245, 0.4);
  color: var(--surface);
  text-decoration: none;
}
.station-chip-label {
  font-size: 0.6rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(250, 248, 245, 0.55);
  background: rgba(250, 248, 245, 0.08);
  padding: 0.08rem 0.4rem;
  border-radius: 999px;
}
.station-chip-host {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 28ch;
}
.station-chip-cloud .station-chip-label {
  color: #bfdbfe;
  background: rgba(147, 197, 253, 0.14);
}

/* Dedicated service page — light-theme version of the same chip
   pattern used in the project hero. Reused styles rather than
   re-declaring everything so the two surfaces read as a pair. */
.service-summary {
  display: flex;
  align-items: center;
  background: white;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 0.9rem 1.1rem;
  margin-bottom: 1rem;
}
.service-summary-head {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}
.service-pulse {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--border-input);
  box-shadow: 0 0 0 3px rgba(203, 198, 191, 0.2);
}
.service-pulse-healthy { background: var(--signal-green); box-shadow: 0 0 0 3px rgba(5, 150, 105, 0.18); }
.service-pulse-silent  { background: var(--border-input); }
.service-pulse-down    { background: var(--signal-red); box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.18); }
.service-summary-title { font-size: 0.95rem; color: var(--steel); }
.service-summary-meta  { font-family: var(--font-mono); font-size: 0.75rem; color: var(--ballast); margin-top: 0.15rem; }

.service-block { margin-top: 1.25rem; }
.service-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.3rem;
}
.service-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.25rem 0.6rem 0.25rem 0.4rem;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--steel);
  background: white;
  border: 1px solid var(--rule);
  border-radius: 999px;
  transition: border-color 0.12s, color 0.12s;
  text-decoration: none;
}
.service-chip:hover { border-color: var(--fusee-ember); color: var(--fusee-ember); text-decoration: none; }
.service-chip-label {
  font-size: 0.62rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ballast);
  background: #f4f1ed;
  padding: 0.08rem 0.45rem;
  border-radius: 999px;
}
.service-chip-host {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 32ch;
}
.service-chip-cloud .service-chip-label { color: #1e3a8a; background: #dbeafe; }

.station-hero-actions {
  display: flex;
  gap: 0.5rem;
  align-items: flex-start;
  flex-shrink: 0;
}
.station-action {
  background: rgba(250, 248, 245, 0.08);
  border: 1px solid rgba(250, 248, 245, 0.16);
  color: var(--surface);
  font-size: 0.74rem;
  letter-spacing: 0.04em;
}
.station-action:hover {
  background: rgba(250, 248, 245, 0.18);
  border-color: rgba(250, 248, 245, 0.32);
  text-decoration: none;
}

/* Seismograph trace — subtle horizontal line with a single amplitude
   spike. Pure CSS; evokes the fault metaphor without animating. */
.station-trace {
  position: absolute;
  inset: auto 0 0 0;
  height: 42px;
  pointer-events: none;
  /* Round the bottom corners so the SVG doesn't extend beyond the
     hero's border radius now that the parent no longer clips. */
  border-radius: 0 0 var(--radius) var(--radius);
  overflow: hidden;
  background:
    linear-gradient(to top, rgba(250, 248, 245, 0.04), transparent 80%),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 600 40' preserveAspectRatio='none'><path d='M0 20 L80 20 L100 20 L115 8 L125 33 L135 14 L150 20 L260 20 L275 4 L285 36 L300 20 L460 20 L478 14 L495 26 L510 20 L600 20' fill='none' stroke='%23EA580C' stroke-opacity='0.38' stroke-width='1.25'/></svg>") center/100% 100% no-repeat;
  opacity: 0.9;
}

/* Vitals strip: 4 cells under the hero. Big tabular numbers carry the
   row, small-caps labels sit above like kern marks. The stat is the
   hero of each cell — the label exists only to disambiguate. */
.station-vitals {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 1px;
  background: var(--rule);
  border-radius: var(--radius);
  margin-top: 0.75rem;
  overflow: hidden;
  border: 1px solid var(--rule);
}
.station-vital {
  background: white;
  padding: 0.65rem 0.85rem 0.55rem;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.station-vital dt {
  font-family: var(--font-mono);
  font-size: 0.6rem;
  font-weight: 500;
  color: var(--ballast);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  order: -1;
}
.station-vital-value {
  font-family: var(--font-mono);
  font-size: 1.1rem;
  font-weight: 600;
  line-height: 1.15;
  color: var(--steel);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.station-vital-value.vital-alarm {
  color: var(--signal-red);
  font-weight: 700;
}
.station-vital-value.vital-calm  { color: var(--signal-green); }
.station-vital-value.vital-muted {
  color: var(--ballast);
  font-weight: 400;
  font-size: 0.95rem;
}

/* Tags row: env badges + component (now anchor) + integration chips. */
.station-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.9rem;
  align-items: center;
}
.comp-chip {
  font-size: 0.72rem;
  padding: 0.2rem 0.6rem;
  background: var(--coal);
  color: var(--steel);
  border-radius: 999px;
  letter-spacing: 0.02em;
  font-weight: 500;
  text-decoration: none;
  border: 1px solid transparent;
  transition: background 0.12s, border-color 0.12s;
}
.comp-chip:hover {
  background: #e7e2dc;
  border-color: var(--fusee-ember);
  text-decoration: none;
}
.integ-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.72rem;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  border: 1px solid var(--rule);
  background: white;
  color: var(--steel);
  font-weight: 500;
  letter-spacing: 0.02em;
}
.integ-chip .integ-glyph {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--ballast);
}
.integ-chip .integ-dot {
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--ballast);
  display: inline-block;
}
.integ-cloud-connected   { border-color: rgba(5, 150, 105, 0.25); }
.integ-cloud-connected   .integ-dot { background: var(--signal-green); }
.integ-cloud-degraded    { border-color: rgba(245, 158, 11, 0.3); }
.integ-cloud-degraded    .integ-dot { background: var(--signal-amber); }
.integ-cloud-disconnected{ border-color: rgba(220, 38, 38, 0.3); }
.integ-cloud-disconnected .integ-dot { background: var(--signal-red); }
.integ-webhook .integ-glyph { color: var(--fusee-ember); }
.integ-db      .integ-glyph { color: var(--steel); }

/* ── Systems cards: one per component + pinned Storage ────────────
   Each card is a navigation target: click anywhere to land on a
   page that drills into the system it represents. Small-caps label
   anchors the card semantically (STORAGE / FRONTEND / API); the
   big name carries the visual weight; a meta line pairs counts and
   status; a reason line (only on Storage, for now) surfaces the
   most recent non-ok check message so "degraded" isn't a mystery. */
.systems-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0.5rem;
  margin-top: 0.9rem;
}
.system-card {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.85rem 1rem;
  background: white;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  text-decoration: none;
  color: var(--steel);
  transition: border-color 0.12s, transform 0.12s, box-shadow 0.12s;
}
.system-card:hover {
  text-decoration: none;
  border-color: var(--fusee-ember);
  box-shadow: 0 2px 0 rgba(212, 165, 116, 0.08);
  transform: translateY(-1px);
}
.system-card-label {
  font-family: var(--font-mono);
  font-size: 0.6rem;
  font-weight: 500;
  color: var(--ballast);
  text-transform: uppercase;
  letter-spacing: 0.16em;
}
.system-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-top: 0.1rem;
}
.system-card-name {
  font-size: 1.1rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--steel);
}
.system-card-pulse {
  --pulse-color: var(--ballast);
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 999px;
  background: var(--pulse-color);
  flex-shrink: 0;
}
.system-card-pulse-healthy { --pulse-color: var(--signal-green); }
.system-card-pulse-faults  { --pulse-color: var(--signal-red); }
.system-card-pulse-silent  { --pulse-color: var(--ballast); opacity: 0.55; }
.system-card-pulse-down    { --pulse-color: var(--fusee-ember); }
.system-card-meta {
  font-size: 0.78rem;
  color: var(--ballast);
  font-family: var(--font-mono);
  letter-spacing: 0.01em;
}
.system-card-reason {
  font-size: 0.72rem;
  color: var(--fusee-ember);
  margin-top: 0.15rem;
  font-family: var(--font-mono);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── Env chips: pulse-bearing surface markers ─────────────────────
   One chip per observed environment on the project card + overview
   tags row. The dot inherits the same healthy/silent/down palette
   the station hero and system cards use so "production" reads the
   same way wherever it appears. Chips are anchors — clicking
   filters the project's issue list by that environment. */
.env-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  background: white;
  border: 1px solid var(--rule);
  color: var(--steel);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-decoration: none;
  transition: background 0.12s, border-color 0.12s;
}
.env-chip:hover {
  background: var(--coal);
  border-color: var(--fusee-ember);
  text-decoration: none;
}
.env-chip-dot {
  --dot-color: var(--ballast);
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--dot-color);
  flex-shrink: 0;
}
.env-chip-healthy .env-chip-dot { --dot-color: var(--signal-green); }
.env-chip-faults  .env-chip-dot { --dot-color: var(--signal-red); }
.env-chip-silent  .env-chip-dot { --dot-color: var(--ballast); }
.env-chip-down    .env-chip-dot { --dot-color: var(--fusee-ember); }
.env-chip-name { font-family: var(--font-mono); }

/* ── "+ Add" dropdown in the hero action bar ──────────────────────
   Uses native <details>/<summary> so there's no JS dependency. The
   menu anchors to the <details> so it hangs below-right; the open
   state flips the summary caret subtly. Items are two-line (title
   + hint) to communicate what each add does. */
.station-add { position: relative; }
.station-add > summary {
  list-style: none;
  cursor: pointer;
  user-select: none;
}
.station-add > summary::-webkit-details-marker { display: none; }
.station-add > summary::before {
  content: "";
  display: inline-block;
  width: 0;
  height: 0;
}
.station-add[open] > summary {
  background: rgba(250, 248, 245, 0.18);
  border-color: rgba(250, 248, 245, 0.32);
}
.station-add-menu {
  position: absolute;
  top: calc(100% + 0.35rem);
  right: 0;
  min-width: 240px;
  background: var(--page);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  box-shadow: 0 10px 24px -10px rgba(15, 23, 42, 0.35);
  padding: 0.35rem;
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.station-add-menu a {
  display: flex;
  flex-direction: column;
  gap: 0.05rem;
  padding: 0.55rem 0.7rem;
  color: var(--steel);
  border-radius: 4px;
  text-decoration: none;
  transition: background 0.1s;
}
.station-add-menu a:hover { background: var(--coal); text-decoration: none; }
.station-add-title {
  font-size: 0.88rem;
  font-weight: 600;
  letter-spacing: -0.005em;
}
.station-add-hint {
  font-size: 0.72rem;
  color: var(--ballast);
}

/* ── Recent faults preview on the project overview page ───────── */
.station-recent { margin-top: 1rem; }
.station-recent-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 0.5rem;
}
.station-section-title {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--steel);
  letter-spacing: -0.01em;
}
.station-recent-link {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ballast);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
}
.station-recent-link:hover { color: var(--steel); text-decoration: none; }

.station-recent-empty {
  border: 1px dashed var(--rule);
  border-radius: var(--radius);
  padding: 1rem 1.1rem;
  background: #fafaf9;
  color: var(--ballast);
  font-size: 0.85rem;
}

.station-recent-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  overflow: hidden;
}
.station-recent-issue {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 0.6rem;
  align-items: center;
  padding: 0.55rem 0.85rem;
  background: white;
  color: var(--steel);
  text-decoration: none;
  transition: background 0.1s;
}
.station-recent-issue:hover {
  background: var(--page);
  text-decoration: none;
}
.station-recent-severity {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* fa-rl6: larger recent-faults type + icon (operator request, round 2). */
  font-size: 1.5rem;
  width: 1.7rem;
}
.station-recent-title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 1rem;
  color: var(--steel);
}
.station-recent-meta {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--ballast);
  letter-spacing: 0.01em;
  white-space: nowrap;
}

@media (max-width: 640px) {
  .station-hero { padding: 0.95rem 1.1rem 0.85rem; }
  .station-title { font-size: 1.3rem; letter-spacing: -0.02em; gap: 0.45rem; }
  .station-hero-body { flex-direction: column; }
  .station-hero-actions { margin-top: 0.5rem; }
  .station-trace { height: 32px; }
  .station-vital-value { font-size: 0.95rem; }
  .station-add-menu { right: auto; left: 0; }
}

/* ── Section titles + empty-cell placeholder (service / containers pages) ── */
.gt-section-title {
  margin: 0 0 0.75rem 0;
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--steel);
}

.gt-conn-none {
  color: var(--ballast);
}

.btn-outline {
  background: white;
  border: 1px solid var(--rule);
  color: var(--steel);
}
.btn-outline:hover {
  border-color: var(--fusee-ember);
  color: var(--fusee-ember);
}
.btn-danger-outline {
  background: white;
  border: 1px solid #e5a0a0;
  color: #a33;
}
.btn-danger-outline:hover {
  background: #fdf3f3;
  border-color: #c66;
  color: #8a1c1c;
}
.btn-danger {
  background: #c0392b;
  border: 1px solid #a93226;
  color: white;
}
.btn-danger:hover {
  background: #a93226;
  color: white;
}
.danger-heading {
  color: #8a1c1c;
  margin-top: 0.5rem;
}

/* Settings tabs — horizontal nav at the top of a project's
   settings page. Tabs carry the current tab in the query string
   so reloads + bookmarks land where the operator was. Active tab
   reads as a pressed pill; Danger is tinted red so the click
   cost matches its blast radius. */
.settings-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin: 0.5rem 0 1.25rem;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 0;
}
.settings-tab {
  padding: 0.55rem 0.95rem;
  font-size: 0.88rem;
  color: var(--ballast);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color 0.12s, border-color 0.12s, background 0.12s;
}
.settings-tab:hover {
  color: var(--steel);
  text-decoration: none;
  background: var(--coal);
}
.settings-tab.is-active {
  color: var(--steel);
  border-bottom-color: var(--signal-red);
  font-weight: 600;
}
.settings-tab-danger {
  color: #a33;
  margin-left: auto;
}
.settings-tab-danger:hover {
  color: #8a1c1c;
  background: #fdf3f3;
}
.settings-tab-danger.is-active {
  color: #8a1c1c;
  border-bottom-color: #8a1c1c;
}

/* Alert rule list — compact summary rows with an inline editor
   that expands on click. Disabled rules get a muted treatment so
   the "what's actually firing" subset reads at a glance. */
.alert-rule-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-bottom: 1rem;
}
.alert-rule {
  background: white;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
}
.alert-rule.is-disabled {
  background: var(--page);
  color: var(--ballast);
}
.alert-rule.is-disabled .alert-rule-name {
  color: var(--ballast);
}
.alert-rule > summary {
  list-style: none;
  cursor: pointer;
  padding: 0.6rem 0.9rem;
  display: grid;
  grid-template-columns: minmax(14ch, auto) 1fr auto;
  align-items: center;
  gap: 0.85rem;
}
.alert-rule > summary::-webkit-details-marker { display: none; }
.alert-rule[open] > summary {
  border-bottom: 1px solid var(--coal);
}
.alert-rule-name {
  font-weight: 600;
  color: var(--steel);
}
.alert-rule-meta {
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--ballast);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.alert-rule-actions {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.alert-rule-chevron {
  color: var(--ballast);
  font-size: 0.75rem;
  transition: transform 0.15s;
}
.alert-rule[open] .alert-rule-chevron {
  transform: rotate(180deg);
}
.alert-rule-form {
  padding: 0.9rem 0.9rem 1rem;
  margin: 0;
}
.alert-rule-new {
  margin-top: 0.5rem;
}
.alert-rule-new > summary {
  list-style: none;
  display: inline-block;
}
.alert-rule-new > summary::-webkit-details-marker { display: none; }
.alert-rule-new[open] > summary { margin-bottom: 0.75rem; }
.alert-history-failed { background: #fef0f0; }
.alert-history-failed:hover { background: #fde5e5; }

/* Inline row for the alert-rule entry points so they sit
   side-by-side without forcing operators to scroll. */
.alert-rule-actions-row {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-top: 0.5rem;
}

/* Per-action label text hidden by default; JS picks the matching
   one based on the current action select. Keeps all four labels
   in the markup so templ doesn't have to know about action
   semantics. */
[data-target-label-slack],
[data-target-label-webhook],
[data-target-label-email] {
  display: none;
}

/* Two-column form row for threshold + window — they're a pair,
   shouldn't stack full-width unless the viewport is narrow. */
.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}
@media (max-width: 640px) {
  .form-row { grid-template-columns: 1fr; }
  .alert-rule > summary {
    grid-template-columns: 1fr auto;
  }
  .alert-rule-meta {
    grid-column: 1 / -1;
    white-space: normal;
  }
}

.checkbox-label {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9rem;
  color: var(--steel);
}

/* Slack section on the Integrations tab — dedicated setup flow
   backed by the same webhook_url + webhook_type fields the generic
   notification form uses. We gave it its own visual treatment so
   first-time operators can spot the Slack-specific path without
   learning that "Slack = webhook URL + type dropdown." */
.slack-section {
  padding: 0.25rem 0 0.25rem;
}
.slack-section-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.75rem;
}
.slack-state {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.75rem 1rem;
  background: #f1f9f5;
  border: 1px solid #c9e6d7;
  border-radius: var(--radius);
}
.slack-state-url {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--steel);
}
.slack-state-url .form-sublabel {
  display: block;
  font-size: 0.6rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ballast);
  margin-bottom: 0.15rem;
}
.slack-state-actions { margin: 0; }
.slack-connect-form { margin-top: 0.25rem; }
.slack-advanced {
  margin-top: 0.9rem;
  padding: 0.65rem 0.9rem;
  background: #fafaf8;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
}
.slack-advanced > summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--steel);
  font-size: 0.88rem;
}

/* Activate page — faultline.live project picker. Each row is a
   form so clicking Claim submits just that DSN. Kept as a list
   rather than a table so the rows breathe + the claim button
   stays aligned right. */
.activate-cloud-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin: 0.5rem 0;
}
.activate-cloud-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.55rem 0.85rem;
  background: white;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  margin: 0;
}
.activate-cloud-row:hover {
  border-color: var(--fusee-ember);
}
.activate-cloud-identity {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}
.activate-cloud-name {
  font-weight: 600;
  color: var(--steel);
}
.activate-cloud-slug {
  font-size: 0.72rem;
  color: var(--ballast);
}
.activate-cloud-slug code {
  font-family: var(--font-mono);
  background: transparent;
  padding: 0;
}
.activate-cloud-row-claimed {
  background: var(--page);
  border-style: dashed;
}
.activate-cloud-row-claimed:hover {
  border-color: var(--rule);
}
.activate-cloud-claimed {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.1rem;
  font-size: 0.8rem;
}
.activate-cloud-claimed-label {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ballast);
}
.activate-cloud-claimed a {
  color: var(--steel);
  text-decoration: none;
  font-weight: 600;
}
.activate-cloud-claimed a:hover {
  color: var(--fusee-ember);
}

/* Admin shell — two-column layout wrapping the admin/settings
   pages (Admin overview, Teams, System, Accounts, Profile, Slack).
   The rail is sticky on desktop so the section nav stays in view
   while the operator scrolls; on mobile it collapses into a bar
   that expands to reveal the same links. Everything else on the
   site keeps its full width — only admin surfaces pay the rail
   cost. */
.admin-shell {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 1.5rem;
  margin-top: 0.5rem;
  align-items: start;
}
.admin-rail {
  position: sticky;
  top: 4.25rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 0.9rem 0.75rem 0.9rem 0;
  border-right: 1px solid var(--rule);
  align-self: stretch;
}
.admin-rail-group {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.admin-rail-label {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ballast);
  padding: 0.25rem 0.6rem 0.35rem;
}
.admin-rail-link {
  display: block;
  padding: 0.4rem 0.6rem;
  border-radius: var(--radius);
  font-size: 0.88rem;
  color: var(--steel);
  border-left: 2px solid transparent;
  transition: background 0.1s, border-color 0.1s;
}
.admin-rail-link:hover {
  background: #f4f1ed;
  text-decoration: none;
}
.admin-rail-link.is-active {
  background: var(--coal);
  border-left-color: var(--signal-red);
  font-weight: 600;
}
.admin-content { min-width: 0; }

/* Mobile rail — collapse to a one-line bar that toggles the
   group open. Checkbox-hack mirrors the hamburger pattern so the
   whole thing stays JS-free. */
.admin-rail-toggle { display: none; }
.admin-rail-bar { display: none; }

@media (max-width: 768px) {
  .admin-shell {
    grid-template-columns: 1fr;
    gap: 0.75rem;
  }
  .admin-rail-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.6rem 0.85rem;
    background: white;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    font-size: 0.88rem;
    color: var(--steel);
    cursor: pointer;
    user-select: none;
  }
  .admin-rail-bar-caret {
    font-size: 0.7rem;
    color: var(--ballast);
    transition: transform 0.15s;
  }
  .admin-rail-toggle:checked ~ .admin-rail-bar .admin-rail-bar-caret {
    transform: rotate(180deg);
  }
  .admin-rail {
    display: none;
    position: static;
    border-right: none;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    padding: 0.75rem;
    background: white;
  }
  .admin-rail-toggle:checked ~ .admin-rail { display: flex; }
}

/* Admin overview — destination tiles on /dashboard/admin. One
   row per surface with the title on the left, a compact count /
   status pill on the right, and a one-line description below. */
.admin-index-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 0.75rem;
  margin-top: 0.75rem;
}
.admin-index-card {
  display: block;
  padding: 0.85rem 1rem 0.95rem;
  background: white;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  color: var(--steel);
  transition: border-color 0.12s, box-shadow 0.12s;
}
.admin-index-card:hover {
  border-color: var(--fusee-ember);
  box-shadow: 0 2px 0 rgba(212, 165, 116, 0.08);
  text-decoration: none;
}
.admin-index-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
}
.admin-index-card-title {
  font-size: 1rem;
  font-weight: 600;
}
.admin-index-card-stat {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--ballast);
  background: var(--coal);
  border: 1px solid var(--rule);
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
  text-transform: lowercase;
}
.admin-index-card-desc {
  font-size: 0.82rem;
  color: var(--ballast);
  margin-top: 0.35rem;
  line-height: 1.45;
}

.nav-account-admin {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.nav-account-admin-arrow {
  color: var(--ballast);
  font-size: 0.85rem;
}

/* Fleet strip — one-line health rollup at the top of the
   dashboard. Three counter pills that mirror the card status
   colors so the strip and the grid speak the same visual language. */
.fleet-strip {
  display: flex;
  gap: 0.85rem;
  align-items: center;
  padding: 0.85rem 1rem;
  background: white;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  margin: 0.5rem 0 1rem;
  flex-wrap: wrap;
}
.fleet-stat {
  display: inline-flex;
  align-items: baseline;
  gap: 0.45rem;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--ballast);
  letter-spacing: 0.02em;
}
.fleet-stat-num {
  font-size: 1.35rem;
  font-weight: 700;
  color: var(--steel);
  font-family: var(--font-sans);
  letter-spacing: -0.01em;
  line-height: 1;
}
.fleet-stat-label {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.68rem;
}
.fleet-stat-sub {
  font-size: 0.7rem;
  color: var(--signal-red);
  margin-left: 0.15rem;
}
.fleet-stat-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  align-self: center;
  display: inline-block;
}
.fleet-stat-healthy .fleet-stat-dot  { background: var(--signal-green); }
.fleet-stat-faults .fleet-stat-dot   { background: var(--signal-red); }
.fleet-stat-silent .fleet-stat-dot   { background: var(--border-input); }

.fleet-allclear {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 0.9rem;
  background: #f1f9f5;
  border: 1px solid #c9e6d7;
  border-radius: var(--radius);
  margin-bottom: 1rem;
  color: #115e3f;
  font-size: 0.85rem;
}
.fleet-allclear-icon { color: var(--signal-green); font-size: 0.7rem; }

/* Needs attention — cross-project list of unresolved / regressed
   issues, newest first. One click per row lands straight on the
   issue detail page so the index stays a dispatch surface rather
   than a read-only summary. */
.attention {
  margin-bottom: 1.25rem;
}
.section-heading {
  display: flex;
  align-items: baseline;
  gap: 0.55rem;
  margin: 0 0 0.55rem 0;
  font-size: 0.95rem;
  color: var(--steel);
}
.section-heading-count {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ballast);
  background: var(--coal);
  padding: 0.05rem 0.5rem;
  border-radius: 999px;
}
.section-heading-muted {
  color: var(--ballast);
  font-weight: 500;
  margin-top: 0.5rem;
}
.attention-list {
  display: flex;
  flex-direction: column;
  background: white;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  overflow: hidden;
}
.attention-row {
  display: grid;
  grid-template-columns: 28px 1fr auto auto;
  align-items: center;
  gap: 0.85rem;
  padding: 0.65rem 0.9rem;
  border-top: 1px solid var(--coal);
  color: var(--steel);
  transition: background 0.1s;
}
.attention-row:first-child { border-top: none; }
.attention-row:hover {
  background: var(--page);
  text-decoration: none;
}
.attention-level {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 22px;
  border-radius: 50%;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.78rem;
}
.attention-level-error { background: #fef0f0; color: var(--signal-red); }
.attention-level-warn  { background: #fef5e1; color: var(--signal-amber); }
.attention-level-muted { background: var(--coal); color: var(--ballast); }
.attention-title {
  font-size: 0.9rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.attention-project {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: lowercase;
  color: var(--ballast);
  padding: 0.15rem 0.55rem;
  border: 1px solid var(--rule);
  border-radius: 999px;
  white-space: nowrap;
}
.attention-meta {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ballast);
  white-space: nowrap;
}
.attention-tag {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 0.08rem 0.42rem;
  border-radius: 999px;
  border: 1px solid transparent;
}
.attention-tag-regressed { background: #fef0f0; color: var(--signal-red); border-color: #f2c7c7; }
.attention-count { color: var(--steel); opacity: 0.6; }

.projects-section { margin-top: 1.5rem; }

@media (max-width: 640px) {
  .attention-row {
    grid-template-columns: 22px 1fr;
    grid-template-rows: auto auto;
    gap: 0.45rem 0.65rem;
    padding: 0.75rem 0.8rem;
  }
  .attention-project {
    grid-column: 2; grid-row: 2;
    justify-self: start;
  }
  .attention-meta {
    grid-column: 1 / -1; grid-row: 3;
  }
}

/* Silent projects — had activity once, gone quiet, no health
   probe running. Shares the dashed-border card pattern with
   pending-card but in a grey register rather than amber, because
   "maybe dead" is a different concern from "not yet activated." */
.silent-projects {
  margin-top: 2rem;
  padding-top: 1.25rem;
  border-top: 1px dashed var(--rule);
}
.silent-heading {
  margin: 0 0 0.35rem 0;
  font-size: 0.95rem;
  color: var(--steel);
}
.silent-card {
  display: block;
  background: var(--coal);
  border: 1px dashed var(--border-input);
  border-radius: var(--radius);
  padding: 0.75rem 0.9rem;
  text-decoration: none;
  color: var(--steel);
  transition: border-color 0.12s, background 0.12s;
}
.silent-card:hover {
  border-color: var(--ballast);
  background: #ebe9e4;
  text-decoration: none;
}
.silent-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}
.silent-card-name {
  font-weight: 600;
  font-size: 1rem;
}
.silent-card-badge {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ballast);
  background: white;
  border: 1px solid var(--border-input);
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
}
.silent-card-desc {
  font-size: 0.8rem;
  color: var(--ballast);
  margin-top: 0.25rem;
}
.silent-card-action {
  margin-top: 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ballast);
}

/* Pending projects — freshly created, no events yet. Separate
   section below the active grid so operators can see what still
   needs wiring without the empty cards polluting the main view. */
.pending-projects {
  margin-top: 2rem;
  padding-top: 1.25rem;
  border-top: 1px dashed var(--rule);
}
.pending-heading {
  margin: 0 0 0.35rem 0;
  font-size: 0.95rem;
  color: var(--steel);
}
.pending-hint {
  margin: 0 0 0.75rem 0;
  font-size: 0.85rem;
  color: var(--ballast);
  max-width: 70ch;
}
.pending-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 0.6rem;
}
.pending-card {
  display: block;
  background: #fffbf5;
  border: 1px dashed #e5c89a;
  border-radius: var(--radius);
  padding: 0.75rem 0.9rem;
  text-decoration: none;
  color: var(--steel);
  transition: border-color 0.12s, background 0.12s;
}
.pending-card:hover {
  border-color: var(--fusee-ember);
  background: #fff6e8;
  text-decoration: none;
}
.pending-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}
.pending-card-name {
  font-weight: 600;
  font-size: 1rem;
}
.pending-card-badge {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #a37500;
  background: #fff1d6;
  border: 1px solid #e5c89a;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
}
.pending-card-desc {
  font-size: 0.8rem;
  color: var(--ballast);
  margin-top: 0.25rem;
}
.pending-card-action {
  margin-top: 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ballast);
}

/* Cloud-shadow section on the dashboard index. Mirrors the silent /
   pending visual vocabulary (dashed border, compact card-row) but
   tinted blue-grey instead of amber to read as "different origin"
   at a glance, not "needs attention." Operator clicks a card and
   opens that project on faultline.live in a new tab — local doesn't
   render cloud-only detail pages yet. */
.cloud-card {
  background: #f4f8fb;
  border: 1px dashed #b8c9d6;
}
.cloud-card:hover {
  border-color: #93afc1;
  background: #eaf2f8;
}
.cloud-card .pending-card-badge {
  color: #34607d;
  background: #dcebf3;
  border-color: #b8c9d6;
}
.project-origin-badge {
  display: inline-block;
  margin-left: 0.6rem;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  vertical-align: middle;
}
.project-origin-local {
  color: var(--ballast);
  background: #f0eee9;
  border: 1px solid #d8d3c5;
}
.project-origin-cloud {
  color: #34607d;
  background: #dcebf3;
  border: 1px solid #b8c9d6;
}
.project-origin-banner {
  display: inline-block;
  margin-left: 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  vertical-align: middle;
}
.project-origin-stale {
  color: #8a5a0c;
  background: #fff1d6;
  border: 1px solid #e5c89a;
}

/* LLM setup prompt — copy-pasteable block the operator hands to a
   coding assistant. pre tag keeps newlines intact; the button is
   absolutely positioned top-right so the prompt body stays
   full-width. */
.llm-prompt {
  position: relative;
  margin-top: 0.5rem;
}
.llm-prompt-body {
  background: #1f1b17;
  color: #f5ecd9;
  border: 1px solid #2d2823;
  border-radius: var(--radius);
  padding: 1rem 1.1rem;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
  max-width: 100%;
  margin: 0;
}
.llm-prompt-copy {
  position: absolute;
  top: 0.55rem;
  right: 0.55rem;
}
.llm-prompt-details {
  margin-top: 0.75rem;
  padding: 0.75rem 0.9rem;
  background: #fafaf8;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
}
.llm-prompt-details > summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--steel);
  font-size: 0.9rem;
}
.llm-prompt-details[open] > summary {
  margin-bottom: 0.5rem;
}
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0);
  white-space: nowrap; border: 0;
}

/* ─── Landing page (light mode) ────────────────────────────────────────── */
.landing-body {
  background: #ffffff;
  color: #0f172a;
  display: block;
}

/* Nav */
.landing-hero {
  background: #ffffff;
  border-bottom: 1px solid #e2e8f0;
}
.landing-nav {
  max-width: 1200px;
  margin: 0 auto;
  padding: 1.25rem 2rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.landing-wordmark {
  font-family: var(--font-mono);
  font-size: 1.2rem;
  font-weight: 700;
  color: #0f172a;
  text-decoration: none;
  letter-spacing: -0.5px;
}
.landing-wordmark-sm { font-size: 0.95rem; }
/* Drawer holds MCP / GitHub / Docs / Sign in. On desktop it's an
   inline horizontal row (the original .landing-nav-links shape).
   On mobile it collapses behind a CSS-only burger toggle defined
   below. The "Get started" CTA stays outside the drawer so the
   primary conversion action remains visible at all widths. */
.landing-nav-drawer {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  flex: 1;
  justify-content: flex-end;
}
.landing-nav-drawer a {
  color: #475569;
  text-decoration: none;
  font-size: 0.9rem;
  transition: color 0.15s;
}
.landing-nav-drawer a:hover { color: #0f172a; text-decoration: none; }
.landing-nav-signin {
  color: #475569 !important;
}
.landing-nav-cta {
  background: var(--fusee-ember);
  color: #fff !important;
  padding: 0.45rem 1rem;
  border-radius: var(--radius);
  font-weight: 600;
  font-size: 0.875rem;
  margin-left: 1.25rem;
  white-space: nowrap;
}
.landing-nav-cta:hover { background: var(--fusee-ember); }
/* Burger checkbox — hidden visually but drives the drawer's
   open/closed state via :checked + sibling combinator. Hidden by
   default; the mobile media query below shows it. */
.landing-nav-toggle {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.landing-nav-burger {
  display: none;
  width: 32px;
  height: 32px;
  cursor: pointer;
  position: relative;
  padding: 0;
}
.landing-nav-burger span {
  display: block;
  position: absolute;
  left: 6px;
  right: 6px;
  height: 2px;
  background: #0f172a;
  border-radius: 1px;
  transition: transform 0.2s, opacity 0.2s, top 0.2s;
}
.landing-nav-burger span:nth-child(1) { top: 9px; }
.landing-nav-burger span:nth-child(2) { top: 15px; }
.landing-nav-burger span:nth-child(3) { top: 21px; }
/* Burger → X transition when the drawer is open. The middle bar
   fades out; the outer two cross. */
.landing-nav-toggle:checked ~ .landing-nav-burger span:nth-child(1) {
  top: 15px;
  transform: rotate(45deg);
}
.landing-nav-toggle:checked ~ .landing-nav-burger span:nth-child(2) {
  opacity: 0;
}
.landing-nav-toggle:checked ~ .landing-nav-burger span:nth-child(3) {
  top: 15px;
  transform: rotate(-45deg);
}
@media (max-width: 768px) {
  .landing-nav {
    padding: 1rem 1.25rem;
    flex-wrap: wrap;
  }
  .landing-nav-burger {
    display: block;
    order: 3;
    margin-left: auto;
  }
  .landing-nav-cta {
    order: 2;
    margin-left: auto;
    padding: 0.4rem 0.85rem;
    font-size: 0.825rem;
  }
  /* Drawer collapses to full-width below the nav row. The
     :checked combinator on the toggle expands it. Animation keeps
     it from snapping in/out abruptly. */
  .landing-nav-drawer {
    order: 4;
    flex-basis: 100%;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: 0;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.25s ease, margin-top 0.25s ease;
    margin-top: 0;
  }
  .landing-nav-toggle:checked ~ .landing-nav-drawer {
    max-height: 360px;
    margin-top: 0.85rem;
    border-top: 1px solid #e2e8f0;
    padding-top: 0.5rem;
  }
  .landing-nav-drawer a {
    padding: 0.65rem 0.25rem;
    border-bottom: 1px solid #f1f5f9;
    font-size: 0.95rem;
  }
  .landing-nav-drawer a:last-child { border-bottom: none; }
  /* Reduce hero padding so the headline doesn't dominate the
     viewport on phone screens. */
  .landing-hero-content {
    padding: 3rem 1.25rem 2.5rem;
  }
  .landing-container {
    padding: 0 1.25rem;
  }
  .landing-section {
    padding: 3rem 0;
  }
  .landing-ctas {
    gap: 0.75rem;
  }
  .landing-cta-primary {
    width: 100%;
    text-align: center;
  }
  .landing-cta-secondary {
    width: 100%;
    text-align: center;
  }
  .landing-footer-inner {
    flex-direction: column;
    gap: 1rem;
    align-items: flex-start;
  }
  .landing-footer-nav {
    flex-wrap: wrap;
    gap: 1rem;
  }
}

/* Hero */
.landing-hero-content {
  max-width: 1200px;
  margin: 0 auto;
  padding: 5rem 2rem 4rem;
}
.landing-badge {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--signal-green);
  background: #ecfdf5;
  border: 1px solid #a7f3d0;
  border-radius: 3px;
  padding: 0.25rem 0.6rem;
  margin-bottom: 1.5rem;
}
.landing-headline {
  font-size: clamp(2.5rem, 6vw, 4.5rem);
  font-weight: 800;
  line-height: 1.08;
  color: #0f172a;
  letter-spacing: -1.5px;
  margin-bottom: 1.5rem;
}
.landing-sub {
  font-size: 1.125rem;
  color: #475569;
  line-height: 1.7;
  max-width: 540px;
  margin-bottom: 2.5rem;
}
.landing-ctas {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  align-items: center;
}
.landing-cta-primary {
  background: var(--fusee-ember);
  color: #fff;
  padding: 0.75rem 1.75rem;
  border-radius: var(--radius);
  font-weight: 700;
  font-size: 0.95rem;
  text-decoration: none;
  transition: background 0.15s;
}
.landing-cta-primary:hover { background: #9A4725; text-decoration: none; }
.landing-cta-secondary {
  color: #475569;
  font-size: 0.95rem;
  text-decoration: none;
  transition: color 0.15s;
}
.landing-cta-secondary:hover { color: #0f172a; text-decoration: none; }

/* Seismograph separator */
.landing-track {
  width: 100%;
  overflow: hidden;
  line-height: 0;
  margin-top: 2rem;
}
.landing-track svg {
  width: 100%;
  height: 56px;
  display: block;
}

/* Sections */
.landing-section {
  padding: 5rem 0;
  background: #f8fafc;
}
.landing-dark-section {
  background: #ffffff;
}
.landing-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 2rem;
}
.landing-section-title {
  font-size: clamp(1.5rem, 3vw, 2.25rem);
  font-weight: 700;
  color: #0f172a;
  letter-spacing: -0.5px;
  margin-bottom: 0.75rem;
}
.landing-section-sub {
  color: #475569;
  font-size: 1.05rem;
  margin-bottom: 2.5rem;
}
.landing-center { text-align: center; }

/* Feature cards */
.landing-features {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.5rem;
}
.landing-feature-card {
  background: #ffffff;
  border: 1px solid #e2e8f0;
  border-radius: calc(var(--radius) * 2);
  padding: 1.75rem;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}
.landing-feature-icon {
  width: 40px;
  height: 40px;
  background: #FBF0EA;
  border-radius: var(--radius);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 1rem;
  color: var(--fusee-ember);
}
.landing-feature-card h3 {
  font-size: 1rem;
  font-weight: 700;
  color: #0f172a;
  margin-bottom: 0.5rem;
}
.landing-feature-card p {
  font-size: 0.9rem;
  color: #475569;
  line-height: 1.65;
}

/* The loop — split layout */
.landing-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4rem;
  align-items: start;
}
@media (max-width: 768px) {
  .landing-split { grid-template-columns: 1fr; gap: 2.5rem; }
}
.landing-steps {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  margin-top: 1.5rem;
}
.landing-steps li {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
}
.step-num {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--signal-red);
  background: #fef2f2;
  border: 1px solid #fecaca;
  border-radius: 3px;
  padding: 0.2rem 0.4rem;
  flex-shrink: 0;
  margin-top: 0.15rem;
}
.landing-steps li > div {
  font-size: 0.9rem;
  color: #475569;
  line-height: 1.5;
}
.landing-steps li strong { color: #0f172a; }

/* Code blocks */
.landing-code-block {
  background: #020617;
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: calc(var(--radius) * 1.5);
  overflow: hidden;
}
.landing-code-header {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.65rem 1rem;
  background: rgba(255,255,255,0.04);
  border-bottom: 1px solid rgba(255,255,255,0.06);
}
.landing-code-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}
.landing-code-title {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: #64748b;
  margin-left: 0.4rem;
}
.landing-code {
  padding: 1.25rem 1.25rem;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  line-height: 1.7;
  color: #e2e8f0;
  overflow-x: auto;
}
.lc-kw { color: #c084fc; }
.lc-str { color: #86efac; }
.lc-num { color: #fbbf24; }
.lc-cmt { color: #475569; }

/* Stack grid */
.landing-stack-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1px;
  background: #e2e8f0;
  border: 1px solid #e2e8f0;
  border-radius: calc(var(--radius) * 2);
  overflow: hidden;
}
.landing-stack-item {
  background: #ffffff;
  padding: 1.25rem 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.landing-stack-label {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: #94a3b8;
}
.landing-stack-value {
  font-size: 0.875rem;
  color: #1e293b;
  font-weight: 500;
}

/* Inline help dropdowns inside settings-card sections. Used by
   the Sentry-pull / GitHub / future-integration sections to embed
   step-by-step setup instructions next to the form so operators
   don't have to context-switch to docs. */
.settings-help {
  margin: 0.75rem 0 1rem;
  border: 1px solid #e2e8f0;
  border-radius: var(--radius);
  background: #f8fafc;
  padding: 0.75rem 1rem;
}
.settings-help summary {
  cursor: pointer;
  font-size: 0.9rem;
  font-weight: 600;
  color: #0f172a;
  padding: 0.25rem 0;
}
.settings-help summary:hover {
  color: var(--signal-red);
}
.settings-help[open] summary {
  margin-bottom: 0.5rem;
}
.settings-help ol,
.settings-help p {
  margin: 0.5rem 0;
}
.settings-help ol {
  padding-left: 1.5rem;
}
.settings-help li {
  margin-bottom: 0.25rem;
  font-size: 0.875rem;
  line-height: 1.55;
}

/* MCP download grid */
.mcp-download-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0.75rem;
  margin-top: 1rem;
}
.mcp-download-card {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 1rem 1.25rem;
  background: #ffffff;
  border: 1px solid #e2e8f0;
  border-radius: var(--radius);
  text-decoration: none;
  transition: border-color 0.15s, transform 0.15s;
}
.mcp-download-card:hover {
  border-color: var(--signal-red);
  text-decoration: none;
  transform: translateY(-1px);
}
.mcp-download-label {
  font-size: 0.95rem;
  font-weight: 600;
  color: #0f172a;
}
.mcp-download-slug {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: #64748b;
}

/* /mcp hero: centered headline + endpoint URL with a copy button */
.landing-center .landing-sub { margin-left: auto; margin-right: auto; }
.landing-center .landing-ctas { justify-content: center; }
.landing-accent {
  text-decoration: underline;
  text-decoration-color: var(--fusee-ember);
  text-decoration-thickness: 0.12em;
  text-underline-offset: 0.14em;
  text-decoration-skip-ink: none;
}
.mcp-url-field {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  max-width: 640px;
  margin: 0 auto 1rem;
  padding: 0.5rem 0.5rem 0.5rem 1.25rem;
  background: #020617;
  border: 1px solid #1e293b;
  border-radius: calc(var(--radius) * 1.5);
}
.mcp-url-field code {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: left;
  font-family: var(--font-mono);
  font-size: 0.95rem;
  color: #e2e8f0;
}
.mcp-url-copy {
  flex-shrink: 0;
  background: var(--signal-red);
  color: #fff;
  border: 0;
  border-radius: var(--radius);
  padding: 0.7rem 1.25rem;
  font: inherit;
  font-weight: 700;
  font-size: 0.95rem;
  cursor: pointer;
  transition: background 0.15s;
}
.mcp-url-copy:hover { background: #b91c1c; }
.mcp-url-hint { max-width: 640px; margin: 0 auto 2rem; }
@media (max-width: 480px) {
  .mcp-url-field code { font-size: 0.82rem; }
}

/* MCP tools list (item 4 on /mcp page) */
.landing-tools {
  list-style: none;
  padding: 0;
  margin: 1rem 0 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.landing-tools li {
  font-size: 0.95rem;
  color: #475569;
  padding-left: 1rem;
  border-left: 2px solid #e2e8f0;
}
.landing-tools li strong {
  font-family: var(--font-mono);
  color: var(--fusee-ember);
  margin-right: 0.5rem;
}

/* Two-path comparison cards on the home page */
.landing-paths {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
  margin-top: 1rem;
}
@media (max-width: 768px) {
  .landing-paths { grid-template-columns: 1fr; }
}
.landing-path-card {
  background: #ffffff;
  border: 1px solid #e2e8f0;
  border-radius: calc(var(--radius) * 2);
  padding: 1.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}
.landing-path-card h3 {
  font-size: 1.1rem;
  font-weight: 700;
  color: #0f172a;
  margin: 0;
}
.landing-path-card .landing-path-tag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--fusee-ember);
  background: #FBF0EA;
  border: 1px solid #EFD3C5;
  border-radius: 3px;
  padding: 0.2rem 0.5rem;
  align-self: flex-start;
}
.landing-path-card p {
  color: #475569;
  font-size: 0.95rem;
  line-height: 1.6;
  margin: 0;
}
.landing-path-card ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}
.landing-path-card ul li {
  font-size: 0.9rem;
  color: #475569;
  padding-left: 1.1rem;
  position: relative;
}
.landing-path-card ul li::before {
  content: "→";
  position: absolute;
  left: 0;
  color: var(--fusee-ember);
  font-weight: 700;
}
.landing-path-card .landing-path-cta {
  margin-top: auto;
  padding-top: 0.75rem;
}

/* CTA band */
.landing-cta-band {
  background: var(--fusee-ember);
  padding: 4rem 0;
}
.landing-cta-band-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  flex-wrap: wrap;
}
.landing-cta-band h2 {
  font-size: 1.75rem;
  font-weight: 800;
  color: #fff;
  letter-spacing: -0.5px;
}
.landing-cta-band p {
  color: rgba(255,255,255,0.75);
  margin-top: 0.35rem;
}
.landing-cta-band .landing-cta-primary {
  background: #fff;
  color: var(--fusee-ember);
}
.landing-cta-band .landing-cta-primary:hover { background: #f1f5f9; }
.landing-cta-band .landing-cta-secondary { color: rgba(255,255,255,0.8); }
.landing-cta-band .landing-cta-secondary:hover { color: #fff; }

/* Footer */
.landing-footer {
  background: #f8fafc;
  padding: 2rem 0;
  border-top: 1px solid #e2e8f0;
}
.landing-footer-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
}
.landing-footer-nav {
  display: flex;
  gap: 1.5rem;
  flex-wrap: wrap;
}
.landing-footer-nav a {
  font-size: 0.85rem;
  color: #64748b;
  text-decoration: none;
}
.landing-footer-nav a:hover { color: #0f172a; text-decoration: none; }
.landing-footer-copy {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: #94a3b8;
}

/* ─── Mobile rules: cloud project detail page ─────────────────────
   Below 720px the page-header buttons (Webhooks /
   Settings) drop under the title; the info-strip chips collapse to
   one chip per row; the issues + recent-events tables become
   horizontally scrollable so columns don't truncate or wrap into
   each other. */
@media (max-width: 720px) {
  .page-header-row {
    flex-direction: column;
    align-items: stretch;
  }
  .page-header-row .action-buttons {
    justify-content: flex-start;
  }
  .cloud-detail-strip {
    flex-direction: column;
    gap: 0.5rem;
  }
  .cloud-strip-chip {
    flex: 1 1 auto;
    width: 100%;
  }
  /* Tables wrap their parent .card so we let the card scroll
     horizontally rather than break each column individually. */
  .card.section-card,
  .cloud-events-card {
    overflow-x: auto;
  }
  .data-table,
  .cloud-events-table {
    min-width: 540px;
  }
  /* Stat cards need a smaller minmax so 2-up fits a phone screen. */
  .cloud-stat-cards {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 0.5rem;
  }
  /* Allow long event messages to wrap on mobile rather than being
     ellipsis-cut at a fixed 360px — vertical space is cheap on a
     phone, horizontal is not. */
  .cloud-event-message {
    white-space: normal;
    max-width: none;
  }
}

/* Webhooks list (fl-4t10) — name-first row layout + collapsed add form. */
.webhook-row-name {
  font-weight: 500;
  text-decoration: none;
}
.webhook-row-name:hover {
  text-decoration: underline;
}
.webhook-row-url {
  margin-top: 0.15rem;
  font-size: 0.78rem;
  color: var(--ballast);
  word-break: break-all;
}
/* Make <details> summary read like a primary action button. The
   default disclosure triangle is suppressed so the summary visually
   matches other .btn-primary elements; the <details> container
   handles the actual show/hide. Card chrome wraps the open form
   so it inherits section-card padding once expanded. */
details.webhook-add-toggle {
  margin-top: 0.75rem;
  background: transparent;
  border: none;
  padding: 0;
  box-shadow: none;
}
details.webhook-add-toggle > summary.webhook-add-summary {
  list-style: none;
  display: inline-flex;
  align-items: center;
  cursor: pointer;
}
details.webhook-add-toggle > summary.webhook-add-summary::-webkit-details-marker {
  display: none;
}
details.webhook-add-toggle[open] > .card-body {
  margin-top: 0.75rem;
  background: white;
  border: 1px solid var(--surface-border, #e5e7eb);
  border-radius: var(--radius, 6px);
  padding: 1.25rem;
}

/* === fa-cg8 / icon set: monochrome SVG icons rendered via CSS mask so they
   inherit the surrounding text color (currentColor), preserving faultline's
   per-context color-coding. Each .ui-icon[data-icon="name"] points its mask
   at /static/icons/<name>.svg. Rules generated from the icon set. === */
.ui-icon{display:inline-block;width:1em;height:1em;vertical-align:-0.125em;background-color:currentColor;-webkit-mask-size:contain;mask-size:contain;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center}
.ui-icon[data-icon="007-check"]{-webkit-mask-image:url(/static/icons/007-check.svg);mask-image:url(/static/icons/007-check.svg)}
.ui-icon[data-icon="014-pause"]{-webkit-mask-image:url(/static/icons/014-pause.svg);mask-image:url(/static/icons/014-pause.svg)}
.ui-icon[data-icon="015-snowflake"]{-webkit-mask-image:url(/static/icons/015-snowflake.svg);mask-image:url(/static/icons/015-snowflake.svg)}
.ui-icon[data-icon="017-lightning-1"]{-webkit-mask-image:url(/static/icons/017-lightning-1.svg);mask-image:url(/static/icons/017-lightning-1.svg)}
.ui-icon[data-icon="021-laptop"]{-webkit-mask-image:url(/static/icons/021-laptop.svg);mask-image:url(/static/icons/021-laptop.svg)}
.ui-icon[data-icon="025-check-1"]{-webkit-mask-image:url(/static/icons/025-check-1.svg);mask-image:url(/static/icons/025-check-1.svg)}
.ui-icon[data-icon="026-up-arrow-1"]{-webkit-mask-image:url(/static/icons/026-up-arrow-1.svg);mask-image:url(/static/icons/026-up-arrow-1.svg)}
.ui-icon[data-icon="029-alert"]{-webkit-mask-image:url(/static/icons/029-alert.svg);mask-image:url(/static/icons/029-alert.svg)}
.ui-icon[data-icon="034-monitor-1"]{-webkit-mask-image:url(/static/icons/034-monitor-1.svg);mask-image:url(/static/icons/034-monitor-1.svg)}
.ui-icon[data-icon="037-security"]{-webkit-mask-image:url(/static/icons/037-security.svg);mask-image:url(/static/icons/037-security.svg)}
.ui-icon[data-icon="052-hourglass-1"]{-webkit-mask-image:url(/static/icons/052-hourglass-1.svg);mask-image:url(/static/icons/052-hourglass-1.svg)}
.ui-icon[data-icon="alarm"]{-webkit-mask-image:url(/static/icons/alarm.svg);mask-image:url(/static/icons/alarm.svg)}
.ui-icon[data-icon="check"]{-webkit-mask-image:url(/static/icons/check.svg);mask-image:url(/static/icons/check.svg)}
.ui-icon[data-icon="cloud-relay"]{-webkit-mask-image:url(/static/icons/cloud-relay.svg);mask-image:url(/static/icons/cloud-relay.svg)}
.ui-icon[data-icon="component-api"]{-webkit-mask-image:url(/static/icons/component-api.svg);mask-image:url(/static/icons/component-api.svg)}
.ui-icon[data-icon="component-cache"]{-webkit-mask-image:url(/static/icons/component-cache.svg);mask-image:url(/static/icons/component-cache.svg)}
.ui-icon[data-icon="component-desktop"]{-webkit-mask-image:url(/static/icons/component-desktop.svg);mask-image:url(/static/icons/component-desktop.svg)}
.ui-icon[data-icon="component-mobile"]{-webkit-mask-image:url(/static/icons/component-mobile.svg);mask-image:url(/static/icons/component-mobile.svg)}
.ui-icon[data-icon="component-package"]{-webkit-mask-image:url(/static/icons/component-package.svg);mask-image:url(/static/icons/component-package.svg)}
.ui-icon[data-icon="infra-dolt"]{-webkit-mask-image:url(/static/icons/infra-dolt.svg);mask-image:url(/static/icons/infra-dolt.svg)}
.ui-icon[data-icon="lifecycle-assigned"]{-webkit-mask-image:url(/static/icons/lifecycle-assigned.svg);mask-image:url(/static/icons/lifecycle-assigned.svg)}
.ui-icon[data-icon="lifecycle-bead-filed"]{-webkit-mask-image:url(/static/icons/lifecycle-bead-filed.svg);mask-image:url(/static/icons/lifecycle-bead-filed.svg)}
.ui-icon[data-icon="lifecycle-detection"]{-webkit-mask-image:url(/static/icons/lifecycle-detection.svg);mask-image:url(/static/icons/lifecycle-detection.svg)}
.ui-icon[data-icon="lifecycle-dispatched"]{-webkit-mask-image:url(/static/icons/lifecycle-dispatched.svg);mask-image:url(/static/icons/lifecycle-dispatched.svg)}
.ui-icon[data-icon="lifecycle-escalation"]{-webkit-mask-image:url(/static/icons/lifecycle-escalation.svg);mask-image:url(/static/icons/lifecycle-escalation.svg)}
.ui-icon[data-icon="lifecycle-fix-failed"]{-webkit-mask-image:url(/static/icons/lifecycle-fix-failed.svg);mask-image:url(/static/icons/lifecycle-fix-failed.svg)}
.ui-icon[data-icon="lifecycle-notified"]{-webkit-mask-image:url(/static/icons/lifecycle-notified.svg);mask-image:url(/static/icons/lifecycle-notified.svg)}
.ui-icon[data-icon="lifecycle-regression"]{-webkit-mask-image:url(/static/icons/lifecycle-regression.svg);mask-image:url(/static/icons/lifecycle-regression.svg)}
.ui-icon[data-icon="lifecycle-slow-burn"]{-webkit-mask-image:url(/static/icons/lifecycle-slow-burn.svg);mask-image:url(/static/icons/lifecycle-slow-burn.svg)}
.ui-icon[data-icon="lifecycle-snoozed"]{-webkit-mask-image:url(/static/icons/lifecycle-snoozed.svg);mask-image:url(/static/icons/lifecycle-snoozed.svg)}
.ui-icon[data-icon="lifecycle-unsnoozed"]{-webkit-mask-image:url(/static/icons/lifecycle-unsnoozed.svg);mask-image:url(/static/icons/lifecycle-unsnoozed.svg)}
.ui-icon[data-icon="link-external"]{-webkit-mask-image:url(/static/icons/link-external.svg);mask-image:url(/static/icons/link-external.svg)}
.ui-icon[data-icon="monitor-human"]{-webkit-mask-image:url(/static/icons/monitor-human.svg);mask-image:url(/static/icons/monitor-human.svg)}
.ui-icon[data-icon="nav-arrow-right"]{-webkit-mask-image:url(/static/icons/nav-arrow-right.svg);mask-image:url(/static/icons/nav-arrow-right.svg)}
.ui-icon[data-icon="nav-caret-down"]{-webkit-mask-image:url(/static/icons/nav-caret-down.svg);mask-image:url(/static/icons/nav-caret-down.svg)}
.ui-icon[data-icon="nav-caret-right"]{-webkit-mask-image:url(/static/icons/nav-caret-right.svg);mask-image:url(/static/icons/nav-caret-right.svg)}
.ui-icon[data-icon="nav-external"]{-webkit-mask-image:url(/static/icons/nav-external.svg);mask-image:url(/static/icons/nav-external.svg)}
.ui-icon[data-icon="platform-ci"]{-webkit-mask-image:url(/static/icons/platform-ci.svg);mask-image:url(/static/icons/platform-ci.svg)}
.ui-icon[data-icon="platform-cocoa"]{-webkit-mask-image:url(/static/icons/platform-cocoa.svg);mask-image:url(/static/icons/platform-cocoa.svg)}
.ui-icon[data-icon="platform-generic"]{-webkit-mask-image:url(/static/icons/platform-generic.svg);mask-image:url(/static/icons/platform-generic.svg)}
.ui-icon[data-icon="platform-go"]{-webkit-mask-image:url(/static/icons/platform-go.svg);mask-image:url(/static/icons/platform-go.svg)}
.ui-icon[data-icon="platform-java"]{-webkit-mask-image:url(/static/icons/platform-java.svg);mask-image:url(/static/icons/platform-java.svg)}
.ui-icon[data-icon="platform-javascript"]{-webkit-mask-image:url(/static/icons/platform-javascript.svg);mask-image:url(/static/icons/platform-javascript.svg)}
.ui-icon[data-icon="platform-python"]{-webkit-mask-image:url(/static/icons/platform-python.svg);mask-image:url(/static/icons/platform-python.svg)}
.ui-icon[data-icon="platform-react-native"]{-webkit-mask-image:url(/static/icons/platform-react-native.svg);mask-image:url(/static/icons/platform-react-native.svg)}
.ui-icon[data-icon="severity-generic"]{-webkit-mask-image:url(/static/icons/severity-generic.svg);mask-image:url(/static/icons/severity-generic.svg)}
.ui-icon[data-icon="severity-fatal"]{-webkit-mask-image:url(/static/icons/severity-fatal.svg);mask-image:url(/static/icons/severity-fatal.svg)}
.ui-icon[data-icon="severity-error"]{-webkit-mask-image:url(/static/icons/severity-error.svg);mask-image:url(/static/icons/severity-error.svg)}
.ui-icon[data-icon="rec-button"]{-webkit-mask-image:url(/static/icons/rec-button.svg);mask-image:url(/static/icons/rec-button.svg)}
.ui-icon[data-icon="severity-warning"]{-webkit-mask-image:url(/static/icons/severity-warning.svg);mask-image:url(/static/icons/severity-warning.svg)}
.ui-icon[data-icon="silent"]{-webkit-mask-image:url(/static/icons/silent.svg);mask-image:url(/static/icons/silent.svg)}
.ui-icon[data-icon="snow-flake"]{-webkit-mask-image:url(/static/icons/snow-flake.svg);mask-image:url(/static/icons/snow-flake.svg)}
.ui-icon[data-icon="status-active"]{-webkit-mask-image:url(/static/icons/status-active.svg);mask-image:url(/static/icons/status-active.svg)}
.ui-icon[data-icon="status-archived"]{-webkit-mask-image:url(/static/icons/status-archived.svg);mask-image:url(/static/icons/status-archived.svg)}
.ui-icon[data-icon="status-fix-landed"]{-webkit-mask-image:url(/static/icons/status-fix-landed.svg);mask-image:url(/static/icons/status-fix-landed.svg)}
.ui-icon[data-icon="status-fixing"]{-webkit-mask-image:url(/static/icons/status-fixing.svg);mask-image:url(/static/icons/status-fixing.svg)}
.ui-icon[data-icon="status-regressed"]{-webkit-mask-image:url(/static/icons/status-regressed.svg);mask-image:url(/static/icons/status-regressed.svg)}
.ui-icon[data-icon="status-resolved"]{-webkit-mask-image:url(/static/icons/status-resolved.svg);mask-image:url(/static/icons/status-resolved.svg)}
.ui-icon[data-icon="status-snoozed"]{-webkit-mask-image:url(/static/icons/status-snoozed.svg);mask-image:url(/static/icons/status-snoozed.svg)}
.ui-icon[data-icon="component-database"]{-webkit-mask-image:url(/static/icons/component-database.svg);mask-image:url(/static/icons/component-database.svg)}
.ui-icon[data-icon="component-web"]{-webkit-mask-image:url(/static/icons/component-web.svg);mask-image:url(/static/icons/component-web.svg)}
.ui-icon[data-icon="component-android"]{-webkit-mask-image:url(/static/icons/component-android.svg);mask-image:url(/static/icons/component-android.svg)}
.ui-icon[data-icon="component-worker"]{-webkit-mask-image:url(/static/icons/component-worker.svg);mask-image:url(/static/icons/component-worker.svg)}
.ui-icon[data-icon="lifecycle-commit"]{-webkit-mask-image:url(/static/icons/lifecycle-commit.svg);mask-image:url(/static/icons/lifecycle-commit.svg)}

/* Fusee marks. Sizes follow line height so a mark sits where the old text
   logotype did. */
.brand-lockup { display: inline-flex; align-items: center; gap: 0.5rem; vertical-align: middle; }
.brand-icon { height: 1.75rem; width: 1.75rem; display: block; }
.brand-wordmark { height: 1.5rem; width: auto; display: block; }
.landing-wordmark-sm .brand-icon { height: 1.35rem; width: 1.35rem; }
.landing-wordmark-sm .brand-wordmark { height: 1.15rem; }
.auth-logo .brand-icon { height: 3rem; width: 3rem; }
.auth-logo .brand-wordmark { height: 2.6rem; }
.auth-card .auth-logo .brand-icon { height: 2rem; width: 2rem; }
.auth-card .auth-logo .brand-wordmark { height: 1.7rem; }

/* ─── Cloud project settings: left-hand section nav + one panel per
   setting. Without JS every panel shows, stacked; with JS
   (.is-paged) only the selected one does. ─────────────────────────── */
.settings-layout {
  display: grid;
  grid-template-columns: 13rem minmax(0, 1fr);
  gap: 2rem;
  align-items: start;
  padding-bottom: 3rem;
}
.settings-nav {
  position: sticky;
  top: 4.5rem;
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}
.settings-nav-group { display: flex; flex-direction: column; gap: 0.1rem; }
.settings-nav-group-danger { padding-top: 0.9rem; border-top: 1px solid var(--rule); }
.settings-nav-heading {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ballast);
  padding: 0 0.75rem 0.3rem;
}
.settings-nav-link {
  display: block;
  padding: 0.45rem 0.75rem;
  border-radius: var(--radius);
  border-left: 2px solid transparent;
  color: var(--steel);
  font-size: var(--text-md);
  text-decoration: none;
}
.settings-nav-link:hover { background: var(--surface); text-decoration: none; }
.settings-nav-link.is-active {
  background: var(--surface);
  border-left-color: var(--rail-blue);
  font-weight: 600;
  box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
.settings-nav-group-danger .settings-nav-link { color: var(--signal-red); }
.settings-nav-group-danger .settings-nav-link.is-active { border-left-color: var(--signal-red); }

.settings-content { min-width: 0; max-width: 52rem; }
.settings-content > .flash { margin-bottom: 1rem; }
.settings-panel { margin-bottom: 1.25rem; overflow: visible; }
.settings-layout.is-paged .settings-panel { margin-bottom: 0; }
.settings-panel[hidden] { display: none; }
.settings-panel-head {
  padding: 1.1rem 1.5rem 1rem;
  border-bottom: 1px solid var(--rule);
}
.settings-panel-head h3 { font-size: 1.05rem; font-weight: 600; margin: 0; }
.settings-panel-head p { margin: 0.3rem 0 0; color: var(--ballast); font-size: var(--text-base); line-height: 1.5; }
.settings-panel-body { padding: 1.25rem 1.5rem 1.5rem; }
.settings-panel-danger { border: 1px solid #fecaca; }
.settings-panel-danger .settings-panel-head h3 { color: var(--signal-red); }

/* One label style, one control width, one hint rhythm across every panel. */
.settings-panel .form-group { margin-bottom: 1.15rem; }
.settings-panel .form-group > label:not(.checkbox-row),
.settings-panel .form-sublabel {
  display: block;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--steel);
  margin-bottom: 0.35rem;
}
.settings-panel .form-group input:not([type="checkbox"], [type="radio"]),
.settings-panel .form-group select,
.settings-panel .form-group textarea {
  width: 100%;
  min-height: var(--control-height);
  padding: 0.5rem 0.7rem;
  border: 1px solid var(--border-input);
  border-radius: var(--radius);
  font-size: var(--text-md);
  font-family: inherit;
  background: var(--surface);
}
.settings-panel .form-group textarea { min-height: 4.5rem; }
.settings-panel .form-hint { font-size: var(--text-sm); line-height: 1.5; margin-top: 0.35rem; }
.settings-panel .checkbox-row {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
  font-size: var(--text-md);
  font-weight: 500;
  margin: 0.15rem 0;
  cursor: pointer;
}
.settings-panel .checkbox-row input {
  width: auto;
  min-height: 0;
  padding: 0;
  margin: 0.2rem 0 0;
  flex: none;
}
.settings-panel .form-group > label.checkbox-row { display: flex; font-size: var(--text-md); font-weight: 500; color: var(--steel); }
.settings-panel .checkbox-row + .form-hint,
.settings-panel .checkbox-hint { padding-left: 1.55rem; margin-bottom: 0.5rem; }
.settings-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 1.25rem;
  align-items: start;
}
.settings-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.settings-panel .settings-narrow input { max-width: 10rem; }
.settings-readonly {
  min-height: var(--control-height);
  display: flex;
  align-items: center;
  padding: 0 0.7rem;
  background: var(--coal);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  font-size: var(--text-base);
}
.settings-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin-top: 0.25rem;
}
.settings-divided { margin-top: 1.5rem; padding-top: 1.25rem; border-top: 1px solid var(--rule); }
.settings-status-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; margin: 1rem 0; }
.settings-panel hr { border: 0; border-top: 1px solid var(--rule); margin: 1.5rem 0; }
.settings-panel .settings-intro { margin: 0 0 1.25rem; }
.settings-panel .github-status {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 0.4rem 1rem;
  margin: 1.25rem 0 0;
  padding-top: 1rem;
  border-top: 1px solid var(--rule);
  font-size: var(--text-base);
}
.settings-panel .github-status dt { font-weight: 600; color: var(--ballast); font-size: var(--text-sm); }
.settings-panel .github-status dd { margin: 0; }
.settings-panel .cloud-danger-row { gap: 1.5rem; }
.settings-panel .cloud-danger-row p { margin: 0; }
.settings-access table { width: 100%; border-collapse: collapse; margin-bottom: 1.5rem; font-size: var(--text-base); }
.settings-access th {
  text-align: left;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ballast);
  padding: 0 0.75rem 0.5rem 0;
  border-bottom: 1px solid var(--rule);
}
.settings-access td { padding: 0.6rem 0.75rem 0.6rem 0; border-bottom: 1px solid var(--rule); vertical-align: middle; }
.settings-access td.row-actions { text-align: right; padding-right: 0; }
.settings-access .inline-create-form {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  gap: 0 1.25rem;
  align-items: start;
  margin-bottom: 1rem;
}
.settings-access .inline-create-form .form-group { margin-bottom: 1rem; min-width: 0; }
.settings-access .inline-create-form > .btn { grid-column: 1 / -1; justify-self: start; }
.settings-panel label .form-hint { display: inline; margin: 0 0 0 0.25rem; font-weight: 400; }

@media (max-width: 860px) {
  .settings-layout { grid-template-columns: minmax(0, 1fr); gap: 1rem; }
  .settings-access .inline-create-form { grid-template-columns: minmax(0, 1fr); }
  .settings-nav {
    min-width: 0;
    position: static;
    flex-direction: row;
    gap: 0.25rem;
    overflow-x: auto;
    padding-bottom: 0.25rem;
  }
  .settings-nav-group { flex-direction: row; gap: 0.25rem; }
  .settings-nav-group-danger { padding-top: 0; border-top: 0; }
  .settings-nav-heading { display: none; }
  .settings-nav-link { white-space: nowrap; border-left: 0; border-bottom: 2px solid transparent; border-radius: var(--radius) var(--radius) 0 0; }
  .settings-nav-link.is-active { border-bottom-color: var(--rail-blue); }
  .settings-nav-group-danger .settings-nav-link.is-active { border-bottom-color: var(--signal-red); }
  .settings-grid, .settings-grid-3 { grid-template-columns: minmax(0, 1fr); }
  .settings-panel-head, .settings-panel-body { padding-left: 1rem; padding-right: 1rem; }
  .settings-panel .cloud-danger-row { flex-direction: column; align-items: flex-start; }
}

/* LLM setup prompt modal — opened from the project page's Connection
   chip and the settings page's Connection panel. */
.cloud-strip-connection { align-items: center; gap: 0.75rem; }
.cloud-strip-connection:has(> details[open]) { align-items: flex-start; }
.cloud-strip-connection .cloud-strip-dsn { padding: 0; flex: 1 1 auto; min-width: 0; }
.cloud-strip-connection .llm-prompt-open { flex: none; white-space: nowrap; }
.llm-dialog {
  width: min(46rem, calc(100vw - 2rem));
  max-height: calc(100vh - 4rem);
  padding: 0;
  border: 0;
  border-radius: calc(var(--radius) * 1.5);
  box-shadow: 0 20px 50px rgba(15, 23, 42, 0.3);
  color: var(--steel);
}
.llm-dialog::backdrop { background: rgba(15, 23, 42, 0.55); }
.llm-dialog-inner { padding: 1.25rem 1.5rem 1.5rem; }
.llm-dialog-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 0.35rem; }
.llm-dialog-head h3 { margin: 0; font-size: 1.05rem; font-weight: 600; }
.llm-dialog-head form { margin: 0; }
.llm-dialog-close {
  border: 0;
  background: transparent;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--ballast);
  cursor: pointer;
  padding: 0.1rem 0.4rem;
  border-radius: var(--radius);
}
.llm-dialog-close:hover { background: var(--coal); color: var(--steel); }
.llm-dialog .form-hint { font-size: var(--text-base); line-height: 1.5; margin: 0 0 0.75rem; }
.llm-dialog .llm-prompt-body { max-height: 55vh; overflow: auto; padding-top: 3rem; }
