/* Astro Coverage Webapp — basic dark theme */

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 13px;
  background: #0a0d12;
  color: #e0e4ea;
}
/* Single-screen layout: body owns the full viewport and stacks topbar →
   layout → statusbar in a flex column. .layout absorbs whatever space is
   left, so the page is always exactly viewport-height (no double-scroll
   when the actual topbar is taller than the previous hardcoded 44px). */
body {
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
}

.topbar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  padding: 8px 14px;
  background: #0f1319;
  border-bottom: 1px solid #1f2937;
  align-items: center;
  min-height: 44px;
}

.title {
  flex: 0 0 220px;
  margin-right: auto;
}
.title strong {
  display: block;
  font-size: 15px;
  color: #e8ecf3;
}
.title .meta {
  font-size: 11px;
  color: #78839a;
}

.controls {
  display: flex;
  align-items: center;
  gap: 6px 10px;
  flex-wrap: wrap;
}

.ctrl {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: #a2aec2;
}

.ctrl select, .ctrl input {
  background: #1a2030;
  border: 1px solid #2a3246;
  color: #e0e4ea;
  padding: 3px 6px;
  border-radius: 3px;
  font-size: 12px;
}

.tele-chips {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px 6px;
  align-items: center;
}

.tele-swatch {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  margin-right: 4px;
  vertical-align: middle;
  border: 1px solid rgba(255,255,255,0.15);
}

/* A swatch you can click to pick the telescope's colour. The native colour
   input is stripped back so it looks like the plain swatch it replaced. */
input.tele-swatch-pick {
  -webkit-appearance: none;
  appearance: none;
  width: 14px;
  height: 14px;
  padding: 0;
  background: none;
  cursor: pointer;
}
input.tele-swatch-pick::-webkit-color-swatch-wrapper { padding: 0; }
input.tele-swatch-pick::-webkit-color-swatch { border: none; border-radius: 2px; }
input.tele-swatch-pick::-moz-color-swatch { border: none; border-radius: 2px; }
input.tele-swatch-pick:hover { border-color: rgba(255,255,255,0.6); }

.label {
  color: #78839a;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Sky survey caption: a full-width row under the toolbar controls that says
   what the chosen background survey shows and how much sky it covers. The
   coverage chip is the point: a partial survey has a hard edge where the
   tiles stop, and without the chip users report that edge as a bug. */
.sky-caption {
  flex-basis: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  color: #a2aec2;
  line-height: 1.3;
}
.sky-banner {
  margin: 6px 0;
  padding: 6px 10px;
  border: 1px solid #7a5a1f;
  border-radius: 6px;
  background: #332611;
  color: #f0c674;
  font-size: 12px;
  line-height: 1.4;
}
.sky-banner[hidden] { display: none; }
.sky-banner button { margin-left: 8px; }
.sky-chip {
  flex: 0 0 auto;
  padding: 1px 7px;
  border-radius: 10px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.02em;
  border: 1px solid #2a3246;
  background: #1a2030;
  color: #c8d2e4;
}
.sky-chip.full { border-color: #2f6b45; background: #15301f; color: #9fe0b5; }
.sky-chip.partial { border-color: #7a5a1f; background: #332611; color: #f0c674; }
.sky-more {
  margin-left: auto;
  flex: 0 0 auto;
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: #7fb3ff;
  text-decoration: underline;
  cursor: pointer;
}
.sky-more:hover { color: #a9ccff; }

.fchip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 6px;
  background: #1a2030;
  border: 1px solid #2a3246;
  border-radius: 12px;
  cursor: pointer;
  user-select: none;
}
.fchip:hover { background: #212939; }
.fchip input { margin: 0; }

select, input[type="text"], input[type="number"], input[type="range"], button {
  background: #1a2030;
  border: 1px solid #2a3246;
  color: #e0e4ea;
  padding: 3px 8px;
  border-radius: 3px;
  font-size: 12px;
  cursor: pointer;
}
button:hover { background: #212939; }
button:active { background: #262e40; }

#depthSlider {
  width: 120px;
}
#depthValue {
  display: inline-block;
  width: 32px;
  font-variant-numeric: tabular-nums;
  color: #a2aec2;
}

.layout {
  display: flex;
  flex: 1;
  min-height: 0;     /* allow children with overflow:auto to shrink properly */
}

/* The map area never changes size when the side panel opens, closes, is
   resized or switches tab: the panel floats over the map's right edge
   instead of taking width from it, so Aladin never resizes or recentres. */
.map-area {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
  display: flex;
}

#aladin-lite-div {
  flex: 1;
  min-width: 0;
  background: #0a0d12;
  /* Own stacking context, so Aladin's high z-index controls stay under
     the side panel rather than poking through it. */
  isolation: isolate;
}

.panel {
  --side-panel-w: 420px;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  width: var(--side-panel-w);
  max-width: calc(100% - 120px);
  background: #0f1319;
  border-left: 1px solid #1f2937;
  box-shadow: -10px 0 28px rgba(0, 0, 0, 0.45);
  display: flex;
  flex-direction: column;
  min-height: 0;
  font-size: 15.5px; /* ~20% larger than body (13 → 15.5) */
  line-height: 1.4;
}
.panel[hidden] { display: none; }

.side-panel-head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px 8px 14px;
  border-bottom: 1px solid #1f2937;
}
.side-panel-head h2 {
  margin: 0;
  flex: 1;
  font-size: 14px;
  color: #e8ecf3;
}
.side-panel-head .icon-btn { font-size: 16px; line-height: 1; }

.side-tab {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.side-tab[hidden] { display: none; }
.side-tab[data-tab="filters"],
.side-tab[data-tab="library"] { overflow-y: auto; }

/* Drag handle on the panel's left edge. Arrow keys work when focused. */
.panel-resizer {
  position: absolute;
  top: 0;
  left: -4px;
  width: 8px;
  height: 100%;
  cursor: col-resize;
  z-index: 2;
}
.panel-resizer::after {
  content: "";
  position: absolute;
  left: 3px;
  top: 0;
  bottom: 0;
  width: 2px;
  background: transparent;
  transition: background 0.1s;
}
.panel-resizer:hover::after,
.panel-resizer:focus-visible::after,
.panel-resizer.dragging::after { background: #4da6ff; }
.panel-resizer:focus-visible { outline: none; }
body.panel-resizing { cursor: col-resize; user-select: none; }
.sheet-grab { display: none; }

/* Icon rail on the far right edge. One panel open at a time. */
.side-rail {
  flex: 0 0 60px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px 0;
  background: #0c1016;
  border-left: 1px solid #1f2937;
  z-index: 31;
}
.rail-btn {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 9px 2px 7px;
  border: 0;
  border-radius: 0;
  background: none;
  color: #78839a;
  font-size: 10px;
  cursor: pointer;
}
.rail-btn svg { width: 22px; height: 22px; }
.rail-btn:hover { color: #e0e4ea; }
.rail-btn[aria-pressed="true"] {
  color: #fff;
  background: #121926;
  box-shadow: inset -3px 0 0 #4da6ff;
}
.rail-badge {
  position: absolute;
  top: 4px;
  right: 8px;
  min-width: 14px;
  padding: 0 4px;
  border-radius: 7px;
  background: #b8862b;
  color: #0a0d12;
  font-size: 9px;
  font-weight: 700;
  text-align: center;
}
.rail-badge[hidden] { display: none; }
.rail-tip {
  position: absolute;
  right: calc(100% + 8px);
  top: 50%;
  transform: translateY(-50%);
  padding: 4px 8px;
  border-radius: 4px;
  background: #232a3a;
  color: #e0e4ea;
  font-size: 12px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.1s;
  z-index: 40;
}
.rail-btn:hover .rail-tip,
.rail-btn:focus-visible .rail-tip { opacity: 1; }

/* Phone width: the rail becomes a bottom tab bar and the panel a sheet
   over the map. The map's height doesn't change when the sheet opens. */
@media (max-width: 640px) {
  .layout { flex-direction: column; }
  .side-rail {
    flex: 0 0 56px;
    flex-direction: row;
    padding: 0;
    border-left: 0;
    border-top: 1px solid #1f2937;
  }
  .rail-btn { flex: 1; padding: 7px 2px 5px; }
  .rail-btn[aria-pressed="true"] { box-shadow: inset 0 3px 0 #4da6ff; }
  .rail-tip { display: none; }
  .panel {
    left: 0;
    right: 0;
    top: auto;
    width: auto;
    max-width: none;
    height: 68%;
    border-left: 0;
    border-top: 1px solid #2a3246;
    border-radius: 12px 12px 0 0;
    box-shadow: 0 -12px 30px rgba(0, 0, 0, 0.5);
  }
  .panel-resizer { display: none; }
  .sheet-grab {
    display: block;
    width: 44px;
    height: 4px;
    margin: 7px auto 0;
    border-radius: 2px;
    background: #3a4458;
  }
}
/* Anything inside the panel that overflows horizontally should clip rather
   than stretch the rail. Belt-and-braces with the .panel max-width above. */
#panelBody { min-width: 0; }
#panelBody fieldset { min-width: 0; }

.panel-search {
  flex: 0 0 auto;
  padding: 10px 14px 8px;
  border-bottom: 1px solid #1f2937;
  background: #0f1319;
}
.panel-search input[type="search"] {
  width: 100%;
  font-size: 13px;
  padding: 5px 8px;
  background: #0a0d12;
  border: 1px solid #2a3246;
  color: #e0e4ea;
  border-radius: 3px;
}
.panel-search input[type="search"]:focus {
  outline: none;
  border-color: #4da6ff;
}
.search-hint {
  font-size: 10px;
  color: #78839a;
  margin-top: 4px;
  font-family: "SF Mono", Monaco, Consolas, monospace;
}
.search-hint.error { color: #ff8080; }

#panelBody {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 14px 16px;
  min-height: 0;
}

.panel h3 {
  margin: 0 0 10px 0;
  font-size: 17px;
  color: #e8ecf3;
}
.panel h4 {
  margin: 14px 0 5px 0;
  font-size: 14px;
  color: #a2aec2;
  font-weight: 600;
}

.panel-empty, .panel-loading {
  color: #78839a;
  font-size: 14px;
  line-height: 1.5;
}

.panel-error {
  color: #e77;
  font-size: 14px;
  line-height: 1.5;
}

/* The sky map's own startup error, shown in the map area. Kept narrow so
   the side panel floating over the map's right edge never covers it. */
.map-error {
  padding: 24px;
  max-width: 36em;
}

/* Placeholder in the map area while Aladin Lite loads. */
.map-loading {
  padding: 24px;
  color: #8a93a6;
  font-size: 14px;
}

.panel-list h3 {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 0 0 8px 0;
}
.panel-list .tr-count {
  color: #78839a;
  font-size: 12px;
  font-weight: 400;
}

.target-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.target-row {
  display: grid;
  /* row 1: swatch · name · hours
     row 2: (swatch col empty) · meta-strip (filter dots, Now+Trend chip,
            sparkline)
     The last column holds the ⋯ across both rows, as on plan rows. The
     name column may shrink below its content so long names ellipsise
     instead of pushing the hours off the row. */
  grid-template-columns: 10px minmax(0, 1fr) auto 22px;
  grid-template-rows: auto auto;
  column-gap: 8px;
  row-gap: 2px;
  align-items: center;
  padding: 6px 6px;
  border-radius: 4px;
  cursor: pointer;
  border-bottom: 1px dashed #1a2030;
  font-size: 13px;
}
.tr-swatch { grid-row: 1; grid-column: 1; align-self: center; }
.tr-name   { grid-row: 1; grid-column: 2; }
.tr-hours  { grid-row: 1; grid-column: 3; }
.tr-meta {
  grid-row: 2;
  grid-column: 2 / -2;       /* span name → hours columns, not the menu */
  display: flex;
  align-items: center;
  gap: 3px 8px;
  min-width: 0;
  /* At the narrowest panel a long chip can leave no room for the strip;
     it then drops below, right aligned, rather than running under the ⋯. */
  flex-wrap: wrap;
  font-size: 11px;
  color: #78839a;
}
/* Push the year-curve sparkline to the right edge of the row so the dots
   and chip keep their leading position and the middle absorbs the slack.
   Slightly smaller cells than elsewhere so line 2 fits a narrow panel. */
.tr-meta .yc-sparkline {
  margin-left: auto;
  margin-right: 0;
  grid-template-columns: repeat(12, 7px);
}
.tr-meta .yc-sparkline .yc-cell { width: 7px; height: 8px; }
/* One chip for this month plus the trend arrow. Never wraps: the label is
   short by construction and the full wording lives in the tooltip. */
.tr-chip { white-space: nowrap; flex-shrink: 0; }
.tr-arrow { font-weight: 600; }
.tr-arrow.nn-trend-up   { color: #8fc485; }
.tr-arrow.nn-trend-down { color: #e0876f; }
.tr-arrow.nn-trend-flat { color: #9aa3b3; }
.tr-arrow.nn-trend-wait { color: #d6b35c; }
.target-row:hover { background: #1a2030; }
.target-row.is-picked { background: #1c2a44; box-shadow: inset 2px 0 0 #4da6ff; }

.tr-swatch {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  border: 1px solid rgba(255,255,255,0.15);
}
.tr-name {
  color: #e8ecf3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tr-dots {
  display: inline-flex;
  gap: 2px;
}
.tr-hours {
  color: #a2aec2;
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  min-width: 38px;
  text-align: right;
}
.fdot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
}
.tr-empty {
  color: #78839a;
  padding: 10px 6px;
  font-style: italic;
}

.back-link {
  display: inline-block;
  color: #78839a;
  text-decoration: none;
  font-size: 12px;
  margin-bottom: 4px;
  cursor: pointer;
}
.back-link:hover { color: #e0e4ea; }

.panel table {
  width: 100%;
  font-size: 13px;
  border-collapse: collapse;
  margin-top: 6px;
}
.panel th {
  text-align: left;
  color: #78839a;
  font-weight: 600;
  border-bottom: 1px solid #2a3246;
  padding: 3px 5px;
}
.panel td {
  padding: 3px 5px;
  border-bottom: 1px dashed #1a2030;
}
.panel td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.filter-pill {
  display: inline-block;
  padding: 1px 5px;
  margin-right: 3px;
  border-radius: 3px;
  font-size: 10px;
  font-weight: 600;
  color: #0a0d12;
}
.fp-Ha   { background: #ff4d4d; }
.fp-SII  { background: #ffd84d; }
.fp-OIII { background: #4da6ff; color: #fff; }
.fp-L    { background: #d0d0d0; }
.fp-R    { background: #ff8080; color: #fff; }
.fp-G    { background: #80ff80; }
.fp-B    { background: #8080ff; color: #fff; }
.fp-V    { background: #b0b0b0; }
.fp-IDAS { background: #a0ffd0; }
.fp-other { background: #3a4356; color: #d8dde8; }
.fp-OSC  { background: #2a3246; color: #e8ecf4; display: inline-flex; align-items: center; gap: 3px; }
/* One shot colour: a third each of R, G and B. */
.rgb-pie {
  display: inline-block;
  width: 10px; height: 10px;
  border-radius: 50%;
  background: conic-gradient(#ff8080 0 120deg, #80ff80 120deg 240deg, #8080ff 240deg 360deg);
  vertical-align: -1px;
}
.fchip-other { color: #9aa3b5; border-style: dashed; }
.via { color: #78839a; font-size: 10px; }

.statusbar {
  /* Pin to a fixed height so growing/shrinking content (e.g. long hover
     tooltips that would otherwise wrap to two lines) never resizes the
     map area underneath — that re-flow caused a visible Aladin shudder. */
  flex: 0 0 24px;
  height: 24px;
  padding: 0 12px;
  background: #0a0d12;
  border-top: 1px solid #1f2937;
  font-size: 11px;
  color: #78839a;
  display: flex;
  align-items: center;
  justify-content: space-between;
  overflow: hidden;
}
.statusbar > span {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.statusbar #tooltip { flex: 1; min-width: 0; margin-right: 12px; }
.statusbar #obsNow  { flex: 0 0 auto; }

.pathlist {
  font-size: 10px;
  font-family: "SF Mono", Monaco, Consolas, monospace;
  color: #a2aec2;
  background: #0a0d12;
  padding: 4px 6px;
  border-radius: 3px;
  max-height: 120px;
  overflow-y: auto;
  word-break: break-all;
}

/* --- Right-rail accordions (Filters, Catalogues) --- */

.rail-accordion {
  flex: 0 0 auto;
  border-bottom: 1px solid #1f2937;
  background: #0f1319;
  font-size: 12px;
}
.rail-accordion > summary {
  list-style: none;
  cursor: pointer;
  padding: 8px 14px;
  color: #a2aec2;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  user-select: none;
  position: relative;
  padding-right: 26px;
}
.rail-accordion > summary::-webkit-details-marker { display: none; }
.rail-accordion > summary::after {
  content: "▸";
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  transition: transform 0.12s ease;
  color: #78839a;
  font-size: 10px;
}
.rail-accordion[open] > summary::after { transform: translateY(-50%) rotate(90deg); }
.rail-accordion > summary:hover { background: #141a24; color: #e0e4ea; }

.rail-accordion .accordion-body {
  padding: 8px 14px 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.rail-accordion .row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
}

.broken-note {
  color: #d08060;
  text-transform: none;
  font-weight: 500;
  letter-spacing: 0;
  font-size: 10px;
  margin-left: 4px;
}

.finished-badge {
  display: inline-block;
  font-size: 10px;
  padding: 1px 5px;
  border-radius: 3px;
  background: #2d6030;
  color: #e0ffe0;
  font-weight: 600;
  margin-left: 6px;
}
.finished-badge.incomplete {
  background: #2a3246;
  color: #78839a;
}

.mark-finished-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 10px 0 4px;
  padding: 8px 10px;
  background: #0a0d12;
  border: 1px dashed #2a3246;
  border-radius: 4px;
}
.mark-finished-row .status-text {
  flex: 1;
  color: #a2aec2;
  font-size: 12px;
}
.mark-finished-row .row-menu-btn { padding: 0; font-size: 16px; }

/* --- Unsaved-edits modal (fires on Esc / empty-sky deselect from plan-edit) --- */

.dirty-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
}
.dirty-modal {
  background: #161b25;
  border: 1px solid #2a3246;
  border-radius: 6px;
  padding: 16px 20px 14px;
  min-width: 320px;
  max-width: 440px;
  color: #e0e4ea;
  font-size: 13px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
}
.dirty-modal h4 {
  margin: 0 0 8px;
  color: #ffffff;
  font-size: 14px;
}
.dirty-modal p {
  margin: 0 0 14px;
  color: #a2aec2;
  line-height: 1.4;
}
.dirty-modal-buttons {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}
.dirty-modal-buttons button {
  padding: 5px 12px;
  font-size: 12px;
}
.dirty-modal-buttons .btn-primary {
  background: #2d4a7a;
  color: #ffffff;
}

/* --- Planner --- */

.mode-toggle {
  display: inline-flex;
  align-items: center;
  border: 1px solid #2a3246;
  border-radius: 4px;
  overflow: hidden;
}
.mode-btn {
  background: #1a2030;
  border: 0;
  color: #a2aec2;
  padding: 4px 10px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  border-radius: 0;
}
.mode-btn:hover { background: #212939; color: #e0e4ea; }
.mode-btn.active {
  background: #2d4a7c;
  color: #fff;
}
.mode-btn + .mode-btn { border-left: 1px solid #2a3246; }

.planner-toolbar {
  display: flex;
  gap: 6px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}
.planner-toolbar button {
  font-size: 12px;
  padding: 3px 8px;
}
.planner-toolbar .btn-primary {
  background: #2d4a7c;
  color: #fff;
  border-color: #3a5a94;
}
.planner-toolbar .btn-primary:hover { background: #3a5a94; }

.plan-row {
  display: grid;
  /* Two-line layout:
     row 1: [pri-dot] [target name (flex)] [N.Nh left]
     row 2: [────── .plan-row-line2 spans cols 2-3 ──────]
     plan-row-line2 packs project + filter dots on the left and right-anchors
     the time-aware visibility chips under the "h left" column so the eye can
     scan all the "right edge" info as one column. */
  grid-template-columns: auto 1fr auto 22px;
  grid-template-rows: auto auto;
  column-gap: 8px;
  row-gap: 3px;
  align-items: center;
  padding: 7px 6px;
  border-radius: 4px;
  cursor: pointer;
  border-bottom: 1px dashed #1a2030;
  font-size: 13px;
}
.plan-pri-dot   { grid-row: 1; grid-column: 1; }
.plan-name      { grid-row: 1; grid-column: 2; }
.plan-vis       { grid-row: 1; grid-column: 3; display: flex; align-items: center; }
.plan-vis .yc-sparkline { margin-right: 0; }
.plan-row-line2 {
  grid-row: 2;
  grid-column: 2 / -2;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  color: #78839a;
}
.plan-row-line2 .plan-remaining { margin-left: auto; }
/* Hours left per panel, on a third line, for a mosaic that tracks panels. */
.plan-panel-left {
  grid-row: 3;
  grid-column: 2 / -2;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  font-size: 10px;
  color: #78839a;
}
.plan-panel-chip { padding: 0 5px; border-radius: 8px; background: #1a2030; white-space: nowrap; }
.plan-panel-chip.done { color: #6fbf8a; }
body:not([data-time-aware="on"]) .plan-vis { display: none; }
.plan-row:hover { background: #1a2030; }

/* Priority dot — blue/green/grey per user's pick. Hover tooltip via the
   `title` attribute set in the template. */
.plan-pri-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}
.plan-pri-dot.plan-pri-high   { background: #3a7ad6; }
.plan-pri-dot.plan-pri-normal { background: #3a9658; }
.plan-pri-dot.plan-pri-low    { background: #5a657a; }

.plan-name {
  color: #e8ecf3;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.plan-project {
  color: #78839a;
  font-size: 11px;
}
.plan-state-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 10px;
  font-weight: 500;
  color: #a2aec2;
  background: #232a3a;
  vertical-align: middle;
}
.plan-row.plan-state-closed { opacity: 0.5; }
.plan-goals {
  display: inline-flex;
  gap: 2px;
}
.plan-goal-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
}
.plan-goal-dot.done     { opacity: 1.0; }
.plan-goal-dot.partial  { opacity: 0.55; }
.plan-goal-dot.todo     { opacity: 0.18; }
.plan-remaining {
  color: #a2aec2;
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  min-width: 44px;
  text-align: right;
}

.plan-form {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.plan-form fieldset {
  border: 1px solid #1f2937;
  border-radius: 4px;
  padding: 8px 10px;
}
.plan-form legend {
  color: #78839a;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 0 4px;
}
.plan-form label {
  display: block;
  font-size: 12px;
  color: #a2aec2;
  margin-bottom: 6px;
}
.plan-form label > span.lab {
  display: inline-block;
  min-width: 90px;
  color: #78839a;
}
.plan-form input[type="text"],
.plan-form input[type="number"],
.plan-form select {
  padding: 3px 6px;
  font-size: 12px;
  width: 110px;
}
.plan-form input[type="text"].wide { width: 100%; }
/* Label | input | readout in fixed columns, so a wide readout such as a
   negative Dec in full sexagesimal wraps inside its own column instead of
   squeezing the label and pushing the input onto a second line. The label
   uses display: contents so its caption and input become grid cells. */
.plan-form .coord-row:not(.mosaic-row) {
  display: grid;
  grid-template-columns: 90px 110px minmax(0, 1fr);
  column-gap: 6px;
  align-items: center;
  margin-bottom: 6px;
}
.plan-form .coord-row:not(.mosaic-row) > label {
  display: contents;
}
.plan-form .coord-row:not(.mosaic-row) > label > span.lab {
  min-width: 0;
}
.plan-form .coord-row:not(.mosaic-row) > button {
  justify-self: start;
}
.plan-form .mosaic-row {
  display: flex;
  gap: 6px;
  align-items: center;
}
/* Three equal columns that share the rail width. The default 110px input
   width does not fit three across inside the 380px rail, which clipped the
   Overlap spinner on the right. */
.plan-form .mosaic-row label { flex: 1 1 0; min-width: 0; }
.plan-form .mosaic-row label > span.lab { min-width: 0; }
.plan-form .mosaic-row input[type="number"] { width: 100%; }
/* The plan's scheduling switch and one switch per mosaic panel. */
.plan-form .schedule-switch input[type="checkbox"] { width: auto; }
.plan-form .panel-switches { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 6px; font-size: 11px; }
.plan-form .panel-switches:empty { display: none; }
.plan-form .panel-switches-head { flex: 1 0 100%; color: #78839a; }
.plan-form .panel-switch { display: inline-flex; align-items: center; gap: 4px; }
.plan-form .coord-row .hms {
  color: #78839a;
  font-family: "SF Mono", Monaco, Consolas, monospace;
  font-size: 11px;
  white-space: nowrap;
}
/* When the readout no longer fits beside the input, it drops to its own
   line under the input instead of wrapping. 350px is the form width below
   which a full negative Dec readout (about 110px) no longer fits beside the
   input; the rail is 368px wide at its default size. */
.plan-form { container-type: inline-size; }
@container (max-width: 350px) {
  .plan-form .coord-row:not(.mosaic-row) > .hms { grid-column: 2 / -1; }
}
.plan-form textarea {
  width: 100%;
  min-height: 44px;
  background: #1a2030;
  border: 1px solid #2a3246;
  color: #e0e4ea;
  padding: 4px 6px;
  border-radius: 3px;
  font-size: 12px;
  font-family: inherit;
  resize: vertical;
}

.goals-table {
  width: 100%;
  font-size: 12px;
}
.goals-table th { color: #78839a; font-weight: 600; }
.goals-table td input[type="number"] { width: 64px; }
.goals-table .tmpl-sel { width: 100%; font-size: 11px; }
.goals-table td { padding: 3px 4px; }
.goal-status {
  font-size: 10px;
  padding: 1px 5px;
  border-radius: 3px;
}
.goal-status.done     { background: #2d6030; color: #e0ffe0; }
.goal-status.partial  { background: #605530; color: #fff8e0; }
.goal-status.todo     { background: #2a3246; color: #a2aec2; }

/* Filter rows: one card per row, a four-column grid shared by both lines.
   Columns are position (22px), filter (104px), template (the rest, allowed
   to shrink to nothing so long names truncate) and remove (26px). Keep the
   column string in step with CARD_GRID_COLUMNS in static/filter-rows.mjs. */
.fr-list { display: flex; flex-direction: column; gap: 6px; max-width: 100%; overflow-x: hidden; padding: 6px 0; margin: -6px 0; }
.fr-empty { font-size: 11px; color: #78839a; }
.fr-card {
  display: grid;
  grid-template-columns: 22px 104px minmax(0, 1fr) 26px;
  grid-template-rows: auto auto;
  column-gap: 6px;
  row-gap: 4px;
  align-items: center;
  padding: 6px;
  background: #1c2332;
  border: 1px solid #2a3246;
  border-radius: 6px;
  min-width: 0;
}
.fr-card > * { min-width: 0; }
.fr-card.fr-done { opacity: 0.55; }
.fr-handle { grid-column: 1; grid-row: 1 / span 2; align-self: stretch; width: 22px; padding: 0; border: 0; border-radius: 4px; background: transparent; color: #6c788d; cursor: grab; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; }
.fr-handle:disabled { cursor: default; opacity: 0.5; }
.fr-pos { text-align: center; font-size: 11px; color: #78839a; }
.fr-card.fr-dragging { opacity: 0.5; }
.fr-drop-line { display: flex; align-items: center; height: 4px; margin: -5px 0 -5px; pointer-events: none; }
.fr-drop-mark { width: 8px; height: 8px; border-radius: 50%; border: 2px solid #4da6ff; box-sizing: border-box; }
.fr-drop-rule { flex: 1; height: 2px; background: #4da6ff; }
.fr-filter { grid-column: 2; grid-row: 1; display: flex; align-items: center; gap: 4px; }
.fr-dot { flex: 0 0 auto; width: 9px; height: 9px; border-radius: 50%; }
.fr-card select, .fr-card input { font-size: 11px; min-width: 0; }
.fr-card select.fr-filter-sel { flex: 1 1 0; width: 0; }
.fr-card select.fr-tmpl-sel { grid-column: 3; grid-row: 1; width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fr-remove { grid-column: 4; grid-row: 1; width: 26px; padding: 0; }
.fr-goal { grid-column: 2; grid-row: 2; display: flex; gap: 3px; }
.fr-card input.fr-goal-input { flex: 1 1 0; width: 0; }
.fr-card select.fr-unit-sel { flex: 0 0 auto; width: 42px; }
.fr-progress { grid-column: 3; grid-row: 2; }
.fr-bar { display: flex; height: 5px; background: #2a3246; border-radius: 3px; overflow: hidden; }
.fr-bar > i { display: block; height: 100%; background: #4da6ff; }
/* Rows a frame grader tracks: amber for accepted, amber stripes for shot but
   not yet graded, green once the goal is done. Same amber and green as the
   goal status badges (.goal-status.partial / .done). */
.fr-bar.fr-bar-grader > i { background: #c9a86a; }
.fr-card.fr-done .fr-bar > i { background: #5fb36a; }
.fr-pending-bar { display: block; height: 100%;
  background: repeating-linear-gradient(135deg, #c9a86a 0 3px, rgba(201, 168, 106, 0.25) 3px 6px); }
.fr-pending { font-size: 10px; color: #c9a86a; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fr-panel-list { display: flex; flex-wrap: wrap; gap: 3px 8px; font-size: 10px; color: #78839a; }
.fr-panel-done { color: #6fbf8a; }
.fr-panels { font-size: 10px; color: #78839a; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fr-prog-text { display: flex; justify-content: space-between; gap: 6px; font-size: 10px; color: #a2aec2; white-space: nowrap; overflow: hidden; }
.fr-add { align-self: flex-start; font-size: 11px; }

/* Above the list: the "Finish each" / "Rotate every N" switch, "Smart order"
   and one line saying what Target Scheduler will do. */
.fr-order { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin-bottom: 6px; font-size: 11px; max-width: 100%; }
.fr-switch { display: inline-flex; border: 1px solid #2a3246; border-radius: 6px; overflow: hidden; }
.fr-switch-opt { display: inline-flex; align-items: center; gap: 4px; padding: 3px 7px; white-space: nowrap; cursor: pointer; }
.fr-switch-opt:has(input[type=radio]:checked) { background: #24324a; color: #e6edf7; }
.fr-switch-opt input[type=radio] { margin: 0; }
.fr-rotate-n { width: 42px; font-size: 11px; }
.fr-smart { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.fr-order-text, .fr-order-note { flex: 1 0 100%; color: #78839a; }

.plan-editor-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  padding-top: 8px;
  border-top: 1px solid #1f2937;
}
.plan-editor-actions .btn-danger {
  background: #5a2030;
  color: #ffcccc;
  border-color: #7a3040;
  margin-right: auto;
}
.plan-editor-actions .btn-danger:hover { background: #7a3040; }

.drag-help {
  font-size: 11px;
  color: #78839a;
  margin-top: 4px;
}

.sync-warn {
  background: #4a2e1a;
  border: 1px solid #7a5030;
  color: #ffd8a0;
  padding: 8px 10px;
  border-radius: 4px;
  font-size: 12px;
  margin-bottom: 10px;
}
.sync-warn h4 { margin: 0 0 4px 0; color: #ffd8a0; }
.sync-warn .rename-row {
  display: flex;
  gap: 6px;
  align-items: center;
  margin-top: 6px;
}
.sync-warn .rename-row input { flex: 1; font-size: 12px; }

.plan-remaining-block {
  background: #0a0d12;
  border: 1px dashed #2a3246;
  border-radius: 4px;
  padding: 6px 8px;
  margin-top: 8px;
  font-size: 12px;
  color: #a2aec2;
}
.plan-remaining-block strong { color: #e8ecf3; font-weight: 600; }

/* Gap-finder block in the Catalogues accordion. */
.gap-finder {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-top: 4px;
}
.gap-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}
.gap-label {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: #a2aec2;
  font-size: 12px;
}
.gap-label.small { font-size: 0.85em; }
.gap-sources { margin-top: 2px; }
.gap-sources-label {
  color: #78839a;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 3px;
}
#gapSourcesList {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
#gapSourcesList .fchip {
  padding: 1px 5px;
  font-size: 11px;
}
#gapSourcesList .fchip input { transform: scale(0.85); }
.gap-stats {
  font-style: italic;
  color: #888;
  font-size: 11px;
  margin-top: 4px;
  min-height: 14px;
}
#gapHave, #gapMissing {
  padding: 2px 6px;
  font-size: 11px;
}

/* --- Catalog hover tooltip (objectHovered → near-cursor popover) --- */

.cat-tooltip {
  position: fixed;
  z-index: 9999;
  background: rgba(20, 26, 38, 0.95);
  border: 1px solid #2a3246;
  border-radius: 4px;
  padding: 4px 8px;
  font-size: 11px;
  color: #e0e4ea;
  pointer-events: none;
  max-width: 240px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
}
.cat-tooltip strong { color: #ffe27a; }
.cat-tooltip .cat-tag { color: #888; font-size: 10px; margin-left: 6px; }
.cat-tooltip .cat-extra { color: #a2aec2; font-size: 10px; margin-left: 6px; }

/* ----- Time-aware toggle (Plan A.2) ------------------------------------- */
/* Aria-pressed drives the visual state — `true` lights it up, `false` is a
   muted background. Generic enough to apply to other toggles later. */
.toggle-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px;
  background: #1a2030;
  border: 1px solid #2a3246;
  color: #a2aec2;
  border-radius: 12px;
  font-size: 12px;
  cursor: pointer;
  user-select: none;
}
.toggle-btn:hover { background: #212939; color: #e0e4ea; }
.toggle-btn[aria-pressed="true"] {
  background: #2a4f7a;
  border-color: #4a7ec0;
  color: #f0f5ff;
}
.toggle-btn[aria-pressed="true"]:hover { background: #345f92; }
.toggle-btn .toggle-icon { font-size: 12px; line-height: 1; }
.toggle-btn .toggle-lbl  { font-weight: 600; letter-spacing: 0.02em; }

/* When time-aware is OFF, hide every UI element that only makes sense with
   a time/site context. New time-aware widgets should add themselves to this
   selector list as they land. */
body:not([data-time-aware="on"]) #obsNow,
body:not([data-time-aware="on"]) .yc-sparkline,
body:not([data-time-aware="on"]) .yc-bar,
body:not([data-time-aware="on"]) .nn-chip,
body:not([data-time-aware="on"]) .tr-chips,
body:not([data-time-aware="on"]) .vis-section,
body:not([data-time-aware="on"]) option[data-time-aware] { display: none; }
/* Keep .sort-control itself visible even with time-aware off — priority/name
   sorts still apply. The time-aware-only options inside the <select> are
   hidden by the option[data-time-aware] rule above. */

/* ----- Year curve sparklines + best-month badges (Plan A.4) ------------- */
/* One cell per month, coloured by visibility label. The list-row variant is
   compact (8x6); the detail-panel variant grows to 16x14 and shows month
   labels underneath. Cell colours intentionally echo a traffic-light
   gradient so the eye scans the row left-to-right for "when's it good". */
.yc-sparkline {
  display: inline-grid;
  grid-template-columns: repeat(12, 8px);
  gap: 1px;
  vertical-align: middle;
  margin-right: 6px;
  /* let the current-month outline render outside its cell without being
     clipped by neighbouring cells. */
  padding: 2px;
}
.yc-sparkline .yc-cell {
  width: 8px;
  height: 10px;
  border-radius: 1px;
}
.yc-bar {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 2px;
  margin: 6px 0 4px;
  max-width: 360px;
}
.yc-bar .yc-cell {
  height: 22px;
  border-radius: 2px;
  position: relative;
  cursor: default;
}
.yc-bar .yc-mlabel {
  position: absolute;
  bottom: -14px;
  left: 0; right: 0;
  text-align: center;
  font-size: 9px;
  color: #78839a;
  pointer-events: none;
}
.yc-bar { padding-bottom: 16px; }
/* Visibility-label colour palette. Great pops as teal so it reads as
   distinctly "the best tier" rather than "slightly brighter green". */
.yc-cell.vc-not_visible { background: #1f242e; }
.yc-cell.vc-partial     { background: #4a4a55; }
.yc-cell.vc-fair        { background: #b9923c; }
.yc-cell.vc-good        { background: #6fcc52; }
.yc-cell.vc-great       { background: #46c5d4; }
/* Current-month indicator. Bright gold ring via box-shadow so it tracks
   the cell's border-radius and isn't clipped by neighbouring cells. The
   detail-panel bar adds a soft glow on top for extra emphasis. */
.yc-cell.vc-current {
  box-shadow: 0 0 0 2px #ffe27a;
  position: relative;
  z-index: 1;
}
.yc-bar .yc-cell.vc-current { box-shadow: 0 0 0 2px #ffe27a, 0 0 6px rgba(255, 226, 122, 0.5); }

/* Fractional fill — used for mosaic plans where each cell shows the
   fraction of panels visible that month. Vertical fill from below so the
   eye reads "how full is this month". --frac is set inline per cell. */
.yc-cell.yc-frac {
  background: linear-gradient(to top, #46c5d4 var(--frac, 0%), #1f242e var(--frac, 0%));
}

/* Pending state — shown while a plan visibility fetch is in flight. The
   sparkline grid stays the same width so the row doesn't reflow when data
   arrives, just fades. */
.yc-sparkline.yc-loading,
.yc-bar.yc-loading {
  opacity: 0.35;
  position: relative;
}
.yc-sparkline.yc-loading::after,
.yc-bar.yc-loading::after {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    90deg, transparent 0 4px, rgba(120, 131, 154, 0.25) 4px 8px);
  border-radius: 2px;
  animation: yc-loading-shift 1.2s linear infinite;
}
@keyframes yc-loading-shift {
  from { background-position: 0 0; }
  to   { background-position: 8px 0; }
}

/* Per-panel heatmap (mosaic plan editor) — rows = panels, cols = months,
   each cell uses the same vc-* palette as the aggregate bar. */
.vis-heatmap {
  display: flex;
  flex-direction: column;
  gap: 1px;
  margin-top: 8px;
  max-height: 240px;
  overflow-y: auto;
}
.vis-heatmap-row {
  display: grid;
  grid-template-columns: 24px repeat(12, 1fr);
  gap: 1px;
  align-items: center;
}
.vis-heatmap-row .yc-cell {
  height: 10px;
  border-radius: 1px;
}
.vis-heatmap-label {
  font-size: 10px;
  color: #78839a;
  text-align: right;
  padding-right: 3px;
  font-variant-numeric: tabular-nums;
}
.vis-aggregate { margin-top: 2px; }

/* Now / Trend chips on the row's second line. Same colour-codes as the
   sparkline so the eye reads "green = good" consistently. */
.nn-chip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 10px;
  border-radius: 8px;
  padding: 0 6px;
  line-height: 14px;
  border: 1px solid #2a3246;
  background: rgba(120,131,154,0.05);
  color: #a2aec2;
}
.nn-chip .nn-prefix { color: #6c7281; font-size: 9px; text-transform: uppercase; letter-spacing: 0.04em; }
.nn-chip.nn-great { color: #46c5d4; border-color: rgba(70, 197, 212, 0.40); background: rgba(70, 197, 212, 0.10); }
.nn-chip.nn-good  { color: #6fcc52; border-color: rgba(111, 204, 82, 0.35); background: rgba(111, 204, 82, 0.08); }
.nn-chip.nn-fair  { color: #d6b35c; border-color: rgba(214, 179, 92, 0.35);  background: rgba(214, 179, 92, 0.07); }
.nn-chip.nn-partial { color: #9aa3b3; border-color: #2a3246; background: rgba(120,131,154,0.05); }
.nn-chip.nn-not_visible { color: #6c7281; border-color: #2a3246; background: rgba(120,131,154,0.05); }
/* Trend chip variants — improving (green up), declining (orange down),
   steady (grey flat), upcoming (yellow/blue, "Peaks in Nm"). */
.nn-chip.nn-trend-up   { color: #8fc485; border-color: rgba(143, 196, 133, 0.35); background: rgba(143, 196, 133, 0.07); }
.nn-chip.nn-trend-down { color: #e0876f; border-color: rgba(224, 135, 111, 0.35); background: rgba(224, 135, 111, 0.07); }
.nn-chip.nn-trend-flat { color: #9aa3b3; border-color: #2a3246; background: rgba(120,131,154,0.05); }
.nn-chip.nn-trend-wait { color: #d6b35c; border-color: rgba(214, 179, 92, 0.35); background: rgba(214, 179, 92, 0.07); }

/* Visibility section in the target detail panel. */
.vis-section { margin-top: 8px; }
/* Each meta row pairs a left-aligned text line with a right-aligned chip,
   so Peak/Now-altitude framing matches NOW/Trend chips column-style. */
.vis-section .vis-meta-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 4px;
}
.vis-section .vis-meta {
  font-size: 11px;
  color: #78839a;
}
.vis-section .vis-now {
  font-size: 11px;
  color: #a2aec2;
}

/* Sort control inside the panel-list header. */
.sort-control {
  font-size: 11px;
  color: #78839a;
  margin-left: 6px;
}
.sort-control select {
  background: #1a2030;
  border: 1px solid #2a3246;
  color: #e0e4ea;
  padding: 1px 4px;
  border-radius: 3px;
  font-size: 11px;
  margin-left: 3px;
}

/* ----- Topbar icon buttons + sites modal (Plan A.1) ---------------------- */
.icon-btn {
  width: 22px;
  height: 22px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  line-height: 1;
  background: #1a2030;
  border: 1px solid #2a3246;
  color: #a2aec2;
  border-radius: 3px;
  cursor: pointer;
}
.icon-btn:hover { background: #212939; color: #e0e4ea; }

.acp-modal {
  background: #0f1319;
  color: #e0e4ea;
  border: 1px solid #2a3246;
  border-radius: 6px;
  padding: 16px 18px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
  min-width: 360px;
  max-width: 92vw;
}
.acp-modal::backdrop {
  background: rgba(0, 0, 0, 0.55);
}
.acp-modal h3 {
  margin: 0 0 12px;
  font-size: 14px;
  color: #e8ecf3;
}
.acp-modal form { display: flex; flex-direction: column; gap: 10px; }
.modal-row { display: flex; flex-direction: column; gap: 4px; font-size: 11px; color: #a2aec2; }
.modal-note { margin: 0 0 10px; font-size: 12px; color: #e0c36a; }
.modal-row.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.modal-row.two-col > label { display: flex; flex-direction: column; gap: 4px; font-size: 11px; color: #a2aec2; }
.modal-row > span,
.modal-row > label > span {
  font-size: 11px;
  color: #78839a;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.modal-row input {
  background: #1a2030;
  border: 1px solid #2a3246;
  color: #e0e4ea;
  padding: 5px 8px;
  border-radius: 3px;
  font-size: 12px;
  width: 100%;
}
.modal-row input:invalid { border-color: #c25b5b; }
.modal-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
}
.modal-actions .spacer { flex: 1; }
.modal-actions button.primary {
  background: #2a4f7a;
  border-color: #355d8e;
  color: #f0f5ff;
}
.modal-actions button.primary:hover { background: #345f92; }
.modal-actions button.danger {
  background: #4a1d1d;
  border-color: #6a2a2a;
  color: #f3c8c8;
}
.modal-actions button.danger:hover { background: #5a2424; }
.modal-error {
  background: #3a1d1d;
  border: 1px solid #6a2a2a;
  color: #f3c8c8;
  padding: 6px 10px;
  border-radius: 3px;
  font-size: 11px;
}

/* ----- Extensions rail + ext action modal ------------------------------ */
/* Buttons and toggles registered by out-of-tree extensions. The rail panel
   itself is hidden until at least one manifest entry shows up. */
.ext-row { margin: 4px 0; display: flex; flex-direction: column; gap: 4px; }
.ext-row button {
  padding: 4px 10px; font-size: 12px; cursor: pointer;
  background: #1d2532; border: 1px solid #2a3346; color: #d8e0ec; border-radius: 3px;
}
.ext-row button:hover { background: #243044; }
.ext-status {
  font-size: 10px; color: #78839a; padding-left: 4px; min-height: 14px;
  display: flex; align-items: center; gap: 6px;
}
.ext-status-running { color: #88c088; }
.ext-status-warn    { color: #c9a86a; }
.ext-status-error   { color: #d68585; }
.ext-status button {
  padding: 1px 6px; font-size: 10px; background: #3a2222; border-color: #5a3030;
}

/* Modal used for extension action flows (picker → preview → result). */
.ext-modal { min-width: 460px; max-width: 600px; }
.ext-modal-title { font-size: 14px; font-weight: 600; margin-bottom: 10px; color: #e0e4ea; }
.ext-modal-step { display: flex; flex-direction: column; gap: 10px; }
/* `display: flex` overrides the browser default for [hidden]; restore it
   explicitly so showStep()'s `step.hidden = true` actually hides the panel. */
.ext-modal-step[hidden] { display: none; }
.ext-hint {
  background: #1a2230; border: 1px solid #2a3a52; color: #a8c0e0;
  padding: 6px 10px; border-radius: 3px; font-size: 11px;
}
.ext-warn {
  background: #2a2418; border: 1px solid #4a3a1a; color: #d8c088;
  padding: 6px 10px; border-radius: 3px; font-size: 11px;
}
.ext-error {
  background: #3a1d1d; border: 1px solid #6a2a2a; color: #f3c8c8;
  padding: 6px 10px; border-radius: 3px; font-size: 11px;
}
.ext-ok {
  background: #1e2a1e; border: 1px solid #3a7a3a; color: #b0ffb0;
  padding: 6px 10px; border-radius: 3px; font-size: 12px; font-weight: 600;
}
.ext-progress { font-size: 11px; color: #78839a; font-style: italic; }
.ext-meta { font-size: 11px; color: #a2aec2; }
.ext-meta code { font-size: 10px; color: #c0c0c0; background: #11151c; padding: 1px 4px; border-radius: 2px; }
.ext-pre {
  font-size: 10px; background: #0a0d12; padding: 8px; border-radius: 3px;
  max-height: 240px; overflow: auto; color: #d8e0ec;
}
.ext-report { width: 100%; border-collapse: collapse; font-size: 11px; }
.ext-report th, .ext-report td {
  padding: 4px 8px; border-bottom: 1px solid #1a2030; text-align: left;
}
.ext-report th { color: #78839a; font-weight: 500; }
.ext-report td:not(:first-child) { text-align: right; font-variant-numeric: tabular-nums; }

/* Per-plan diff inside the preview modal. Scrollable so a sync touching many
   plans doesn't blow the modal off-screen; visual hierarchy is project →
   plan → change line. */
.ext-diff-scroll {
  max-height: 360px;
  overflow-y: auto;
  border: 1px solid #1a2030;
  border-radius: 3px;
  background: #0d1118;
  padding: 4px;
}
.ext-diff-group { padding: 6px 8px; border-bottom: 1px solid #141a24; }
.ext-diff-group:last-child { border-bottom: none; }
.ext-diff-group.ext-diff-insert { background: #1a2a1a; border-color: #2a3a2a; }
.ext-diff-proj {
  font-weight: 600; font-size: 12px; color: #d8e0ec; margin-bottom: 4px;
}
.ext-diff-shared {
  padding: 4px 8px; margin: 2px 0 6px 0; background: #11151c;
  border-left: 2px solid #2a4f7a; border-radius: 2px;
}
.ext-diff-meta { font-size: 10px; color: #78839a; margin-top: 3px; font-style: italic; }
.ext-diff-plan {
  padding: 4px 8px; margin: 2px 0; background: #11151c;
  border-left: 2px solid #2a3346; border-radius: 2px;
}
.ext-diff-target { font-size: 11px; color: #a2aec2; margin-bottom: 3px; }
.ext-diff-change {
  font-size: 11px; padding: 2px 0; display: flex; gap: 6px;
  align-items: baseline; flex-wrap: wrap;
}
.ext-diff-label { color: #78839a; min-width: 110px; }
.ext-diff-from { color: #c9a86a; font-variant-numeric: tabular-nums; }
.ext-diff-to   { color: #88c088; font-variant-numeric: tabular-nums; font-weight: 600; }
.ext-diff-arrow { color: #5a657a; }
.ext-diff-unchanged {
  margin-top: 6px; font-size: 11px; color: #78839a;
  background: #0d1118; border: 1px solid #1a2030; border-radius: 3px; padding: 4px 8px;
}
.ext-diff-unchanged summary { cursor: pointer; user-select: none; }
.ext-diff-unchanged-list {
  margin-top: 6px; max-height: 200px; overflow-y: auto;
  padding-left: 12px;
}
.ext-diff-unchanged-list > div { padding: 1px 0; }

/* Bidirectional Sync with NINA modal — overlays multiple diff sections
   (Outgoing / Incoming / Conflicts / New / Notes), each independently
   scrollable so the modal stays a reasonable height. */
.ext-bidi-section { margin: 8px 0; }
.ext-bidi-head {
  font-size: 11px; color: #a2aec2; padding: 4px 0;
  display: flex; align-items: center; gap: 8px;
  border-bottom: 1px solid #1a2030;
  margin-bottom: 4px;
}
.ext-bidi-count {
  background: #1a2030; color: #d8e0ec;
  padding: 1px 6px; border-radius: 8px; font-size: 10px;
  font-variant-numeric: tabular-nums;
}
.ext-bidi-sub { color: #5a657a; font-style: italic; font-size: 10px; }
.ext-bidi-out  .ext-bidi-head { color: #c9a86a; }
.ext-bidi-in   .ext-bidi-head { color: #88c088; }
.ext-bidi-conflict .ext-bidi-head { color: #d68585; }
.ext-bidi-new  .ext-bidi-head { color: #a8c0e0; }
.ext-bidi-notes {
  font-size: 11px; color: #a2aec2;
  margin: 4px 0; padding-left: 18px;
}
.ext-diff-arrow-out { color: #c9a86a; }
.ext-diff-arrow-in  { color: #88c088; }

/* Conflict card — one per plan with a conflicting field. Inline picker. */
.ext-conflict-card {
  padding: 6px 8px; margin: 4px 0;
  background: #1a1418; border: 1px solid #3a2222; border-radius: 3px;
}
.ext-conflict-field {
  display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
  font-size: 11px; padding: 2px 0;
}
.ext-conflict-field .ext-diff-label { min-width: 110px; }
.ext-conflict-acp { color: #c9a86a; font-variant-numeric: tabular-nums; }
.ext-conflict-ts  { color: #88c088; font-variant-numeric: tabular-nums; }
.ext-conflict-buttons {
  margin-top: 6px; display: flex; gap: 4px; flex-wrap: wrap;
}
.ext-conflict-buttons label {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 8px; font-size: 11px; cursor: pointer;
  background: #11151c; border: 1px solid #2a3346; border-radius: 3px;
  user-select: none;
}
.ext-conflict-buttons label.selected { background: #2a4f7a; border-color: #355d8e; color: #f0f5ff; }
.ext-conflict-buttons label input { margin: 0; }

/* ts_only_new — import-checkbox rows. */
.ext-tsnew-row {
  display: flex; gap: 8px; align-items: flex-start;
  padding: 4px 6px; cursor: pointer; font-size: 11px;
  border-radius: 3px;
}
.ext-tsnew-row:hover { background: #11151c; }
.ext-tsnew-row input { margin-top: 2px; }

.ext-profile-list { display: flex; flex-direction: column; gap: 6px; }
.ext-profile-row {
  display: flex; align-items: center; gap: 10px; padding: 8px;
  background: #11151c; border: 1px solid #1a2030; border-radius: 3px;
  cursor: pointer;
}
.ext-profile-row:hover { background: #141a24; }
.ext-profile-row:has(input:checked) { border-color: #2a4f7a; background: #1a2230; }
.ext-profile-pid { font-family: monospace; font-size: 10px; color: #a2aec2; }
.ext-profile-meta { font-size: 11px; color: #d8e0ec; margin-top: 2px; }

/* Extension input_schema form (collected before /preview is called) */
.ext-inputs-form { display: flex; flex-direction: column; gap: 10px; }
.ext-input-row { display: flex; flex-direction: column; gap: 4px; }
.ext-input-label { font-size: 11px; color: #d8e0ec; }
.ext-input-req { color: #ff7676; font-weight: bold; }
.ext-input-control {
  background: #11151c; color: #e6edf6;
  border: 1px solid #2a3344; border-radius: 3px;
  padding: 5px 7px; font-size: 12px;
}
.ext-input-control:focus { outline: none; border-color: #4a7ec7; }
input[type="checkbox"].ext-input-control { width: auto; align-self: start; }
.ext-input-help { font-size: 10px; color: #8b95a8; }
.ext-input-error { font-size: 10px; color: #ff7676; }

/* Extension modal header (title + close X) and footer nav (Back / primary).
   Replaces the per-step Cancel buttons — one nav row owns the action
   button for all steps; JS rebinds its label + handler each step. */
.ext-modal-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 10px;
}
.ext-modal-close {
  background: transparent; color: #a2aec2; border: none;
  font-size: 20px; line-height: 1; cursor: pointer; padding: 2px 8px;
}
.ext-modal-close:hover { color: #e6edf6; }
.ext-modal-nav {
  display: flex; align-items: center; gap: 8px; margin-top: 12px;
  padding-top: 10px; border-top: 1px solid #1a2030;
}
.ext-modal-nav-spacer { flex: 1; }
.ext-modal-back {
  background: transparent; color: #d8e0ec;
  border: 1px solid #2a3344; border-radius: 3px;
  padding: 5px 11px; font-size: 12px; cursor: pointer;
}
.ext-modal-back:hover { background: #1a2030; }
.ext-modal-back[hidden] { display: none; }

/* Cross-catalogue Object filter — sits under #catChips inside the
   Catalogues accordion. Type chips aggregate categories across every
   enabled CategorisedCatalogSource; the filter input accepts the
   standard token search syntax (class:PNe -tag:done "phrase"). */
.cat-objects {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px dashed #1a2030;
  display: flex; flex-direction: column; gap: 6px;
}
.cat-objects[hidden] { display: none; }
.cat-objects-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.cat-objects-row[hidden] { display: none; }
.cat-objects-lbl { font-size: 10px; color: #a2aec2; min-width: 38px; }
.cat-objects-chips { display: flex; flex-wrap: wrap; gap: 4px; }
.cat-objects-chips label.fchip { font-size: 10px; }
#catObjectsFilter {
  flex: 1;
  background: #11151c; color: #e6edf6;
  border: 1px solid #2a3344; border-radius: 3px;
  padding: 4px 7px; font-size: 11px;
}
#catObjectsFilter:focus { outline: none; border-color: #4a7ec7; }
.cat-objects-hint { font-size: 10px; color: #8b95a8; }
.cat-objects-hint[hidden] { display: none; }

/* Progress bar shown during streaming preview load. The explicit
   [hidden] selector is required because `display: flex` overrides the
   user-agent default `[hidden] { display: none }`. */
.ext-progress-wrap { display: flex; flex-direction: column; gap: 6px; }
.ext-progress-wrap[hidden] { display: none; }
.ext-progress-label { font-size: 11px; color: #d8e0ec; }
.ext-progress-track {
  width: 100%; height: 6px;
  background: #11151c; border: 1px solid #1a2030; border-radius: 3px;
  overflow: hidden;
}
.ext-progress-bar {
  height: 100%;
  background: #4a7ec7;
  width: 0%;
  transition: width 120ms linear;
}

/* ----- Inventory rail panel (Plan 4b) ----------------------------------- */
/* Each tile source = one collapsible block. Header = toggle + label;
   body = filter chips for priority / missing-bands / categories + a
   "N of M tiles shown" counter. */
.inv-source { margin: 4px 0; padding: 6px; border: 1px solid #1a2030; border-radius: 4px; background: #11151c; }
.inv-source-head {
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  user-select: none;
}
.inv-source-head .swatch {
  display: inline-block; width: 10px; height: 10px; border-radius: 2px;
  border: 1px solid rgba(255,255,255,0.15);
}
.inv-source-head .label { font-weight: 600; color: #e0e4ea; flex: 1; }
.inv-source-head .count { font-size: 11px; color: #78839a; font-variant-numeric: tabular-nums; }
.inv-source-body {
  margin-top: 6px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 11px;
}
.inv-source[data-open="false"] .inv-source-body { display: none; }
.inv-row { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }
.inv-row .inv-row-lbl {
  color: #78839a;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-right: 4px;
  min-width: 56px;
}
/* Priority chip — coloured ring per level. The first 4 levels carry a
   distinct hue; levels 5+ all read as "lower priority" grey. */
.inv-pri {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 1px 6px; border-radius: 8px;
  background: rgba(120,131,154,0.06);
  border: 1px solid #2a3246;
  color: #a2aec2;
  font-size: 10px;
  cursor: pointer;
  user-select: none;
}
.inv-pri input { margin: 0; }
.inv-pri.pri-1 { color: #ff8a8a; border-color: rgba(255, 138, 138, 0.40); }
.inv-pri.pri-2 { color: #ffb877; border-color: rgba(255, 184, 119, 0.40); }
.inv-pri.pri-3 { color: #ffe27a; border-color: rgba(255, 226, 122, 0.40); }
.inv-pri.pri-4 { color: #9aa3b3; border-color: #2a3246; }
.inv-pri.pri-other { color: #6c7281; border-color: #2a3246; }

/* Extension-declared facet chips: a coloured square swatch sits left
   of the label so the rail doubles as a legend for the facet's colour
   coding (matches whatever the source's color_facet paints onto tiles). */
.facet-chip { gap: 4px; }
.facet-swatch {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 2px;
  border: 1px solid rgba(255,255,255,0.15);
}
.tile-facet-badges {
  display: flex; flex-wrap: wrap; gap: 4px;
  margin: 6px 0 10px;
}

.inv-saved-row .inv-saved-select {
  background: #1a2030;
  border: 1px solid #2a3246;
  color: #e0e4ea;
  font-size: 11px;
  padding: 1px 4px;
  border-radius: 3px;
  flex: 1;
  min-width: 100px;
  max-width: 180px;
}
.inv-saved-row .link-btn[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
}

.tile-actions {
  margin-top: 12px;
  padding: 10px;
  background: #11151c;
  border: 1px solid #1a2030;
  border-radius: 4px;
}
.tile-suggestion {
  font-size: 11px;
  color: #a2aec2;
  margin-bottom: 8px;
}
.tile-suggestion code {
  background: rgba(120,131,154,0.10);
  border: 1px solid #2a3246;
  border-radius: 3px;
  padding: 0 4px;
  font-size: 11px;
  color: #e0e4ea;
}
#tileCreatePlan.primary {
  background: #2a4f7a;
  border-color: #355d8e;
  color: #f0f5ff;
  padding: 6px 12px;
  width: 100%;
  font-size: 12px;
}
#tileCreatePlan.primary:hover { background: #345f92; }

/* Plan ↔ tile cross-ref status row in the tile detail panel. */
.tile-plan-row {
  margin-top: 8px;
  padding: 6px 10px;
  background: #11151c;
  border: 1px solid #2a3246;
  border-radius: 4px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
}
.tile-plan-state {
  flex: 1;
  color: #e0e4ea;
  font-weight: 600;
}
.tile-plan-state.tps-queued      { color: #d6a04a; }
.tile-plan-state.tps-in_progress { color: #5bb6ff; }
.tile-plan-state.tps-done        { color: #6fcc52; }
.link-btn {
  background: transparent;
  border: 1px solid #2a3246;
  color: #a2aec2;
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 3px;
  cursor: pointer;
}
.link-btn:hover { color: #e0e4ea; border-color: #3a4458; }

/* TS upload banner: a slim full-width row under the toolbar, filled by
   loadTsSyncBanner() in app.js. Hidden by default (the [hidden] rule),
   so a fresh page load with nothing pending reserves no space and the
   layout doesn't shift; it only grows the topbar by one row once there's
   something to show. */
.ts-sync-banner {
  flex-basis: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 14px;
  padding: 5px 8px;
  font-size: 11px;
  color: #f0c674;
  background: #241b0d;
  border: 1px solid #4a3b1a;
  border-radius: 4px;
}
.ts-sync-banner[hidden] { display: none; }
.ts-sync-line { white-space: normal; }
.ts-sync-link {
  color: #6aa6ff;
  text-decoration: underline;
}
.ts-sync-link:hover { color: #88baff; }
.ts-sync-more {
  color: #a2aec2;
  font-style: italic;
}

/* --- Onboarding banner (shown when manifest is empty) --- */
.onboarding-banner {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 50;
  background: rgba(10, 14, 22, 0.78);
  backdrop-filter: blur(2px);
  pointer-events: auto;
}
.onboarding-banner[hidden] { display: none; }
.onboarding-banner-inner {
  max-width: 560px;
  padding: 28px 32px 32px;
  background: #14192a;
  border: 1px solid #2a3246;
  border-radius: 8px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
  color: #e0e4ea;
  position: relative;
}
.onboarding-banner-inner h2 {
  margin: 0 0 12px;
  font-size: 20px;
  font-weight: 600;
  color: #f0f3f8;
}
.onboarding-banner-inner p {
  margin: 0 0 12px;
  font-size: 13px;
  line-height: 1.55;
  color: #b6bdcd;
}
.onboarding-banner-inner p:last-of-type { margin-bottom: 16px; }
.onboarding-banner-inner a {
  color: #6aa6ff;
  text-decoration: underline;
}
.onboarding-banner-inner a:hover { color: #88baff; }
.onboarding-banner-inner code {
  background: #0d111c;
  border: 1px solid #2a3246;
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 12px;
  color: #c8d1e0;
}
.onboarding-step strong {
  color: #f0f3f8;
}
.onboarding-demo {
  font-size: 12px !important;
  color: #8c95a8 !important;
  border-top: 1px solid #2a3246;
  padding-top: 12px;
}
.onboarding-dismiss {
  position: absolute;
  top: 8px;
  right: 12px;
  background: transparent;
  border: 1px solid #2a3246;
  color: #8c95a8;
  font-size: 11px;
  padding: 3px 10px;
  border-radius: 3px;
  cursor: pointer;
}
.onboarding-dismiss:hover { color: #e0e4ea; border-color: #3a4458; }

/* NINA rigs rail: one read-only block per NINA profile that has asked
   /api/plans/match which plans its gear can shoot. */
.rig-row {
  padding: 5px 0;
  border-bottom: 1px solid #1b2230;
}
.rig-row:last-child { border-bottom: none; }
.rig-name {
  font-size: 12px;
  color: #e0e4ea;
}
.rig-meta {
  font-size: 11px;
  color: #888;
}

/* Scan health accordion */
.health-row { display: flex; justify-content: space-between; gap: 8px; padding: 2px 0; font-size: 12px; }
.health-row .num { color: #c9d1e0; }
.health-sub { color: #78839a; font-size: 11px; margin: 6px 0 2px; }
.health-paths { margin: 0 0 6px 8px; }
.health-path { color: #78839a; font-size: 10px; line-height: 1.4; direction: rtl; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.health-table { width: 100%; font-size: 11px; border-collapse: collapse; }
.health-table td { padding: 1px 0; }
.health-table td.num { text-align: right; color: #9aa3b5; white-space: nowrap; }
.health-report { display: inline-block; margin-top: 6px; font-size: 11px; color: #8fb4ff; }
.health-badge { display: inline-block; min-width: 16px; padding: 0 5px; margin-left: 6px; border-radius: 8px; background: #b8862b; color: #0a0d12; font-size: 10px; font-weight: 700; text-align: center; }

/* --- Plan list: Plans / Projects switch, status chips, project rows --- */

/* The main switch for the plan list, so it is full width, taller than the
   chips below it and filled when active. */
.plan-view-toggle {
  display: flex;
  margin-bottom: 10px;
  border: 1px solid #3a4458;
  border-radius: 6px;
  overflow: hidden;
}
.plan-view-toggle button {
  flex: 1 1 0;
  padding: 8px 10px;
  border: 0;
  border-radius: 0;
  background: #141a24;
  color: #a2aec2;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.plan-view-toggle button + button { border-left: 1px solid #3a4458; }
.plan-view-toggle button:hover { background: #1a2030; color: #e0e4ea; }
.plan-view-toggle button[aria-pressed="true"] { background: #2d4a7c; color: #fff; }
.plan-view-toggle .n {
  margin-left: 6px;
  font-weight: 400;
  opacity: 0.75;
  font-variant-numeric: tabular-nums;
}

.plan-search {
  width: 100%;
  margin-bottom: 8px;
  padding: 5px 8px;
  font-size: 13px;
  background: #0a0d12;
  border: 1px solid #2a3246;
  color: #e0e4ea;
  border-radius: 3px;
}
.plan-search:focus { outline: none; border-color: #4da6ff; }

.plan-state-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 5px;
  margin-bottom: 6px;
}
.state-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px;
  border-radius: 12px;
  font-size: 12px;
  background: #1a2030;
  border: 1px solid #2a3246;
  color: #a2aec2;
  cursor: pointer;
}
.state-chip .sw { width: 7px; height: 7px; border-radius: 50%; }
.state-chip .c { color: #78839a; font-variant-numeric: tabular-nums; }
.state-chip[aria-pressed="true"] { background: #223150; border-color: #3a5a94; color: #fff; }
.state-chip[aria-pressed="true"] .c { color: #b9c8e6; }
.state-chip.zero:not([aria-pressed="true"]) { opacity: 0.55; }
.plan-state-chips .link-btn { border: 0; color: #7fb3ff; text-decoration: underline; }

.plan-list-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 4px;
  font-size: 12px;
  color: #78839a;
}
.plan-list-meta .sort-control { margin-left: auto; }

.plan-row:focus-visible { outline: 2px solid #4da6ff; outline-offset: -2px; }
.plan-state-badge.plan-state-draft { color: #f0c98a; background: #3a2e17; }

.proj-group { border-bottom: 1px solid #1f2937; }
.proj-row {
  display: grid;
  grid-template-columns: 14px 1fr auto;
  column-gap: 8px;
  row-gap: 5px;
  align-items: center;
  width: 100%;
  padding: 8px 6px;
  border: 0;
  border-radius: 4px;
  background: none;
  color: #e0e4ea;
  text-align: left;
  font: inherit;
  cursor: pointer;
}
.proj-row:hover { background: #1a2030; }
.proj-caret {
  display: inline-block;
  color: #78839a;
  font-size: 10px;
  transition: transform 0.12s ease;
}
.proj-group[data-open="true"] .proj-caret { transform: rotate(90deg); }
.proj-name {
  font-size: 14px;
  font-weight: 600;
  color: #e8ecf3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.proj-count {
  font-size: 12px;
  color: #a2aec2;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.proj-line2 {
  grid-column: 2 / -1;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  font-size: 11px;
  color: #78839a;
}
.proj-line2 .plan-remaining { margin-left: auto; white-space: nowrap; }
.state-mix {
  display: inline-flex;
  flex: 0 0 auto;
  width: 46px;
  height: 6px;
  border-radius: 3px;
  overflow: hidden;
  background: #1d2433;
}
.state-mix i { display: block; height: 100%; }
.state-mix-txt { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.plan-progress {
  display: block;
  flex: 1 1 auto;
  min-width: 40px;
  height: 6px;
  border-radius: 3px;
  overflow: hidden;
  background: #1d2433;
}
.plan-progress i { display: block; height: 100%; background: #4f8a5f; }
.proj-kids {
  list-style: none;
  margin: 0 0 6px 20px;
  padding: 0 0 0 6px;
  border-left: 1px solid #2a3246;
}
.proj-kids .plan-row { padding: 5px 6px; font-size: 12px; }

/* The "⋯" row menu. The button has its own narrow column at the row's far
   right, centred across both lines, so it never sits on top of the hours,
   the filter dots or the time-aware column. Always there, faint until the
   row is hovered or the button has focus. Hidden rows are only listed
   while Show hidden is on, and are drawn faded. */
.row-menu-btn {
  width: 22px;
  height: 20px;
  padding: 0;
  font-size: 16px;
  line-height: 1;
  color: #a2aec2;
  background: none;
  border: 1px solid transparent;
  border-radius: 4px;
  cursor: pointer;
  opacity: 0.4;
}
.target-row:hover > .row-menu-btn,
.plan-row:hover > .row-menu-btn,
.proj-group:hover > .row-menu-btn,
.mark-finished-row .row-menu-btn { opacity: 0.75; }
.row-menu-btn:hover,
.row-menu-btn:focus-visible,
.row-menu-btn[aria-expanded="true"] {
  opacity: 1;
  color: #e0e4ea;
  background: #232b3c;
  border-color: #3a4458;
}
.target-row > .row-menu-btn,
.plan-row > .row-menu-btn { grid-column: -2; grid-row: 1 / -1; align-self: center; }
.proj-group {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 22px;
  column-gap: 4px;
  align-items: center;
}
.proj-group > .proj-row { grid-column: 1; }
.proj-group > .row-menu-btn { grid-column: 2; grid-row: 1; }
.proj-group > .proj-kids { grid-column: 1 / -1; }
.is-hidden > :not(.row-menu-btn):not(.proj-kids) { opacity: 0.45; }

.row-menu {
  position: fixed;
  z-index: 1000;
  min-width: 150px;
  padding: 4px;
  background: #141a26;
  border: 1px solid #3a4458;
  border-radius: 6px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.5);
}
.row-menu-item {
  display: block;
  width: 100%;
  padding: 5px 10px;
  font: inherit;
  font-size: 12px;
  text-align: left;
  color: #e0e4ea;
  background: none;
  border: 0;
  border-radius: 4px;
  cursor: pointer;
}
.row-menu-item:hover,
.row-menu-item:focus { background: #232b3c; outline: none; }
.row-menu-item[aria-disabled="true"] { color: #78839a; cursor: default; background: none; font-style: italic; }
.hidden-via { margin-left: 6px; font-size: 10px; color: #78839a; }
.hidden-toggle-row { margin: 2px 0 6px; }
.filter-hide-note { margin: 2px 0 6px; font-size: 12px; color: #a2aec2; }
.filter-hide-note .link-btn { border: 0; color: #7fb3ff; text-decoration: underline; }
.hidden-toggle[hidden] { display: none; }
.hidden-toggle[aria-pressed="true"] { color: #e0e4ea; border-color: #4da6ff; }
.hidden-note { font-size: 12px; color: #78839a; margin: 4px 0 8px; }

/* Rotation unknown: a rotation arrow struck through, at the right end of the
   filter pill row. Brightens when hovered, focused or open. */
.pill-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 6px; flex-wrap: wrap; }
.rot-unknown {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0;
  background: transparent; border: 1px solid #4a5468; border-radius: 4px;
  color: #c9d0dc; cursor: pointer;
}
.rot-unknown:hover, .rot-unknown:focus-visible, .rot-unknown[aria-expanded="true"] { color: #ffffff; border-color: #9aa3b5; }
.rot-unknown:focus-visible { outline: 2px solid #4da6ff; outline-offset: 1px; }
.rot-unknown-note { flex-basis: 100%; font-size: 12px; color: #9aa3b5; margin: 4px 0 0; }
.rot-unknown-note[hidden] { display: none; }

/* Plan editor card notes (docs/specs/gear-templates.md section 7) */
.fr-notes { grid-column: 2 / span 3; grid-row: 3; display: flex; flex-wrap: wrap; gap: 2px 10px; font-size: 10px; color: #8d99ad; }
.fr-flag-warn { color: #f0c46a; }

/* Gear button badge: held template conflicts (section 6) */
.gear-badge { display: inline-block; min-width: 16px; margin-left: 6px; padding: 0 5px; border-radius: 999px; background: #d64545; color: #fff; font-size: 10px; font-weight: 700; line-height: 16px; text-align: center; vertical-align: 1px; }
.gear-badge[hidden] { display: none; }

/* Gear editor (docs/specs/gear-templates.md section 6, the approved Main and Telescopes artboards) */
.ge { display: flex; flex-direction: column; min-height: 0; flex: 1; font-size: 12px; color: #e0e4ea; }
.ge button, .ge input, .ge select { font-family: inherit; }
.ge-head { display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-bottom: 1px solid #1f2937; }
.ge-head a { font-size: 12px; text-decoration: none; margin: 0; }
.ge-head h2 { margin: 0; flex: 1; font-size: 14px; color: #e8ecf3; text-align: center; }
.ge-save { height: 30px; padding: 0 12px; border: 0; border-radius: 6px; background: #2f6fd6; color: #fff; font-size: 12px; font-weight: 600; cursor: pointer; }
.ge-save:disabled { opacity: 0.6; cursor: default; }
.ge-tabs { display: flex; gap: 4px; padding: 10px 14px 0; }
.ge-tab { flex: 1; text-align: center; padding: 8px 0; font-size: 12px; color: #8d99ad; background: transparent; border: 0; border-bottom: 2px solid transparent; cursor: pointer; }
.ge-tab[aria-selected="true"] { color: #e8ecf3; font-weight: 600; border-bottom-color: #7fb2ff; }
.ge-body { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 12px 14px 16px; display: flex; flex-direction: column; gap: 10px; min-height: 0; }
.ge-banner { padding: 8px 10px; border-radius: 6px; font-size: 11px; line-height: 1.5; background: #3a2e14; color: #f0c46a; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ge-banner.ge-info { background: #1a2c4a; color: #9cc4ff; }
.ge-banner button { height: 24px; padding: 0 8px; border: 1px solid currentColor; border-radius: 5px; background: transparent; color: inherit; font-size: 11px; cursor: pointer; }
.ge-card { border: 1px solid #263044; border-radius: 8px; background: #121821; min-width: 0; }
.ge-card-top { padding: 10px 12px; display: flex; flex-direction: column; gap: 8px; border-bottom: 1px solid #1f2937; }
.ge-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
.ge-caret { font-size: 11px; color: #8d99ad; }
.ge-card input[type=text], .ge-card input[type=number], .ge-card select { box-sizing: border-box; background: #0f1319; border: 1px solid #263044; border-radius: 6px; color: #e0e4ea; font-size: 12px; padding: 0 6px; height: 28px; min-width: 0; }
.ge-card input:disabled { opacity: 0.5; }
.ge-name { flex: 1; height: 30px !important; font-size: 13px !important; font-weight: 600; color: #e8ecf3 !important; padding: 0 8px !important; }
.ge-icon-btn { width: 30px; height: 30px; border: 1px solid #263044; border-radius: 6px; background: transparent; color: #8d99ad; cursor: pointer; flex: none; }
.ge-menu-wrap { position: relative; flex: none; }
.ge-menu { position: absolute; right: 0; top: 34px; z-index: 5; min-width: 170px; display: flex; flex-direction: column; background: #161d28; border: 1px solid #263044; border-radius: 6px; padding: 4px; box-shadow: 0 6px 18px rgba(0, 0, 0, 0.5); }
.ge-menu button { text-align: left; padding: 6px 8px; border: 0; border-radius: 4px; background: transparent; color: #e0e4ea; font-size: 12px; cursor: pointer; }
.ge-menu button:hover { background: #1f2a3b; }
.ge-menu button.ge-danger { color: #e08a8a; }
.ge-grid3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.ge-grid4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
.ge-field { display: flex; flex-direction: column; gap: 3px; font-size: 10px; color: #8d99ad; min-width: 0; }
.ge-field-wide { grid-column: 1 / -1; }
.ge-muted { font-size: 11px; color: #8d99ad; }
.ge-warn { color: #f0c46a; }
.ge-filters { padding: 10px 12px 12px; display: flex; flex-direction: column; gap: 10px; }
.ge-filters-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.ge-eyebrow { font-size: 11px; font-weight: 700; letter-spacing: 0.06em; color: #a2aec2; }
.ge-legend { font-size: 10px; color: #6c788d; }
.ge-box { border: 1px solid #1f2937; border-radius: 6px; overflow: hidden; }
.ge-box-head { display: flex; align-items: center; gap: 8px; padding: 6px 8px; background: #161d28; flex-wrap: wrap; }
.ge-fname { font-size: 12px; font-weight: 700; color: #e8ecf3; min-width: 38px; }
.ge-wnote { font-size: 10px; color: #8d99ad; flex: 1; min-width: 0; }
.ge-pill { font-size: 10px; padding: 2px 6px; border-radius: 999px; white-space: nowrap; background: #1a2c4a; color: #9cc4ff; }
.ge-pill.ge-pill-in_ts { background: #173326; color: #7fd6a6; }
.ge-pill.ge-pill-new { background: #3a2e14; color: #f0c46a; }
.ge-pill.ge-pill-changed { background: #1a2c4a; color: #9cc4ff; }
.ge-pill.ge-pill-waiting { background: #232a36; color: #9aa6ba; }
.ge-pill.ge-pill-conflict { background: #4a1f1f; color: #f29a9a; }
.ge-pill.ge-pill-wheel { background: #232a36; color: #9aa6ba; }
.ge-dashed { height: 24px; padding: 0 8px; border: 1px dashed #36425a; border-radius: 5px; background: transparent; color: #7fb2ff; font-size: 11px; cursor: pointer; }
.ge-dashed-lg { height: 34px; width: 100%; border: 1px dashed #36425a; border-radius: 6px; background: transparent; color: #7fb2ff; font-size: 12px; cursor: pointer; }
.ge-x { height: 24px; width: 24px; padding: 0; border: 0; background: transparent; color: #6c788d; cursor: pointer; font-size: 12px; }
.ge-x:disabled { opacity: 0.3; cursor: default; }
.ge-tpl { border-top: 1px solid #1a2230; }
.ge-line { width: 100%; display: grid; grid-template-columns: 12px minmax(0, 1fr) auto auto; align-items: center; column-gap: 8px; padding: 7px 8px; background: transparent; border: 0; color: #e0e4ea; text-align: left; cursor: pointer; }
.ge-tpl.ge-open .ge-line { background: #18212e; }
.ge-star { font-size: 11px; color: #f2c94c; }
.ge-tname { min-width: 0; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ge-tsub { font-size: 12px; color: #c9d2e0; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ge-editor { padding: 8px 10px 10px 28px; background: #0f1520; display: flex; flex-direction: column; gap: 8px; }
.ge-check { display: flex; align-items: center; gap: 6px; font-size: 11px; color: #c9d2e0; }
.ge-note { font-size: 11px; color: #8d99ad; line-height: 1.5; }
.ge-impact { font-size: 11px; color: #c9d2e0; line-height: 1.5; }
.ge-btns { display: flex; gap: 6px; flex-wrap: wrap; }
.ge-btn { height: 28px; padding: 0 10px; border: 1px solid #263044; border-radius: 6px; background: transparent; color: #c9d2e0; font-size: 11px; cursor: pointer; }
.ge-btn.ge-danger { border-color: #4a2b2b; color: #e08a8a; }
.ge-btn:disabled { opacity: 0.45; cursor: default; }
.ge-summary { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border: 1px solid #263044; border-radius: 8px; background: #121821; color: #e0e4ea; text-align: left; cursor: pointer; width: 100%; }
.ge-summary .ge-sname { flex: 1; min-width: 0; font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ge-swatch { width: 12px; height: 12px; border-radius: 3px; flex: none; }
.ge-card input[type=color] { width: 30px; height: 30px; padding: 0; border: 1px solid #263044; border-radius: 6px; background: transparent; flex: none; }
.ge-add-filter { display: flex; flex-direction: column; gap: 6px; padding: 8px; border: 1px dashed #36425a; border-radius: 6px; }
.ge-add-filter .ge-btns { align-items: center; }
.ge-linkrow { display: flex; gap: 6px; flex-wrap: wrap; }
/* === Activity tab ===
   Opens at 560 px where the screen allows (the other tabs stay 380 px), and
   takes the whole map area below 760 px. Palette and rows follow the approved
   mockup, inside the panel's own tokens. */
.side-tab[data-tab="activity"] { overflow-y: auto; }
.panel.is-activity { --side-panel-w: 560px; }
@media (max-width: 760px) {
  .panel.is-activity { left: 0; width: auto; max-width: none; }
}
.rail-dot {
  position: absolute;
  top: 6px;
  right: 14px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #4da6ff;
}
.rail-dot[hidden] { display: none; }

.activity {
  font-size: 13px;
  line-height: 1.45;
  color: #e0e4ea;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}
.activity .act-scroll { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.activity a { color: #7fb2ff; }
.activity a:hover { color: #a9cbff; }
.activity fieldset.box {
  margin: 0;
  border: 1px solid #263044;
  border-radius: 6px;
  padding: 10px 12px 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}
.activity fieldset.box legend {
  padding: 0 6px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: #a2aec2;
}
.activity .night-line { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 12px; color: #a2aec2; }
.activity .night-line b { color: #e8ecf3; font-weight: 600; font-variant-numeric: tabular-nums; }
.activity .shot { display: flex; flex-direction: column; gap: 6px; }
.activity .shot-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2px 10px;
  align-items: center;
  padding: 6px 8px;
  border: 1px solid #222a3a;
  border-radius: 6px;
  background: #121822;
}
.activity .shot-row .name { font-weight: 600; color: #e8ecf3; min-width: 0; overflow-wrap: anywhere; }
.activity .shot-row .hrs { font-variant-numeric: tabular-nums; color: #e8ecf3; text-align: right; }
.activity .shot-row .detail {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: #8d99ad;
}
/* One filter: dot, name, bar and figures stay on one line and wrap together. */
.activity .shot-row .fl { display: flex; align-items: center; gap: 6px; flex: 1 1 240px; min-width: 0; white-space: nowrap; }
.activity .dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: #8d99ad; flex: 0 0 auto; }
.activity .dot.f-ha { background: #ff6b6b; }
.activity .dot.f-oiii { background: #4da6ff; }
.activity .dot.f-sii { background: #ffd84d; }
.activity .dot.f-l { background: #d0d0d0; }
.activity .dot.f-r { background: #ff8080; }
.activity .dot.f-g { background: #80ff80; }
.activity .dot.f-b { background: #8080ff; }
.activity .bar { height: 4px; border-radius: 2px; background: #222a3a; overflow: hidden; flex: 1 1 80px; min-width: 60px; }
.activity .bar i { display: block; height: 100%; background: #d9b44a; }
.activity .bar i.done { background: #5fb36a; }
.activity .pill {
  display: inline-flex;
  align-items: center;
  padding: 1px 7px;
  border-radius: 10px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}
.activity .pill.good { background: #18301d; color: #8fd497; }
.activity .pill.bad { background: #3a1a17; color: #f0a79b; }
.activity .pill.dim { background: #1b2230; color: #a2aec2; }

.activity .needs { display: flex; flex-direction: column; gap: 8px; }
.activity .need {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr) auto;
  gap: 8px;
  padding: 8px 10px;
  border: 1px solid #3a3218;
  border-radius: 6px;
  background: #17150e;
  color: #f0cf70;
}
.activity .need.bad { border-color: #4a2420; background: #1a1110; color: #e07a6a; }
.activity .need svg { width: 16px; height: 16px; margin-top: 1px; }
.activity .need p { margin: 0; color: #e0e4ea; }
.activity .need .detail { color: #8d99ad; font-size: 12px; }
.activity .need .acts { display: flex; flex-wrap: wrap; gap: 6px 12px; margin-top: 4px; font-size: 12px; }
.activity .need .x {
  align-self: start;
  border: 0;
  background: transparent;
  color: #8d99ad;
  font-size: 18px;
  line-height: 1;
  padding: 0 4px;
  cursor: pointer;
}
.activity .need .x:hover { color: #e8ecf3; }
.activity .empty-note,
.activity .ev-empty {
  padding: 10px 12px;
  font-size: 12px;
  color: #8d99ad;
  border: 1px dashed #2a3246;
  border-radius: 6px;
  list-style: none;
}
.activity .ev-empty { border: 0; padding: 8px 0; }

.activity .chip-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
.activity .chips { display: flex; flex-wrap: wrap; gap: 6px; }
.activity .chip {
  display: inline-flex;
  align-items: center;
  height: 28px;
  padding: 0 10px;
  border: 1px solid #2a3246;
  border-radius: 14px;
  background: #161c27;
  color: #a2aec2;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.activity .chip[aria-pressed="true"] { background: #1c2a42; border-color: #34507c; color: #e8ecf3; }
.activity .linkbtn { border: 0; background: transparent; color: #7fb2ff; font: inherit; font-size: 12px; padding: 4px 0; cursor: pointer; }

.activity details.night { border: 1px solid #263044; border-radius: 6px; background: #0f1319; }
.activity details.night > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  padding: 10px 12px;
}
.activity details.night > summary::-webkit-details-marker { display: none; }
.activity details.night > summary::before {
  content: "";
  width: 0;
  height: 0;
  border-left: 5px solid #a2aec2;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transform: translateY(-1px);
  transition: transform 0.15s;
}
.activity details.night[open] > summary::before { transform: rotate(90deg); }
.activity details.night > summary h3 { margin: 0; font-size: 13px; color: #e8ecf3; }
.activity details.night > summary .sum { font-size: 11px; color: #8d99ad; }
.activity .events { list-style: none; margin: 0; padding: 0 12px 12px; display: flex; flex-direction: column; }
.activity .ev {
  display: grid;
  grid-template-columns: 46px 22px minmax(0, 1fr);
  column-gap: 8px;
  padding: 7px 0;
  border-top: 1px solid #192130;
}
.activity .ev:first-child { border-top: 0; }
.activity .ev.ev-group { display: block; }
.activity .ev-grp > summary {
  display: grid; grid-template-columns: 46px 22px minmax(0, 1fr); column-gap: 8px;
  cursor: pointer; list-style: none;
}
.activity .ev-grp > summary::-webkit-details-marker { display: none; }
.activity .ev-grp > summary .what::after { content: " \25B8"; color: #8d99ad; }
.activity .ev-grp[open] > summary .what::after { content: " \25BE"; }
.activity .ev-grp > .events.inner { padding: 6px 0 0 0; }
.activity .ev.is-new { box-shadow: inset 2px 0 0 #4da6ff; background: rgba(77, 166, 255, 0.05); }
.activity .ev time { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; font-size: 11px; color: #8d99ad; padding-top: 1px; }
.activity .ev .ico { width: 22px; height: 22px; border-radius: 5px; display: flex; align-items: center; justify-content: center; }
.activity .ev .ico svg { width: 13px; height: 13px; }
.activity .ev .txt { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.activity .ev .what { color: #e0e4ea; overflow-wrap: anywhere; }
.activity .ev.sev-error .what { color: #f0a79b; }
.activity .ev .meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; font-size: 11px; color: #8d99ad; }
.activity .ev .meta a { font-size: 11px; }
.activity .ev .detail { overflow-wrap: anywhere; }
.activity .ev-more { list-style: none; padding-top: 8px; }
.activity .t-plans .ico { background: #1d2440; color: #a7b4ff; }
.activity .t-syncs .ico { background: #142838; color: #7fc8ff; }
.activity .t-imaging .ico { background: #2a1b1b; color: #ff9a8a; }
.activity .t-site .ico { background: #1b2230; color: #a2aec2; }
.activity .t-data .ico { background: #1b2a22; color: #8fd497; }
.activity .t-processing .ico { background: #2a2414; color: #f0cf70; }
.activity .t-masters .ico { background: #2a1a30; color: #e3a6ff; }
.activity .t-coverage .ico { background: #1f2630; color: #c4cdda; }

.activity .master { margin-top: 4px; padding: 6px 8px; border: 1px solid #3a2a44; border-radius: 6px; background: #150f19; display: flex; flex-direction: column; gap: 4px; }
.activity .loc { display: grid; grid-template-columns: 52px minmax(0, 1fr) auto; align-items: center; gap: 8px; }
.activity .loc .lbl { font-size: 10px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: #8d99ad; }
.activity .loc code {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 11px;
  color: #d9c8e6;
  overflow-x: auto;
  white-space: nowrap;
  padding-block: 2px;
  user-select: all;
}
.activity .cp, .activity .btn {
  height: 24px;
  min-width: 58px;
  padding: 0 8px;
  border: 1px solid #3a4560;
  border-radius: 4px;
  background: #161c27;
  color: #e0e4ea;
  font: inherit;
  font-size: 11px;
  cursor: pointer;
}
.activity .btn { height: 28px; font-size: 12px; padding: 0 10px; }
.activity .cp:hover, .activity .btn:hover { border-color: #4d5c80; color: #e8ecf3; }
.activity .cp.ok { border-color: #2f5a36; color: #8fd497; }
.activity .more { display: flex; flex-direction: column; align-items: center; gap: 6px; padding-block: 4px 8px; }
.activity .more .count { font-size: 11px; color: #8d99ad; font-variant-numeric: tabular-nums; }
@media (prefers-reduced-motion: reduce) { .activity details.night > summary::before { transition: none; } }

/* Extension rail tabs: the extension's page fills the panel. */
.side-tab[data-ext-tab] { overflow: hidden; }
.ext-rail-frame {
  flex: 1 1 auto;
  width: 100%;
  min-height: 0;
  border: 0;
  background: #0c1016;
}

/* Cards at the top of the Activity tab: ACP's own and extensions' iframes. */
.activity-cards { flex: 0 0 auto; display: flex; flex-direction: column; gap: 6px; padding: 0 0 6px; }
.activity-cards:empty { display: none; }
.ext-activity-frame {
  display: block;
  width: 100%;
  height: 120px;
  border: 0;
  border-radius: 6px;
  background: #0c1016;
}

/* Upload progress card (POST /api/uploads/<id>/progress). */
.upload-card { border: 1px solid #263042; border-radius: 6px; padding: 6px 10px; background: #111722; }
.upload-card h3 { margin: 0 0 4px; font-size: 12px; font-weight: 600; color: #9aa6bd; }
.upload-card ul { list-style: none; margin: 0; padding: 0; }
.upload-card .up-row + .up-row { margin-top: 8px; }
.upload-card .up-head { display: flex; justify-content: space-between; gap: 8px; font-size: 13px; }
.upload-card .up-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.upload-card .up-state { color: #9aa6bd; white-space: nowrap; }
.upload-card .up-row[data-state="paused"] .up-state { color: #d8b45a; }
.upload-card .up-bar { height: 4px; margin: 4px 0; border-radius: 2px; background: #263042; overflow: hidden; }
.upload-card .up-bar > span { display: block; height: 100%; background: #5a9be6; }
.upload-card .up-row[data-state="paused"] .up-bar > span { background: #d8b45a; }
.upload-card .up-figs, .upload-card .up-times { font-size: 11px; color: #78839a; }

/* Extension sections under the plan editor (manifest editor_sections). */
.ext-editor-frame {
  display: block;
  width: 100%;
  height: 180px;
  border: 0;
  background: #0c1016;
}

/* Plan links an extension attaches to a tile (metadata.plans). */
.tile-plans { list-style: none; margin: 4px 0 0; padding: 0; }
.tile-plans li { margin: 0 0 6px; }
.tile-plan-detail { color: #78839a; font-size: 11px; margin-top: 1px; }

/* Tile panel: source label above the tile id, and extension-supplied HTML. */
.tile-source-label { color: #78839a; font-size: 11px; margin-top: 8px; }
.ext-tile-panel a,
.ext-tile-panel [data-acp-plan-id],
.ext-tile-panel [data-acp-new-plan],
.ext-tile-panel [data-acp-goto],
.tile-plans a.tile-plan-link {
  color: #7fb2ff;
  cursor: pointer;
  text-decoration: underline;
}
.ext-tile-panel a:hover,
.ext-tile-panel [data-acp-plan-id]:hover,
.ext-tile-panel [data-acp-new-plan]:hover,
.ext-tile-panel [data-acp-goto]:hover,
.tile-plans a.tile-plan-link:hover { color: #a9cbff; }
.ext-tile-notice {
  background: #2a3346;
  border-radius: 4px;
  color: #e0e4ea;
  font-size: 12px;
  margin: 6px 0;
  padding: 6px 8px;
}

/* Extensions block in the Inventory rail. */
.ext-status { margin: 0 0 8px; font-size: 12px; color: #b6bdcd; }
.ext-status summary { cursor: pointer; }
.ext-groups, .ext-groups ul { list-style: none; margin: 4px 0 0; padding: 0; }
.ext-groups ul { padding-left: 12px; }
.ext-src { display: flex; gap: 8px; align-items: baseline; margin: 2px 0; }
.ext-src-state { color: #78839a; }
[data-state="error"] > .ext-src-state, .ext-src[data-state="error"] .ext-src-state { color: #e0816b; }
[data-state="loading"] > .ext-src-state, .ext-src[data-state="loading"] .ext-src-state { color: #d6a04a; }
#sidePanelWide[hidden] { display: none; }
@media (max-width: 640px) { #sidePanelWide { display: none; } }

.plan-form input.invalid { outline: 1px solid #c25b5b; border-color: #c25b5b; }

/* "What's here?" panel. Controls reuse the plan form's label and input rules. */
.ss-view, .ss-rig-info, .ss-count { font-size: 12px; color: #78839a; margin: 2px 0 6px; }
.ss-controls { margin: 8px 0; }
.ss-controls .primary {
  background: #2a4f7a;
  border: 1px solid #355d8e;
  color: #f0f5ff;
  border-radius: 4px;
  padding: 6px 12px;
  width: 100%;
  font-size: 12px;
  cursor: pointer;
}
.ss-controls .primary:hover { background: #345f92; }
.ss-status { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 6px; }
.ss-chip {
  font-size: 11px;
  padding: 1px 7px;
  border-radius: 10px;
  background: #1a2030;
  border: 1px solid #2a3246;
  color: #a2aec2;
}
.ss-chip.bad { border-color: #7a3a3a; color: #e3a0a0; }
.ss-group { margin: 12px 0 2px; }
.ss-row { padding: 6px 2px; border-bottom: 1px solid #1f2937; }
.ss-main { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.ss-name { color: #e0e4ea; font-weight: 600; }
.ss-size { color: #a2aec2; font-size: 12px; white-space: nowrap; }
.ss-size.unknown { color: #78839a; font-style: italic; }
.ss-meta, .ss-alias { font-size: 12px; color: #78839a; }
.ss-actions { display: flex; gap: 12px; margin-top: 2px; }
.ss-chiprow { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; margin-bottom: 6px; }
.ss-chiprow .lab { font-size: 12px; color: #78839a; min-width: 62px; }
.ss-chip.tog { cursor: pointer; opacity: 0.55; }
.ss-chip.tog.on { opacity: 1; background: #2a4f7a; border-color: #4a7ec0; color: #f0f5ff; }
.ss-fill-custom { font-size: 12px; color: #a2aec2; margin-bottom: 6px; }
.ss-fill-custom input { width: 60px; }
.ss-filters { margin: 6px 0; }
.ss-actions a.link-btn { text-decoration: none; }

/* Help tab: the tour button, the feature map and the hidden shortcuts. */
.side-tab[data-tab="help"] { overflow-y: auto; }
.help-body { padding: 14px 16px 20px; }
.help-body h3 { margin: 18px 0 6px; }
.help-body h3:first-of-type { margin-top: 16px; }
.help-body h4 { margin: 12px 0 4px; font-size: 13px; }
.help-list { margin: 0; padding-left: 18px; color: #c4ccd8; font-size: 14px; }
.help-list li { margin: 3px 0; }
.help-list a { color: #5bb6ff; }
.help-version { margin-top: 18px; color: #78839a; font-size: 12px; }
.help-update { margin-top: 4px; color: #78839a; font-size: 12px; }
.help-update[hidden] { display: none; }
.help-update a { color: #5bb6ff; }

/* Newer-release banner, filled by loadUpdateNotice() in app.js. Minor is calm,
   major is the most visible thing in the toolbar. Patch gets no banner. */
.update-banner {
  flex-basis: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 12px;
  padding: 5px 8px;
  font-size: 11px;
  color: #b9d4f5;
  background: #121c2b;
  border: 1px solid #2a4263;
  border-radius: 4px;
}
.update-banner[hidden] { display: none; }
.update-banner .update-link { color: #6aa6ff; text-decoration: underline; }
.update-banner.is-major {
  padding: 8px 10px;
  font-size: 13px;
  font-weight: 600;
  color: #fff3d6;
  background: #6b4a0a;
  border-color: #f0c674;
}
.update-banner.is-major .update-link { color: #ffd98a; }
.help-tour-btn,
.tour-card button.primary {
  background: #2a4f7a;
  border-color: #355d8e;
  color: #f0f5ff;
}
.help-tour-btn:hover,
.tour-card button.primary:hover { background: #345f92; }
.help-tour-btn { width: 100%; padding: 8px 12px; font-size: 14px; }

/* The tour: a ring round one control and a card beside it. The ring's
   wide shadow dims everything else; neither catches clicks except the
   card itself. */
.tour-ring {
  position: fixed;
  z-index: 1000;
  border: 2px solid #4da6ff;
  border-radius: 6px;
  box-shadow: 0 0 0 9999px rgba(5, 8, 12, 0.55);
  pointer-events: none;
}
.tour-shade {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: rgba(5, 8, 12, 0.55);
  pointer-events: none;
}
.tour-ring[hidden], .tour-shade[hidden] { display: none; }
.tour-card {
  position: fixed;
  z-index: 1001;
  max-width: calc(100vw - 16px);
  padding: 14px 16px 12px;
  background: #14192a;
  border: 1px solid #2a3246;
  border-radius: 8px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
  color: #e0e4ea;
  font-size: 14px;
  line-height: 1.45;
}
.tour-card h3 { margin: 2px 0 6px; font-size: 16px; color: #e8ecf3; }
.tour-card p { margin: 0 0 12px; color: #c4ccd8; }
.tour-count { font-size: 11px; color: #78839a; }
.tour-actions { display: flex; align-items: center; gap: 8px; }
.tour-spacer { flex: 1; }
.tour-actions button[hidden] { display: none; }
@media (prefers-reduced-motion: no-preference) {
  .tour-ring { transition: left 0.18s ease, top 0.18s ease, width 0.18s ease, height 0.18s ease; }
  .tour-card { transition: left 0.18s ease, top 0.18s ease; }
}

.modal-row select {
  background: #1a2030;
  border: 1px solid #2a3246;
  color: #e0e4ea;
  padding: 5px 8px;
  border-radius: 3px;
  font-size: 12px;
  width: 100%;
}
.acp-modal :is(button, input, select):focus-visible { outline: 2px solid #4da6ff; outline-offset: 1px; }

/* Link from the map's header to the setup and settings page. */
.settings-link {
  color: #a2aec2;
  font-size: 12px;
  text-decoration: none;
  padding: 3px 8px;
  border: 1px solid #2a3246;
  border-radius: 3px;
  background: #1a2030;
}
.settings-link:hover { background: #212939; color: #e0e4ea; }
