/* ══════════════════════════════════════════════════════════════════════
   LYDIAN HERO OPERATIONS RAILS v15

   Replaces .hero-rail (v10), which showed three hard-coded numbers under
   hand-drawn polylines that were styled to read as trend data. These panels
   render only measured values; the motion marks a real event (a sample
   landing), never a loop that runs regardless of what the system is doing.

   Both themes are first-class. Every size is fluid so the rails shrink with
   the viewport instead of colliding with the constellation.
   ══════════════════════════════════════════════════════════════════════ */

.ops-rail {
  --ops-surface: linear-gradient(180deg, rgba(31, 31, 29, 0.92) 0%, rgba(21, 21, 20, 0.94) 100%);
  --ops-border: rgba(255, 255, 255, 0.1);
  --ops-edge: rgba(233, 116, 81, 0.8);
  --ops-title: rgba(255, 255, 255, 0.62);
  --ops-label: rgba(255, 255, 255, 0.78);
  --ops-value: #ffffff;
  --ops-foot: rgba(255, 255, 255, 0.6);
  --ops-src: rgba(255, 255, 255, 0.62);
  --ops-track: rgba(255, 255, 255, 0.09);
  --ops-accent: #e97451;
  --ops-accent-soft: rgba(233, 116, 81, 0.22);
  --ops-ok: #22c55e;
  --ops-down: #d9534f;

  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: clamp(196px, 15.5vw, 244px);
  display: flex;
  flex-direction: column;
  gap: 10px;
  z-index: 4;
  pointer-events: none;
  opacity: 0;
  animation: ops-rail-in 0.8s cubic-bezier(0.16, 1, 0.3, 1) 0.9s forwards;
}
.ops-rail--left {
  left: clamp(0.75rem, 2vw, 2.25rem);
}
.ops-rail--right {
  right: clamp(0.75rem, 2vw, 2.25rem);
}
@keyframes ops-rail-in {
  from {
    opacity: 0;
    translate: 0 10px;
  }
  to {
    opacity: 1;
    translate: 0 0;
  }
}

/* ── Rail header ─────────────────────────────────────────────────────── */
.ops-rail-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 2px 8px;
  border-bottom: 1px solid var(--ops-border);
}
.ops-rail-head::before {
  content: '';
  width: 20px;
  height: 1px;
  background: linear-gradient(90deg, var(--ops-accent), transparent);
  flex-shrink: 0;
}
.ops-rail-title {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.16em;
  /* Uppercase lives in the markup, not here: the document is lang="tr", so
     CSS uppercasing renders English labels as MODELS ONLİNE. */
  color: var(--ops-title);
  white-space: nowrap;
}
/* Fires once per successful sample — motion tied to a real event */
.ops-rail-pulse {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  margin-left: auto;
  background: var(--ops-accent);
  flex-shrink: 0;
  opacity: 0.45;
}
.ops-rail-pulse.is-firing {
  animation: ops-pulse 0.9s ease-out;
}
@keyframes ops-pulse {
  0% {
    opacity: 1;
    box-shadow: 0 0 0 0 var(--ops-accent-soft);
  }
  100% {
    opacity: 0.45;
    box-shadow: 0 0 0 12px rgba(233, 116, 81, 0);
  }
}

/* ── Card ────────────────────────────────────────────────────────────── */
.ops-panel {
  position: relative;
  padding: 11px 12px 10px;
  border-radius: 10px;
  background: var(--ops-surface);
  border: 1px solid var(--ops-border);
  border-left: 2px solid var(--ops-edge);
  backdrop-filter: blur(16px) saturate(1.1);
  -webkit-backdrop-filter: blur(16px) saturate(1.1);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.06),
    0 10px 26px rgba(0, 0, 0, 0.4);
  overflow: hidden;
}
.ops-panel::after {
  /* scan line: sweeps when the rail receives data */
  content: '';
  position: absolute;
  inset: 0 auto 0 -40%;
  width: 40%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.05), transparent);
  pointer-events: none;
  opacity: 0;
}
.ops-rail:not(.is-degraded) .ops-panel::after {
  animation: ops-scan 6.5s ease-in-out infinite;
}
.ops-panel:nth-of-type(2)::after {
  animation-delay: 0.5s;
}
.ops-panel:nth-of-type(3)::after {
  animation-delay: 1s;
}
@keyframes ops-scan {
  0%,
  72% {
    left: -40%;
    opacity: 0;
  }
  76% {
    opacity: 1;
  }
  100% {
    left: 100%;
    opacity: 0;
  }
}

.ops-head {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-bottom: 4px;
}
.ops-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.07em;
  color: var(--ops-label);
}
.ops-src {
  margin-left: auto;
  font-family: ui-monospace, 'Geist Mono', 'JetBrains Mono', Menlo, monospace;
  /* 7.5px at 0.42 alpha measured 4.01:1 dark / 3.24:1 light — below AA for
     text this size. Lifted alpha and size until both themes clear 4.5:1. */
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--ops-src);
  border: 1px solid var(--ops-track);
  border-radius: 3px;
  padding: 1px 4px;
  white-space: nowrap;
}
/* A claim is labelled differently from a measurement, on purpose. */
.ops-src--claim {
  color: color-mix(in srgb, var(--ops-accent) 70%, var(--ops-src));
  border-color: color-mix(in srgb, var(--ops-accent) 35%, transparent);
}

.ops-body {
  display: flex;
  align-items: baseline;
  gap: 5px;
  min-height: 26px;
}
.ops-body--wrap {
  flex-wrap: wrap;
  gap: 4px;
  align-items: center;
}
.ops-value {
  font-size: clamp(19px, 1.55vw, 25px);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.015em;
  color: var(--ops-value);
  font-variant-numeric: tabular-nums;
}
.ops-unit {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--ops-foot);
}
.ops-note {
  display: block;
  margin-top: 7px;
  font-size: 9px;
  letter-spacing: 0.04em;
  color: var(--ops-foot);
  font-variant-numeric: tabular-nums;
}

.ops-chip {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.08em;
  padding: 3px 6px;
  border-radius: 4px;
  color: var(--ops-label);
  background: var(--ops-track);
  border: 1px solid var(--ops-border);
  white-space: nowrap;
}

/* ── Model LED grid: one cell per model actually reported ────────────── */
.ops-leds {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
  margin-top: 8px;
}
.ops-leds i {
  width: 6px;
  height: 6px;
  border-radius: 1.5px;
  background: color-mix(in srgb, var(--ops-accent) 55%, transparent);
  box-shadow: 0 0 4px color-mix(in srgb, var(--ops-accent) 35%, transparent);
}
.ops-leds.is-sweeping i {
  animation: ops-led 1.1s ease-out both;
  animation-delay: calc(var(--i, 0) * 26ms);
}
@keyframes ops-led {
  0% {
    background: var(--ops-accent);
    box-shadow: 0 0 8px var(--ops-accent);
  }
  100% {
    background: color-mix(in srgb, var(--ops-accent) 55%, transparent);
    box-shadow: 0 0 4px color-mix(in srgb, var(--ops-accent) 35%, transparent);
  }
}

/* ── Sparkline: drawn from measured samples only ─────────────────────── */
.ops-spark {
  display: block;
  width: 100%;
  height: 26px;
  margin-top: 6px;
  overflow: visible;
}
.ops-spark-line {
  fill: none;
  stroke: var(--ops-accent);
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  filter: drop-shadow(0 0 3px color-mix(in srgb, var(--ops-accent) 45%, transparent));
  transition: d 0.4s ease;
}

/* ── Meter + histogram ───────────────────────────────────────────────── */
.ops-meter {
  height: 4px;
  margin-top: 8px;
  border-radius: 99px;
  background: var(--ops-track);
  overflow: hidden;
}
.ops-meter-fill {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 99px;
  background: linear-gradient(90deg, var(--ops-accent), #f5a47c);
  transition: width 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
.ops-bars {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 22px;
  margin-top: 8px;
}
.ops-bars i {
  flex: 1 1 auto;
  min-width: 2px;
  border-radius: 1px;
  background: color-mix(in srgb, var(--ops-accent) 60%, transparent);
  transition: height 0.5s ease;
}

/* ── Three orbit ticks, echoing the constellation ────────────────────── */
.ops-orbits {
  position: relative;
  height: 26px;
  margin-top: 8px;
}
.ops-orbits i {
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
  border: 1px solid color-mix(in srgb, var(--ops-accent) 40%, transparent);
  border-radius: 50%;
}
.ops-orbits i:nth-child(1) {
  width: 12px;
  height: 12px;
  animation: ops-orbit-breathe 4s ease-in-out infinite;
}
.ops-orbits i:nth-child(2) {
  width: 22px;
  height: 22px;
  border-color: color-mix(in srgb, var(--ops-accent) 26%, transparent);
  animation: ops-orbit-breathe 4s ease-in-out 0.4s infinite;
}
.ops-orbits i:nth-child(3) {
  width: 32px;
  height: 32px;
  border-color: color-mix(in srgb, var(--ops-accent) 16%, transparent);
  animation: ops-orbit-breathe 4s ease-in-out 0.8s infinite;
}
@keyframes ops-orbit-breathe {
  0%,
  100% {
    opacity: 0.55;
    scale: 1;
  }
  50% {
    opacity: 1;
    scale: 1.06;
  }
}

/* ── Rail footer / connection state ──────────────────────────────────── */
.ops-rail-status {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 7px 9px;
  border-radius: 8px;
  background: rgba(24, 24, 23, 0.82);
  border: 1px solid var(--ops-border);
  font-family: ui-monospace, 'Geist Mono', 'JetBrains Mono', Menlo, monospace;
  font-size: 9px;
  letter-spacing: 0.06em;
  color: var(--ops-foot);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
.ops-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--ops-ok);
  box-shadow: 0 0 6px var(--ops-ok);
  animation: ops-heartbeat 1.9s ease-in-out infinite;
}
.ops-dot.is-down {
  background: var(--ops-down);
  box-shadow: 0 0 6px var(--ops-down);
  animation: none;
}
@keyframes ops-heartbeat {
  0%,
  100% {
    opacity: 1;
    scale: 1;
  }
  50% {
    opacity: 0.4;
    scale: 0.72;
  }
}
/* Degraded state must look degraded, not merely stale - but it must still be
   readable. At opacity 0.45 the notes measured 2.43:1 in dark and 1.80:1 in
   light (ops/landing-verify/verify_contrast.py, rendered pixels): the state a
   reader most needs to understand was the one they could not read. The dimming
   that carries the signal is kept on the value, and the degraded colour of the
   panel edge plus the status dot carry the rest; the 9px notes are left alone.
   0.78 is the measured floor that keeps both themes above AA here. */
.ops-rail.is-degraded .ops-value {
  opacity: 0.78;
}
.ops-rail.is-degraded .ops-panel {
  border-left-color: var(--ops-down);
}

/* ══════════════════════════════════════════════════════════════════════
   LIGHT THEME
   theme.css carries a blanket [data-theme='light'] span{color} rule, so the
   text tokens are restated at component specificity rather than relying on
   inheritance.
   ══════════════════════════════════════════════════════════════════════ */
[data-theme='light'] .ops-rail {
  --ops-surface: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.95) 0%,
    rgba(252, 250, 248, 0.95) 100%
  );
  --ops-border: rgba(31, 31, 30, 0.12);
  --ops-edge: rgba(201, 90, 55, 0.85);
  --ops-title: rgba(31, 31, 30, 0.62);
  --ops-label: rgba(31, 31, 30, 0.78);
  --ops-value: #17110d;
  --ops-foot: rgba(31, 31, 30, 0.62);
  --ops-src: rgba(31, 31, 30, 0.7);
  --ops-track: rgba(31, 31, 30, 0.09);
  --ops-accent: #c95a37;
  --ops-accent-soft: rgba(201, 90, 55, 0.22);
}
[data-theme='light'] .ops-panel {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.85),
    0 10px 24px rgba(143, 61, 33, 0.1);
}
[data-theme='light'] .ops-panel::after {
  background: linear-gradient(90deg, transparent, rgba(143, 61, 33, 0.06), transparent);
}
[data-theme='light'] .ops-rail-status {
  background: rgba(255, 255, 255, 0.92);
}
[data-theme='light'] .ops-rail .ops-label,
[data-theme='light'] .ops-rail .ops-chip {
  color: var(--ops-label);
}
[data-theme='light'] .ops-rail .ops-value {
  color: var(--ops-value);
}
[data-theme='light'] .ops-rail .ops-note,
[data-theme='light'] .ops-rail .ops-unit,
[data-theme='light'] .ops-rail-status span {
  color: var(--ops-foot);
}
[data-theme='light'] .ops-rail .ops-src {
  color: var(--ops-src);
}
[data-theme='light'] .ops-rail .ops-rail-title {
  color: var(--ops-title);
}

/* ══════════════════════════════════════════════════════════════════════
   RESPONSIVE
   The rails flank the constellation only where there is genuinely room for
   both. Below that they are removed rather than shrunk into illegibility —
   the constellation is the hero, and on a phone it already reflows into the
   platform index.
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 1439px) {
  .ops-rail {
    width: clamp(178px, 14vw, 210px);
    gap: 8px;
  }
  .ops-panel {
    padding: 9px 10px 8px;
  }
  .ops-value {
    font-size: clamp(17px, 1.5vw, 21px);
  }
  .ops-spark,
  .ops-orbits {
    height: 22px;
  }
  .ops-bars {
    height: 18px;
  }
}
@media (max-width: 1279px) {
  .ops-rail {
    display: none !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ops-rail,
  .ops-rail-pulse,
  .ops-panel::after,
  .ops-leds i,
  .ops-orbits i,
  .ops-dot {
    animation: none !important;
    opacity: 1 !important;
  }
  .ops-meter-fill,
  .ops-bars i,
  .ops-spark-line {
    transition: none !important;
  }
}

/* ── v16: state follows /api/status/ai — no "live" signal while the AI service is down ── */
.cst-live.is-down::before {
  background: #8a8a85;
  box-shadow: none;
  animation: none;
}
.ops-panel[data-ops-ai].is-down .ops-value {
  color: #e8a07c;
}
