/* ═══════════════════════════════════════════════════════════════════════════
   Spectrum hero art: a browser window showing an operator screen.

   Uses the .part window frame from /product-art.css; this file is only the
   scene (.part-spectrum). The screen inside follows RAYLUX-STD-HMI-001: gray
   background, black bold values, gray equipment (white fill = running), and
   saturated color ONLY for the alarm (P1 red + square). No beam.

   MOTION: one 12.6 s loop (9 x the standard's 1.4 s alarm pulse, so the pulse
   never drifts against the loop). Runs ONLY under .is-playing (main.js).
     0.0 s   EQ level rising from 58 %
     4.2 s   P1 alarm: value red, square, row slides in, pulsing (unacknowledged)
     5.2 s   cursor arrives; 6.8 s clicks Ack
     7.0 s   pulse stops, row holds steady
     7.8 s   pump starts (gray to white), level falls
     9.4 s   alarm clears, row fades; 11.8 s pump stops; loop resets
   Without JS, or under reduced motion, the base styles are the still: a
   normal state, level 58 %, pump stopped, no alarm.

   All keyframe times are percentages of 12.6 s: 4.2 s = 33.33 %,
   7.0 s = 55.56 %, 7.8 s = 61.9 %, 9.4 s = 74.6 %.
   ═══════════════════════════════════════════════════════════════════════════ */

@property --sp-lvl { syntax: "<integer>"; inherits: true; initial-value: 58; }
@property --sp-tr { syntax: "<integer>"; inherits: true; initial-value: 0; }
@property --sp-c { syntax: "<color>"; inherits: true; initial-value: #e12d39; }

.part-spectrum {
  container-type: inline-size;
  /* HMI palette (RAYLUX-STD-HMI-001). The operator screen is light gray in
     both site themes: it is the product's screen, not the page's. */
  --h-screen: #d8d8d8;
  --h-container: #e8e8e8;
  --h-input: #f5f5f5;
  --h-border: #b0b0b0;
  --h-header: #c4c4c4;
  --h-text: #333333;
  --h-text2: #666666;
  --h-dis: #9e9e9e;
  --h-val: #000000;
  --h-run: #ffffff;
  --h-stop: #808080;
  --h-trans: #b0b0b0;
  --h-p1: var(--error);
  --h-p1-pale: color-mix(in srgb, var(--error), #fff 60%);
  --sp-c: var(--error);
}

.part-spectrum .part-body.sp-body {
  display: block;
  gap: 0;
  padding: 0;
  min-height: 0;
}

/* ---------- the operator screen ---------- */
.sp-hmi {
  display: grid;
  gap: 10px;
  padding: 0 0 12px;
  background: var(--h-screen);
  color: var(--h-text);
}

.sp-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 4px 16px;
  padding: 9px 14px;
  background: var(--h-header);
  border-bottom: 1px solid var(--h-border);
}

.sp-id {
  display: grid;
  min-width: 0;
}

.sp-plant {
  color: var(--h-val);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.25;
}

.sp-crumb {
  color: var(--h-text2);
  font-size: 12px;
}

.sp-crumb i {
  margin: 0 5px;
  font-style: normal;
}

.sp-hr {
  display: flex;
  align-items: center;
  gap: 12px;
}

.sp-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--h-text);
  font-size: 12.5px;
  font-weight: 700;
}

.sp-cnt {
  display: grid;
  min-width: 1ch;
}

.sp-cnt > span {
  grid-area: 1 / 1;
}

.sp-time {
  color: var(--h-text2);
  font-size: 12.5px;
  font-weight: 600;
}

/* shape icon: gray outline always; the alarm color is a layer on top */
.sp-ico {
  display: block;
  flex: none;
  width: 12px;
  height: 12px;
  overflow: visible;
}

.sp-ico .sp-h {
  fill: none;
  stroke: var(--h-stop);
  stroke-width: 1.5;
}

.sp-ico .sp-s {
  fill: var(--sp-c);
}

.sp-shape {
  position: relative;
  display: grid;
}

.sp-shape > * {
  grid-area: 1 / 1;
}

/* ---------- KPI strip ---------- */
.sp-kpis {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
  padding: 0 12px;
}

.sp-kpi {
  position: relative;
  display: grid;
  gap: 3px;
  padding: 9px 11px 10px;
  background: var(--h-container);
  border: 1px solid var(--h-border);
  border-radius: var(--r-sm);
}

.sp-kl {
  color: var(--h-text2);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.2;
}

.sp-kv {
  display: grid;
}

.sp-kv > span {
  grid-area: 1 / 1;
  white-space: nowrap;
}

.sp-kv b {
  color: var(--h-val);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
}

.sp-kv small {
  margin-left: 3px;
  color: var(--h-text2);
  font-size: 12px;
  font-weight: 500;
}

.sp-kv .sp-kv-a b {
  color: var(--sp-c);
}

.sp-sqt {
  position: absolute;
  top: 11px;
  right: 11px;
  width: 11px;
  height: 11px;
  background: var(--sp-c);
}

/* ---------- process + alarms ---------- */
.sp-main {
  display: grid;
  grid-template-columns: minmax(300px, 1.15fr) minmax(0, 1fr);
  gap: 8px;
  padding: 0 12px;
}

.sp-proc,
.sp-alarms {
  min-width: 0;
  background: var(--h-container);
  border: 1px solid var(--h-border);
  border-radius: var(--r-sm);
}

.sp-proc {
  padding: 6px 6px 2px;
}

.sp-svg {
  display: block;
  width: 100%;
  height: auto;
}

.sp-svg text {
  fill: var(--h-text2);
  font-family: var(--f-ui);
  font-size: 12px;
  font-weight: 500;
}

.sp-svg .sp-strong {
  fill: var(--h-text);
  font-weight: 700;
}

.sp-svg .sp-vessel {
  fill: var(--h-input);
  stroke: var(--h-text);
  stroke-width: 1.5;
}

.sp-svg .sp-liquid {
  fill: var(--h-trans);
  transform: scaleY(0.58);
  transform-box: fill-box;
  transform-origin: 50% 100%;
}

.sp-svg .sp-limit {
  fill: none;
  stroke: var(--h-text2);
  stroke-width: 1;
  stroke-dasharray: 4 3;
}

.sp-svg .sp-pipe {
  fill: none;
  stroke: var(--h-stop);
  stroke-width: 5;
}

.sp-svg .sp-flow {
  fill: none;
  stroke: var(--h-run);
  stroke-width: 1.5;
  stroke-dasharray: 4 6;
  opacity: 0;
}

.sp-svg .sp-flow-in {
  opacity: 1;
}

.sp-svg .sp-pump {
  fill: var(--h-stop);
  stroke: var(--h-text);
  stroke-width: 1.5;
}

.sp-svg .sp-imp {
  fill: none;
  stroke: var(--h-text);
  stroke-width: 1.5;
  stroke-linejoin: round;
}

.sp-svg .sp-sqs {
  fill: var(--sp-c);
  opacity: 0;
}

.sp-svg .sp-pstate {
  text-anchor: middle;
}

.sp-svg .sp-pstate-on {
  opacity: 0;
}

.sp-alarms {
  position: relative;
  display: grid;
  grid-template-rows: auto auto 1fr;
  overflow: hidden;
}

.sp-ah {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 7px 8px 7px 11px;
}

.sp-ackw {
  position: relative;
}

.sp-ackb {
  display: block;
  padding: 3px 12px;
  background: var(--h-container);
  border: 1px solid var(--h-border);
  border-radius: var(--r-sm);
  color: var(--h-dis);
  font-size: 12px;
  font-weight: 700;
  line-height: 1.4;
}

.sp-cursor {
  position: absolute;
  z-index: 2;
  top: 50%;
  left: 50%;
  width: 16px;
  height: 22px;
  opacity: 0;
  transform-origin: 0 0;
  pointer-events: none;
}

.sp-cursor path {
  fill: #000;
  stroke: #fff;
  stroke-width: 1.2;
  stroke-linejoin: round;
}

.sp-th,
.sp-row {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) 52px;
  align-items: center;
  gap: 4px;
  padding: 0 10px 0 11px;
}

.sp-th {
  padding-block: 5px;
  background: var(--h-header);
  color: var(--h-text2);
  font-size: 11px;
  font-weight: 600;
}

.sp-list {
  position: relative;
  min-height: 62px;
}

.sp-empty {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  margin: 0;
  color: var(--h-text2);
  font-size: 12px;
}

.sp-row {
  position: absolute;
  inset: 0 0 auto;
  min-height: 54px;
  border-bottom: 1px solid var(--h-border);
  background: var(--h-input);
  opacity: 0;
}

.sp-desc {
  display: grid;
  min-width: 0;
}

.sp-desc b {
  color: var(--h-val);
  font-size: 12.5px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sp-desc span {
  color: var(--h-text2);
  font-size: 11.5px;
  white-space: nowrap;
}

.sp-state {
  display: grid;
  justify-items: end;
  font-size: 11.5px;
  font-weight: 700;
}

.sp-state > span {
  grid-area: 1 / 1;
}

.sp-un {
  color: var(--sp-c);
  opacity: 0;
}

.sp-ak {
  color: var(--h-text);
}

/* ---------- gates (base = the still) ---------- */
.sp-on { opacity: 0; }

/* ---------- motion: only while on screen ---------- */
.part-spectrum.is-playing {
  animation:
    sp-lvl 12.6s linear infinite,
    sp-tr 12.6s ease-in-out infinite,
    sp-pulse 12.6s ease-in-out infinite;
}

.part-spectrum.is-playing .sp-n-lvl::before {
  counter-reset: part-n var(--sp-lvl);
  content: counter(part-n);
}

.part-spectrum.is-playing .sp-n-tr::before {
  counter-reset: part-n var(--sp-tr);
  content: counter(part-n);
}

.part-spectrum.is-playing .sp-liquid { animation: sp-fill 12.6s linear infinite; }
.part-spectrum.is-playing .sp-on { animation: sp-on 12.6s linear infinite; }
.part-spectrum.is-playing .sp-off { animation: sp-off 12.6s linear infinite; }
.part-spectrum.is-playing .sp-row { animation: sp-row 12.6s ease-in-out infinite; }
.part-spectrum.is-playing .sp-empty { animation: sp-empty 12.6s ease-in-out infinite; }
.part-spectrum.is-playing .sp-un { animation: sp-un 12.6s linear infinite; }
.part-spectrum.is-playing .sp-ak { animation: sp-ak 12.6s linear infinite; }
.part-spectrum.is-playing .sp-ackb { animation: sp-ackb 12.6s ease-in-out infinite; }
.part-spectrum.is-playing .sp-cursor { animation: sp-cursor 12.6s ease-in-out infinite; }
.part-spectrum.is-playing .sp-pump { animation: sp-pump 12.6s ease-in-out infinite; }
.part-spectrum.is-playing .sp-pstate-on { animation: sp-run 12.6s linear infinite; }
.part-spectrum.is-playing .sp-pstate-off { animation: sp-stop 12.6s linear infinite; }
.part-spectrum.is-playing .sp-sqs { animation: sp-on 12.6s linear infinite; }

.part-spectrum.is-playing .sp-flow-out {
  animation: sp-flowgate 12.6s ease-in-out infinite, sp-dash 1.2s linear infinite;
}

.part-spectrum.is-playing .sp-flow-in {
  animation: sp-dash 1.2s linear infinite;
}

/* The standard's pulse: alarm color to a pale tint (60 % white) and back,
   1.4 s, eased. Written out as keyframes so it stops exactly at Ack. */
@keyframes sp-pulse {
  0%, 33.3% { --sp-c: var(--h-p1); }
  38.89% { --sp-c: var(--h-p1-pale); }
  44.44% { --sp-c: var(--h-p1); }
  50% { --sp-c: var(--h-p1-pale); }
  55.56%, 100% { --sp-c: var(--h-p1); }
}

@keyframes sp-lvl {
  0% { --sp-lvl: 58; }
  33.33%, 61.9% { --sp-lvl: 86; }
  69.84% { --sp-lvl: 85; }
  74.6% { --sp-lvl: 82; }
  92.06%, 100% { --sp-lvl: 58; }
}

@keyframes sp-fill {
  0% { transform: scaleY(0.58); }
  33.33%, 61.9% { transform: scaleY(0.86); }
  69.84% { transform: scaleY(0.85); }
  74.6% { transform: scaleY(0.82); }
  92.06%, 100% { transform: scaleY(0.58); }
}

@keyframes sp-tr {
  0%, 61.9% { --sp-tr: 0; }
  69.84%, 93.65% { --sp-tr: 860; }
  98.4%, 100% { --sp-tr: 0; }
}

/* Alarm visible: 4.2 s to 9.4 s. Snaps, so the red never half-appears. */
@keyframes sp-on {
  0%, 33.2% { opacity: 0; }
  33.5%, 74.5% { opacity: 1; }
  74.8%, 100% { opacity: 0; }
}

@keyframes sp-off {
  0%, 33.2% { opacity: 1; }
  33.5%, 74.5% { opacity: 0; }
  74.8%, 100% { opacity: 1; }
}

@keyframes sp-row {
  0%, 33.2% { opacity: 0; transform: translateX(28px); }
  36%, 74.6% { opacity: 1; transform: none; }
  79.4%, 100% { opacity: 0; transform: none; }
}

@keyframes sp-empty {
  0%, 33.2% { opacity: 1; }
  36%, 77% { opacity: 0; }
  81%, 100% { opacity: 1; }
}

@keyframes sp-un {
  0%, 33.2% { opacity: 0; }
  33.5%, 55.4% { opacity: 1; }
  55.7%, 100% { opacity: 0; }
}

@keyframes sp-ak {
  0%, 55.4% { opacity: 0; }
  55.7%, 100% { opacity: 1; }
}

/* Ack button: dead, then live while the alarm is unacknowledged, pressed,
   then dead again. */
@keyframes sp-ackb {
  0%, 35.5% { background: var(--h-container); color: var(--h-dis); transform: none; }
  37.5%, 53.5% { background: var(--h-input); color: var(--h-text); transform: none; }
  54.4%, 55.6% { background: var(--h-header); color: var(--h-text); transform: translateY(1px); }
  57%, 58.5% { background: var(--h-input); color: var(--h-text); transform: none; }
  60.5%, 100% { background: var(--h-container); color: var(--h-dis); transform: none; }
}

/* Cursor: tip anchored on the center of the Ack button. */
@keyframes sp-cursor {
  0%, 40% { opacity: 0; transform: translate(74px, 54px); }
  42% { opacity: 1; transform: translate(74px, 54px); }
  49.2%, 53.8% { opacity: 1; transform: translate(0, 0); }
  54.9% { opacity: 1; transform: translate(0, 0) scale(0.85); }
  56.3%, 60% { opacity: 1; transform: translate(0, 0); }
  63%, 100% { opacity: 0; transform: translate(0, 0); }
}

/* Pump symbol: stopped gray, transition gray, running white. */
@keyframes sp-pump {
  0%, 61.9% { fill: var(--h-stop); }
  63.5% { fill: var(--h-trans); }
  65.1%, 93.65% { fill: var(--h-run); }
  95% { fill: var(--h-trans); }
  96.5%, 100% { fill: var(--h-stop); }
}

@keyframes sp-run {
  0%, 61.8% { opacity: 0; }
  62.2%, 93.5% { opacity: 1; }
  93.9%, 100% { opacity: 0; }
}

@keyframes sp-stop {
  0%, 61.8% { opacity: 1; }
  62.2%, 93.5% { opacity: 0; }
  93.9%, 100% { opacity: 1; }
}

@keyframes sp-flowgate {
  0%, 62% { opacity: 0; }
  66%, 93.65% { opacity: 1; }
  96%, 100% { opacity: 0; }
}

@keyframes sp-dash {
  to { stroke-dashoffset: -20; }
}

/* Reduced motion: the base styles are the still. */
@media (prefers-reduced-motion: reduce) {
  .part-spectrum,
  .part-spectrum * {
    animation: none !important;
  }

  .part-spectrum .sp-n-lvl::before,
  .part-spectrum .sp-n-tr::before {
    content: none !important;
  }
}

/* ---------- narrow: the window is a container, not the viewport ---------- */
@container (max-width: 540px) {
  .sp-main {
    grid-template-columns: minmax(0, 1fr);
  }

  .sp-kpis {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
