/* ==========================================================================
   Operational panels (ops-motion.js).
   A live graph beside a terminal log that plays in step with it. The panel
   paints its own ground, so it reads the same on the landing, the documents
   and either console theme.
   ========================================================================== */
.opsPanel {
  --ops-ground: #0A0E15; --ops-term: #05070B; --ops-line: #1A2130;
  --ops-text: #E9EDF4; --ops-dim: #8A94A6; --ops-acc: #9D90FF;
  --ops-ok: #4FB58B; --ops-warn: #D4913F; --ops-bad: #E46E62;
  container-type: inline-size;
  display: block; min-width: 0; color: var(--ops-text);
}
.opsPanel[data-ground="light"] {
  --ops-ground: #F7F8FA; --ops-term: #FFFFFF; --ops-line: #DCE1E8;
  --ops-text: #131925; --ops-dim: #566072; --ops-acc: #5A4BD6;
  --ops-ok: #2B7F5B; --ops-warn: #955C19; --ops-bad: #B33E33;
}
.opsGrid {
  display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  border: 1px solid var(--ops-line); background: var(--ops-ground);
}
.opsViz { position: relative; min-width: 0; border-right: 1px solid var(--ops-line); }
.opsViz canvas { display: block; width: 100%; aspect-ratio: 2.1 / 1; }

.opsBar {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  height: 34px; padding: 0 14px; border-bottom: 1px solid var(--ops-line);
  font-family: var(--mono, "IBM Plex Mono"), ui-monospace, Consolas, monospace;
  font-size: 10.5px; letter-spacing: .08em; color: var(--ops-dim); white-space: nowrap; overflow: hidden;
}
.opsBar > span { overflow: hidden; text-overflow: ellipsis; }
.opsBar i { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--ops-line); margin-right: 5px; }
.opsTag {
  display: inline-flex; align-items: center; gap: 7px; flex: none;
  font-family: var(--mono, "IBM Plex Mono"), ui-monospace, Consolas, monospace;
  font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--ops-dim);
}
.opsTag::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--ops-acc);
  animation: opsPulse 1.6s ease-in-out infinite;
}
.opsTagFloat {
  position: absolute; top: 10px; right: 12px; padding: 3px 7px;
  background: color-mix(in srgb, var(--ops-ground) 82%, transparent);
}
@keyframes opsPulse { 50% { opacity: .25; } }

.opsReadout {
  position: absolute; left: 14px; bottom: 12px; display: flex; flex-direction: column; gap: 1px;
  pointer-events: none; text-shadow: 0 0 16px var(--ops-ground), 0 0 4px var(--ops-ground);
}
.opsReadout b {
  font-family: var(--display, "Archivo"), "Helvetica Neue", Arial, sans-serif; font-weight: 800;
  font-size: clamp(1.35rem, 4.2cqi, 2.2rem); letter-spacing: -.03em; line-height: 1;
  font-variant-numeric: tabular-nums; color: var(--ops-text);
}
.opsReadout span, .opsReadout small {
  font-family: var(--mono, "IBM Plex Mono"), ui-monospace, Consolas, monospace; font-size: 10.5px;
}
.opsReadout span { letter-spacing: .1em; text-transform: uppercase; color: var(--ops-dim); margin-top: 3px; }
.opsReadout small { color: var(--ops-dim); }

.opsTerm { position: relative; min-width: 0; background: var(--ops-term); }
.opsTermBody {
  position: absolute; inset: 34px 0 0 0; overflow: hidden; padding: 12px 14px;
  font-family: var(--mono, "IBM Plex Mono"), ui-monospace, Consolas, monospace;
  font-size: 11.5px; line-height: 1.72;
  /* Tail in sight without script: the reversed column starts at the bottom, so
     overflow spills off the top, while the auto margin holds a short log at
     the top. No scrollTop, so no forced layout per typed character. */
  display: flex; flex-direction: column-reverse;
}
.opsTermLines { flex: none; margin-bottom: auto; min-width: 0; }
.opsTermBody .ln { white-space: pre-wrap; word-break: break-word; color: var(--ops-dim); }
.opsTermBody .ln.k-cmd { color: var(--ops-text); }
.opsTermBody .ln.k-cmd::before { content: "$ "; color: var(--ops-acc); }
.opsTermBody .ln.k-ok::before { content: "\2713  "; color: var(--ops-ok); }
.opsTermBody .ln.k-warn::before { content: "!  "; color: var(--ops-warn); }
.opsTermBody .ln.k-bad::before { content: "\2717  "; color: var(--ops-bad); }
.opsTermBody .ln.k-info::before { content: "\2192  "; color: var(--ops-dim); }
.opsTermBody .ln.k-link { color: var(--ops-acc); text-decoration: underline; text-underline-offset: 3px; }
.opsTermBody .hi { color: var(--ops-text); }
.opsCursor {
  display: inline-block; width: 7px; height: 12px; margin-left: 2px; vertical-align: -2px;
  background: var(--ops-text); animation: opsBlink 1s steps(1) infinite;
}
@keyframes opsBlink { 50% { opacity: 0; } }

/* Compact: the graph on top, the last few log lines beneath it. */
.opsPanel[data-ops-layout="compact"] .opsGrid { grid-template-columns: 1fr; }
.opsPanel[data-ops-layout="compact"] .opsViz { border-right: 0; border-bottom: 1px solid var(--ops-line); }
.opsPanel[data-ops-layout="compact"] .opsViz canvas { aspect-ratio: 3 / 1; }
.opsPanel[data-ops-layout="compact"] .opsTerm { height: 66px; }
.opsPanel[data-ops-layout="compact"] .opsTermBody { inset: 0; padding: 9px 14px; font-size: 11px; line-height: 1.6; }
/* A short graph leaves no room for three readout lines beside the drawing. */
.opsCompact .opsReadout { bottom: 10px; }
.opsCompact .opsReadout b { font-size: clamp(1.1rem, 3.4cqi, 1.65rem); }
.opsCompact .opsReadout small { display: none; }

/* A side-by-side panel stacks once it is too narrow for both halves. A compact
   panel is already stacked, so it only changes shape at phone width. */
@container (max-width: 700px) {
  .opsGrid:not(.opsCompact) { grid-template-columns: 1fr; }
  .opsGrid:not(.opsCompact) .opsViz { border-right: 0; border-bottom: 1px solid var(--ops-line); }
  .opsGrid:not(.opsCompact) .opsViz canvas { aspect-ratio: 16 / 10; }
  .opsGrid:not(.opsCompact) .opsTerm { height: 176px; }
}
@container (max-width: 460px) {
  .opsGrid.opsCompact .opsViz canvas { aspect-ratio: 16 / 10; }
}

/* Inside console views the panel sits between rows of cards. */
.viewOps { margin: 4px 0 20px; }

body[data-motion="paused"] .opsTag::before,
body[data-motion="paused"] .opsCursor,
.opsOffscreen .opsTag::before,
.opsOffscreen .opsCursor { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .opsTag::before, .opsCursor { animation: none; }
}
