/* "A landmark or city-scale show" stage (stage-landmark.svg): an illustrative example, not a
   real project. One ELM HUB in a rack running ELM 2026 Architectural; its two 10 Gb ports each
   on their own network leg and switch. Leg A: three OCTO MK3 on the facade pixel bars. Leg B:
   two STORM 10 on DMX to wall washers at the base. A building management system triggers it through an S-PLAY SP1-1;
   Sentry flags a failed wall washer on the HUB's front screen and on the team's phone.
   Chapters: 0 the kit (beats: HUB, two legs + switches, OCTOs + facade, STORMs + washers, S-PLAY, BMS),
   1 the show runs, 2 on a schedule or a trigger, 3 Sentry catches a fault (loops).
   The pixel and washer colours are the show's own light, not UI colours.
   Every selector is scoped to the root class .st-landmark. Sibling of small.css. */

/* ---- the drawing ---- */
.st-landmark .lm-lbl { font-size: 15px; font-weight: 700; fill: #2f2f2f; letter-spacing: 0; transition: fill .4s var(--eds-ease); }
.st-landmark .lm-lbl--sub { font-weight: 600; fill: #4c4c4c; }
.st-landmark .lm-rack__cab { fill: #f4f4f4; stroke: #d9d9d9; stroke-width: 1.5; }
.st-landmark .lm-rack__blank { fill: #ececec; stroke: #d4d8db; stroke-width: 1; }
/* The 19-inch rack, front-on: rails with the hole pattern, panels screwed to them. */
.st-landmark .lm-rack__rail { fill: #d4d8db; }
.st-landmark .lm-rack__hole { fill: #9aa0a4; }
.st-landmark .lm-rack__screw { fill: #b5babd; }
.st-landmark .lm-rack__vent { fill: #d4d8db; }
.st-landmark .lm-screen polygon { opacity: 0; transition: opacity .5s var(--eds-ease); }
.st-landmark .lm-screen__tint { fill: #d32f2f; }
.st-landmark .lm-screen__bar { fill: #d32f2f; }

.st-landmark .lm-bldg { fill: #f4f4f4; stroke: #d9d9d9; stroke-width: 1.5; }
.st-landmark .lm-ledge, .st-landmark .lm-ground { fill: none; stroke: #d9d9d9; stroke-width: 1.5; }
.st-landmark .lm-bar { fill: #333; }
.st-landmark .lm-px { fill: #8a8a8a; transition: fill .6s var(--eds-ease); }

.st-landmark .lm-beam { fill: #ffd9a0; opacity: 0; transition: opacity .9s var(--eds-ease); }
.st-landmark .lm-fx__body { fill: #333; }
.st-landmark .lm-fx__lens { fill: #8a8a8a; transition: fill .6s var(--eds-ease); }
.st-landmark .lm-ring { fill: none; stroke: #d32f2f; stroke-width: 2.5; opacity: 0; }

.st-landmark .lm-bms__box { fill: #fff; stroke: #2f2f2f; stroke-width: 2; transition: stroke .4s var(--eds-ease); }
.st-landmark .lm-bms__icon { fill: none; stroke: #2f2f2f; stroke-width: 2; stroke-linejoin: round; }

.st-landmark .lm-clock circle { fill: #fff; stroke: #2f2f2f; }
.st-landmark .lm-clock line { stroke: #2f2f2f; }

.st-landmark .lm-phone { opacity: 0; transition: opacity .5s var(--eds-ease); }
.st-landmark .lm-phone__body { fill: #333; }
.st-landmark .lm-phone__screen { fill: #111; transition: fill .4s var(--eds-ease); }
.st-landmark .lm-msg { opacity: 0; transition: opacity .4s var(--eds-ease); }
.st-landmark .lm-msg__card { fill: #d32f2f; }
.st-landmark .lm-msg__bang { fill: none; stroke: #fff; stroke-width: 3; stroke-linecap: round; }
.st-landmark .lm-msg__line { fill: none; stroke: #bfbfbf; stroke-width: 3; stroke-linecap: round; }

/* Cables: each group carries its colour (--c) and liveness (--ss-live, the engine's dot). */
.st-landmark .lm-c { --c: #d9d9d9; transition: opacity .5s var(--eds-ease); }
.st-landmark .lm-c :is(.ss-net, .ss-dmx) { stroke: var(--c); transition: stroke .5s var(--eds-ease); }
/* The alert is not a cable: dashed (pathLength units), red once it fires. */
.st-landmark .lm-alert > path:first-child { stroke-dasharray: 1.6 1.6; }
.st-landmark .ss-rec { opacity: 0; }

/* ---- 0: THE KIT. Each group lands on its beat. ---- */
.st-landmark[data-chapter="0"] .ss-part { opacity: 0; transform: translateY(12px); }
.st-landmark[data-chapter="0"][data-beat="0"] .lm-hub,
.st-landmark[data-chapter="0"][data-beat="1"] :is(.lm-hub, .lm-net),
.st-landmark[data-chapter="0"][data-beat="2"] :is(.lm-hub, .lm-net, .lm-pixg),
.st-landmark[data-chapter="0"][data-beat="3"] :is(.lm-hub, .lm-net, .lm-pixg, .lm-wash),
.st-landmark[data-chapter="0"][data-beat="4"] :is(.lm-hub, .lm-net, .lm-pixg, .lm-wash, .lm-splayg),
.st-landmark[data-chapter="0"][data-beat="5"] .ss-part { opacity: 1; transform: none; }
/* While the kit lands, names are grey and the group a beat is about has its names in black. */
.st-landmark[data-chapter="0"] .lm-lbl { fill: #8a8a8a; }
.st-landmark[data-chapter="0"][data-beat="0"] .lm-hub .lm-lbl,
.st-landmark[data-chapter="0"][data-beat="1"] .lm-net .lm-lbl,
.st-landmark[data-chapter="0"][data-beat="2"] .lm-pixg .lm-lbl,
.st-landmark[data-chapter="0"][data-beat="3"] .lm-wash .lm-lbl,
.st-landmark[data-chapter="0"][data-beat="4"] .lm-splayg .lm-lbl,
.st-landmark[data-chapter="0"][data-beat="5"] .lm-bmsg .lm-lbl { fill: #000; }
/* Each landing group's own runs show their dot once, so what it adds reads clearly. */
.st-landmark[data-chapter="0"][data-beat="1"] .lm-leg,
.st-landmark[data-chapter="0"][data-beat="2"] :is(.lm-bus, .lm-pix),
.st-landmark[data-chapter="0"][data-beat="3"] :is(.lm-st, .lm-dmx),
.st-landmark[data-chapter="0"][data-beat="4"] .lm-splay,
.st-landmark[data-chapter="0"][data-beat="5"] .lm-bms { --c: #0ea5df; --ss-live: 1; }

/* ---- 1 on: THE SHOW RUNS. Both legs live end to end, pixels chasing, washers lit. ---- */
.st-landmark:not([data-chapter="0"]) :is(.lm-leg, .lm-bus, .lm-pix, .lm-st, .lm-dmx) { --c: #0ea5df; --ss-live: 1; }
.st-landmark:not([data-chapter="0"]) :is(.ss-rec, .ss-rec__playing) { opacity: 1; }
.st-landmark:not([data-chapter="0"]) .lm-beam { opacity: .55; }
.st-landmark:not([data-chapter="0"]) .lm-fx__lens { fill: #ffd9a0; }
.st-landmark[data-chapter="1"] .lm-px { animation: lm-look-a 2.4s linear infinite; animation-delay: calc(var(--y) * -.15s + var(--x) * -.08s); }
@keyframes lm-look-a { 0%, 100% { fill: #0ea5df; } 50% { fill: #e6f6fc; } }

/* ---- 2: ON A SCHEDULE OR A TRIGGER. The scheduler's clock turns; the BMS link pulses into the
   S-PLAY, then the S-PLAY's network link into the HUB, and a moment later the facade changes
   to a new look. The second link waits by delaying both its colour and its dot. ---- */
.st-landmark:is([data-chapter="2"], [data-chapter="3"]) .lm-clock { opacity: 1; }
.st-landmark:is([data-chapter="2"], [data-chapter="3"]) .lm-hand--m { animation: ss-clock 3s linear infinite; }
.st-landmark:is([data-chapter="2"], [data-chapter="3"]) .lm-hand--h { animation: ss-clock 36s linear infinite; }
.st-landmark[data-chapter="2"] :is(.lm-bms, .lm-splay) { --c: #0ea5df; --ss-live: 1; }
.st-landmark[data-chapter="2"] .lm-splay :is(.ss-net, .ss-pulse) { transition: stroke .5s var(--eds-ease) 1.2s, stroke-opacity 0s 1.2s; }
.st-landmark[data-chapter="2"] .lm-splay .ss-pulse { animation-delay: 1.2s; }
.st-landmark[data-chapter="2"] .lm-bms__box { stroke: #0ea5df; }
.st-landmark[data-chapter="2"] .lm-px { animation: lm-look-b 3s linear infinite; animation-delay: calc(3s - var(--x) * .08s - var(--y) * .1s); animation-fill-mode: backwards; }
.st-landmark[data-chapter="3"] .lm-px { animation: lm-look-b 3s linear infinite; animation-delay: calc(var(--x) * -.08s + var(--y) * -.1s); }
/* Before the trigger lands (the delay), the 0% frame holds: look A's blue. */
@keyframes lm-look-b { 0% { fill: #0ea5df; } 1%, 99% { fill: #f5b94a; } 50% { fill: #8e5cf2; } 100% { fill: #f5b94a; } }

/* ---- 3: SENTRY CATCHES A FAULT. One wall washer goes dark and red; RDM answers back down its
   DMX line; the HUB's front screen flags it; the alert reaches the team's phone. ---- */
.st-landmark[data-chapter="3"] .lm-beam.lm-fault { opacity: 0; transition-delay: .5s; }
.st-landmark[data-chapter="3"] .lm-fault .lm-fx__lens { fill: #d32f2f; transition-delay: .5s; }
.st-landmark[data-chapter="3"] .lm-ring { animation: lm-ring 1.8s ease-out .8s infinite; }
.st-landmark[data-chapter="3"] .lm-c--dmx1 .ss-pulse { animation-direction: reverse; }
.st-landmark[data-chapter="3"] .lm-screen__tint { opacity: .28; transition-delay: 1.4s; }
.st-landmark[data-chapter="3"] .lm-screen__bar { opacity: 1; transition-delay: 1.4s; }
.st-landmark[data-chapter="3"] .lm-phone { opacity: 1; transition-delay: 1.8s; }
.st-landmark[data-chapter="3"] .lm-alert { --c: #d32f2f; --ss-live: 1; }
.st-landmark[data-chapter="3"] .lm-phone__screen { fill: #fff; transition-delay: 2.4s; }
.st-landmark[data-chapter="3"] .lm-msg { opacity: 1; transition-delay: 2.6s; }
@keyframes lm-ring { 0% { opacity: .9; r: 16px; } 100% { opacity: 0; r: 38px; } }

@media (prefers-reduced-motion: reduce) {
  .st-landmark[data-chapter="1"] .lm-px { fill: #0ea5df; }
  .st-landmark:is([data-chapter="2"], [data-chapter="3"]) .lm-px { fill: #f5b94a; }
  .st-landmark[data-chapter="3"] .lm-ring { opacity: 1; }
}

/* Before play (the story shell's is-idle): a healthy system, every part shown. The last step
   is the Sentry fault, so undo it here: every washer lit, the HUB screen normal, the phone
   shown with no alert, no PLAYING label. The BMS, S-PLAY and their two links show as kit, grey. */
.st-landmark.is-idle .lm-beam.lm-fault { opacity: .55; }
.st-landmark.is-idle .lm-fault .lm-fx__lens { fill: #ffd9a0; }
.st-landmark.is-idle .lm-ring { animation: none; opacity: 0; }
.st-landmark.is-idle :is(.lm-screen__tint, .lm-screen__bar, .lm-msg) { opacity: 0; }
.st-landmark.is-idle .lm-phone { opacity: 1; }
.st-landmark.is-idle .lm-alert { --c: #d9d9d9; --ss-live: 0; }
.st-landmark.is-idle :is(.ss-rec, .ss-rec__playing) { opacity: 0; }
