/* sky.css: everything sky.js draws or builds.
   The sky panel itself (position, border, ground) is laid out by styles.css
   (.skybox); this file styles what sky.js puts inside it: the WebGL canvas,
   the overlay (corner caption, legend, tags, hover label, empty message),
   and the control deck it renders into #live-deck. Chrome colours come from
   the Observatory variables in styles.css; the only hard-coded colours are
   data colours (route white/blue) that match sky.js's own constants. */

/* ---------------- the sky container and canvas ---------------- */
.sky-host { position: relative; overflow: hidden; cursor: grab; touch-action: none; }
.sky-host:active { cursor: grabbing; }
.sky-canvas {
  position: absolute; inset: 0;
  width: 100%; height: 100%; display: block;
}

/* ---------------- overlay: captions that float over the canvas ---------------- */
/* Most of the overlay leaves the pointer to the orbitable container. The
   Turn button is the one interactive exception. */
.sky-overlay { position: absolute; inset: 0; pointer-events: none; }

.sky-corner {
  position: absolute; left: 12px; top: 10px; right: 62px;
  font: 11px/1.5 var(--mono); color: var(--ink-3);
  text-shadow: 0 1px 4px rgba(var(--well-rgb), 0.85);
  text-wrap: balance;
}
.sky-turn {
  position: absolute; right: 10px; top: 9px; z-index: 2;
  min-width: 0; min-height: 0; padding: 3px 8px; pointer-events: auto;
  border: 1px solid var(--hairline-2); border-radius: var(--radius);
  background: color-mix(in srgb, var(--panel) 82%, transparent);
  color: var(--corona-2); font: 500 10.5px/1.35 var(--mono);
  letter-spacing: 0.05em; text-transform: uppercase; cursor: pointer;
  box-shadow: 0 2px 10px rgba(var(--shadow-rgb), 0.28);
}
.sky-turn:hover { border-color: var(--corona-2); color: var(--ink); }
.sky-turn:focus-visible { outline: 1px solid var(--corona-2); outline-offset: 2px; }

.sky-legend {
  position: absolute; right: 12px; bottom: 10px;
  display: flex; flex-wrap: wrap; gap: 6px 14px; justify-content: flex-end;
  font: 11px/1.5 var(--mono); color: var(--ink-3);
  text-shadow: 0 1px 4px rgba(var(--well-rgb), 0.85);
}
.sky-legend span { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.sky-legend i { display: inline-block; flex: 0 0 auto; }
.sky-legend i.solid { width: 18px; border-top: 2px solid var(--corona-2); }
.sky-legend i.dotted { width: 18px; border-top: 2px dotted var(--specular); }
.sky-legend i.halo {
  width: 11px; height: 11px; border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--specular-rgb), 0.95) 0%, rgba(var(--specular-rgb), 0) 72%);
}

/* ---------------- axis key: what the three reduced axes mean ---------------- */
/* Bottom left, the one corner neither the caption (top, full width) nor the
   legend (bottom right) reaches, and far from the comet that marks the
   running cell in the middle of the box. */
.sky-axiskey {
  position: absolute; left: 12px; bottom: 10px; max-width: 46%;
  font: 11px/1.6 var(--mono); color: var(--ink-3);
  text-shadow: 0 1px 4px rgba(var(--well-rgb), 0.85);
}
.sky-axiskey b {
  display: block; margin-bottom: 2px;
  font: 500 10px/1.5 var(--mono); letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--corona-2);
}
.sky-axiskey span { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sky-axiskey i {
  display: inline-block; width: 15px; font-style: normal; color: var(--corona-2);
}

/* A compact, camera-aware axis triad replaces the old projection cube. Its
   origin is screen-pinned so it remains readable while the data cloud turns. */
.sky-origin {
  position: absolute; left: 50%; top: 50%; width: 0; height: 0;
  color: var(--corona-2); filter: drop-shadow(0 1px 4px rgba(var(--well-rgb), 0.95));
}
.sky-origin[data-position="top-left"] { left: 18%; top: 22%; }
.sky-origin[data-position="top-right"] { left: 82%; top: 22%; }
.sky-origin[data-position="bottom-left"] { left: 18%; top: 78%; }
.sky-origin[data-position="bottom-right"] { left: 82%; top: 78%; }
.sky-origin-line {
  position: absolute; left: 0; top: 0; height: 1px; transform-origin: 0 0;
  background: currentColor; opacity: 0.72;
}
.sky-origin-line::after {
  content: ''; position: absolute; right: -1px; top: -2px;
  width: 5px; height: 5px; border-radius: 50%; background: currentColor;
}
.sky-origin-line.axis-1, .sky-origin-label.axis-1 { color: var(--specular); }
.sky-origin-line.axis-2, .sky-origin-label.axis-2 { color: var(--sun); }
.sky-origin-point {
  position: absolute; left: -3px; top: -3px; width: 7px; height: 7px;
  border: 1px solid var(--specular); border-radius: 50%; background: var(--sky-0);
}
.sky-origin-label {
  position: absolute; left: 0; top: 0; max-width: 150px; overflow: hidden;
  color: var(--corona-2); font: 500 10.5px/1.2 var(--mono);
  letter-spacing: 0.02em; white-space: nowrap; text-overflow: ellipsis;
}

/* ---------------- tags: small mono captions pinned to projected points ---------------- */
.sky-tags { position: absolute; inset: 0; overflow: hidden; }
.sky-tag {
  position: absolute; left: 0; top: 0; pointer-events: none;
  white-space: nowrap; will-change: transform;
  font: 10.5px/1.3 var(--mono); letter-spacing: 0.02em; color: var(--ink-3);
  text-shadow: 0 1px 3px rgba(var(--well-rgb), 0.9), 0 0 6px rgba(var(--well-rgb), 0.7);
}
.sky-tag.cell { color: var(--ink-3); }
.sky-tag.axis { color: var(--corona-2); letter-spacing: 0.05em; }
.sky-tag.axis.dim { color: var(--ink-3); }
.sky-tag.axis.category-tick { font-size: 11.5px; letter-spacing: 0.025em; }
.sky-tag.pass { color: var(--corona-2); }
.sky-tag.ahead { color: var(--ink-2); font-style: italic; }
.sky-tag.comet { color: var(--ink); font-weight: 500; }

/* ---------------- hover label: one small panel-ground tooltip ---------------- */
/* sky.js flips it left of the pointer when x + 14 + 220 exceeds the box,
   so the width here must stay 220px. */
.sky-hover {
  position: absolute; left: 0; top: 0; width: 220px; pointer-events: none;
  background: var(--panel); border: 1px solid var(--hairline-2);
  border-radius: var(--radius); padding: 8px 10px;
  font: 11px/1.55 var(--mono); color: var(--ink-2);
  box-shadow: 0 8px 30px rgba(var(--shadow-rgb), 0.55), 0 0 18px rgba(var(--corona-rgb), 0.12);
  overflow-wrap: anywhere; white-space: normal;
}
.sky-hover b { display: block; color: var(--ink); font-weight: 500; margin-bottom: 2px; }
.sky-hover span { display: block; }

/* ---------------- empty message: why there is nothing to draw ---------------- */
.sky-empty {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center; text-align: center;
  padding: 24px 32px; pointer-events: none;
  font: 500 11px/1.7 var(--mono); letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-3); text-wrap: balance;
}

/* ---------------- the control deck (#live-deck) ---------------- */
/* Labelled groups in the dashboard's control look: mono uppercase captions
   above each control, the include chips as a full-width row doubling as the
   legend. Selects and chips take the global styles.css rules. */
.sky-deck {
  display: flex; flex-wrap: wrap; gap: 14px 24px; align-items: flex-start;
}
.sky-deck .g {
  display: flex; flex-direction: column; gap: 6px; min-width: 0;
}
.sky-deck .g > span {
  font: 500 10.5px/1.4 var(--mono); letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-3);
}
.sky-deck .sky-control-title { display: flex; align-items: center; gap: 6px; }
.sky-deck .sky-control-title .metric-help-btn {
  width: 18px; height: 18px; flex-basis: 18px; font-size: 10px;
}
.sky-deck .g.wide { flex: 1 1 100%; }
.sky-deck .g select { max-width: 260px; }
.sky-deck .sky-axsel { display: flex; flex-direction: column; gap: 6px; }
.sky-deck .sky-field { display: flex; flex-direction: column; gap: 4px; }
.sky-deck .sky-field > span {
  font: 500 10px/1.4 var(--mono); letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-3);
}
.sky-deck .chip-row { max-width: none; }
.sky-colour-editor {
  padding: 11px 12px; background: color-mix(in srgb, var(--well) 76%, transparent);
  border: 1px solid var(--hairline-2); border-radius: var(--radius);
}
.sky-colour-editor-head {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 12px;
}
.sky-colour-editor-head > div { min-width: 0; }
.sky-colour-editor-head span {
  display: block; font: 500 10.5px/1.4 var(--mono); letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-2);
}
.sky-colour-editor-head small {
  display: block; margin-top: 2px; font: 11.5px/1.4 var(--sans); color: var(--ink-3);
}
.sky-colour-toolbar { display: flex; align-items: flex-end; gap: 7px; }
.sky-colour-toolbar .sky-field { min-width: 190px; }
.sky-colour-toolbar .sky-outcome-overlay {
  align-items: center; min-height: 31px; padding: 3px 8px;
  background: var(--well); border: 1px solid var(--hairline);
  border-radius: var(--radius); white-space: nowrap;
}
.sky-colour-toolbar .sky-outcome-overlay > span {
  font: 11.5px/1.25 var(--sans); color: var(--ink-2);
  letter-spacing: 0; text-transform: none;
}
.sky-colour-toolbar .sky-outcome-overlay small {
  display: block; margin: 1px 0 0; font: 10.5px/1.25 var(--sans);
  color: var(--ink-3);
}
.sky-colour-toolbar .ghost-btn {
  flex: 0 0 auto; min-height: 0; padding: 5px 9px; font-size: 11px;
}
.sky-colour-values {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 4px; max-height: 132px; overflow-y: auto; padding: 1px 3px 1px 0;
}
.sky-rate-gradient {
  grid-column: 1 / -1; display: grid; grid-template-columns: auto minmax(180px, 1fr) auto;
  align-items: center; gap: 9px; padding: 7px 2px;
  font: 11.5px/1.4 var(--mono); color: var(--ink-2);
}
.sky-rate-gradient i {
  height: 12px; border: 1px solid var(--hairline-2); border-radius: 999px;
  background: linear-gradient(90deg, #ff2d16 0%, #ffe44c 50%, #72c33b 100%);
}
.sky-colour-value {
  display: grid; grid-template-columns: 18px minmax(0, 1fr);
  align-items: center; gap: 6px; min-width: 0; padding: 2px 7px;
  background: var(--well);
  border: 1px solid var(--hairline); border-radius: var(--radius); cursor: pointer;
}
.sky-colour-value input[type="color"] {
  width: 18px; height: 18px; min-width: 0; padding: 0; border: 0;
  border-radius: 50%; background: transparent; cursor: pointer; overflow: hidden;
}
.sky-colour-value input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
.sky-colour-value input[type="color"]::-webkit-color-swatch {
  border: 1px solid rgba(var(--specular-rgb), 0.45); border-radius: 50%;
}
.sky-colour-value input[type="color"]::-moz-color-swatch {
  border: 1px solid rgba(var(--specular-rgb), 0.45); border-radius: 50%;
}
.sky-colour-value > span {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font: 11.5px/1.4 var(--mono); color: var(--ink-2);
}

/* The visualization filters are grouped by recorded data dimension. Keeping
   tasks and documentation builds wide prevents the short two-choice controls
   from being buried in one long, unlabelled run of pills. */
.sky-include {
  border-top: 1px solid var(--hairline); padding-top: 13px;
}
.sky-include-title {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 12px;
}
.sky-include-title > span {
  font: 500 10.5px/1.4 var(--mono); letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-3);
}
.sky-include-title > small {
  font: 11.5px/1.4 var(--sans); color: var(--ink-3);
}
.sky-include-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 9px; width: 100%;
}
.sky-include-group {
  min-width: 0; padding: 10px 11px;
  background: color-mix(in srgb, var(--well) 76%, transparent);
  border: 1px solid var(--hairline); border-radius: var(--radius);
}
.sky-include-group.span-two { grid-column: 1 / -1; }
.sky-include-group-head {
  display: flex; align-items: center; gap: 7px; margin-bottom: 8px;
  font: 500 10.5px/1.4 var(--mono); letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-2);
}
.sky-include-group-head > small {
  font: 10.5px/1.4 var(--mono); letter-spacing: 0; text-transform: none;
  color: var(--ink-3);
}
.sky-filter-actions { display: flex; gap: 3px; margin-left: auto; }
.sky-filter-actions button {
  border: 0; padding: 1px 4px; background: transparent; cursor: pointer;
  font: 10.5px/1.4 var(--mono); color: var(--ink-3);
}
.sky-filter-actions button:hover { color: var(--corona-2); }
.sky-filter-actions button:focus-visible {
  outline: 1px solid var(--corona-2); outline-offset: 1px;
}
.sky-include-subrow {
  display: grid; grid-template-columns: 92px minmax(0, 1fr); gap: 7px;
  align-items: start;
}
.sky-include-subrow + .sky-include-subrow { margin-top: 6px; }
.sky-include-subrow > span {
  padding-top: 4px; font: 10.5px/1.4 var(--mono); color: var(--ink-3);
}
.sky-include .chip.is-on[data-v="H-STR"],
.sky-include .chip.is-on[data-v="H-NON"] {
  background: var(--btn); border-color: var(--btn);
  box-shadow: 0 0 14px rgba(var(--btn-rgb), 0.45);
}

@media (max-width: 780px) {
  .sky-colour-editor-head { align-items: stretch; flex-direction: column; }
  .sky-colour-toolbar { align-items: stretch; flex-wrap: wrap; }
  .sky-colour-toolbar .sky-field { flex: 1 1 auto; min-width: 0; }
  .sky-include-grid { grid-template-columns: minmax(0, 1fr); }
  .sky-include-group.span-two { grid-column: auto; }
  .sky-include-subrow { grid-template-columns: 1fr; gap: 3px; }
  .sky-include-subrow > span { padding-top: 0; }
}

.sky-deck .check {
  display: flex; align-items: center; gap: 8px; cursor: pointer;
  font: 12.5px/1.4 var(--sans); color: var(--ink-2);
}

.sky-readout b {
  display: block; font: 500 13px/1.45 var(--mono); letter-spacing: 0.01em;
  color: var(--ink);
}
.sky-readout small {
  display: block; margin-top: 2px;
  font: 11.5px/1.4 var(--sans); color: var(--ink-3);
}

/* ---------------------------------------------------------------- failure axes
   The third setting of the Axes control, its own two selects in the deck, and
   the panel underneath the map that says what was fitted and how much of it to
   believe. Everything here borrows the deck's and the panels' existing shapes;
   the only new colour is the swatch beside a group name, and that comes from
   the same task palette the map itself colours groups with. */
.sky-deck .sky-failsel { gap: 8px; }
.sky-deck .sky-failsel select { max-width: 260px; }
.sky-failure-state {
  font: 10.5px/1.5 var(--mono); color: var(--corona-2);
  letter-spacing: 0.02em; min-height: 16px;
}
.sky-deck .sky-failure-help {
  align-self: flex-start; padding: 4px 9px; font-size: 10.5px;
}

.failure-panel { display: block; }
.failure-grid {
  display: grid; gap: 18px 26px; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  margin-top: 12px;
}
.failure-panel h3 {
  margin: 0 0 6px; font: 500 11px/1.4 var(--mono); letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--corona-2);
}
.failure-panel p { margin: 0 0 10px; max-width: 78ch; color: var(--ink-2); }
.failure-panel .failure-note { font-size: 12.5px; color: var(--ink-3); }
.failure-panel .failure-refused {
  padding: 10px 12px; border-left: 2px solid var(--warn);
  background: var(--warn-dim); color: var(--ink-2); font-size: 13px;
}
.failure-weights {
  display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 10px; padding: 0; list-style: none;
}
.failure-weights li {
  display: flex; align-items: baseline; gap: 6px; padding: 3px 9px;
  border: 1px solid var(--hairline); border-radius: 999px; background: var(--well);
  font: 11.5px/1.4 var(--mono);
}
.failure-weights b { color: var(--ink); font-weight: 500; }
.failure-weights span { color: var(--corona-2); }
.failure-groups-lead { margin: 16px 0 10px; max-width: 78ch; color: var(--ink-2); }
.failure-groups {
  display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.failure-group {
  padding: 12px 14px; border: 1px solid var(--hairline); border-radius: var(--radius);
  background: color-mix(in srgb, var(--well) 76%, transparent);
}
.failure-group.is-shaky { border-style: dashed; border-color: var(--warn); }
.failure-group h4 {
  display: flex; align-items: center; gap: 8px; margin: 0 0 6px;
  font: 500 12px/1.4 var(--sans); color: var(--ink);
}
.failure-swatch {
  width: 10px; height: 10px; border-radius: 2px; flex: 0 0 10px;
}
.failure-group p { margin: 0 0 8px; font-size: 13px; }
.failure-group-size { color: var(--ink) !important; }
.failure-group .failure-repro { font-size: 12px; color: var(--ink-3); margin-bottom: 0; }
.failure-group.is-shaky .failure-repro { color: var(--warn); }
.failure-group dl {
  display: grid; grid-template-columns: auto 1fr; gap: 2px 10px; margin: 0 0 8px;
  font: 11.5px/1.5 var(--mono);
}
.failure-group dt { color: var(--ink-3); }
.failure-group dd { margin: 0; color: var(--ink-2); }
.failure-method-body article { padding: 14px 0; border-bottom: 1px solid var(--hairline); }
.failure-method-body article:last-child { border-bottom: 0; }
.failure-method-body h3 { margin: 0 0 6px; font: 600 14px/1.4 var(--sans); color: var(--ink); }
.failure-method-body p { margin: 0; color: var(--ink-2); max-width: 78ch; }
.failure-method-body ul { margin: 8px 0 0; padding-left: 18px; color: var(--ink-3); font-size: 13px; }
.failure-method-body li { margin-bottom: 8px; }
.failure-method-body li b { color: var(--ink-2); }
.failure-method-body code { font: 11.5px/1.4 var(--mono); color: var(--corona-2); }
