/* 40 Modules (#servis): the module swap. An axonometric wheel module (rail, flange with 3 bolts,
   connector, inverter, hub motor, wheel) over three steps and a swap clock; then two points and
   the Rescue & Cargo / Armox cards.
   Static (no motion, no JS, viewport under 540 px tall): exploded and labelled drawing, steps in
   a row, clock at 03:00. Behind .ar-motion the track pins the stage and --ar-progress scrubs the
   drawing's paused animations; the script sets data-step, aria-current and the clock.
   The SVG is drawn assembled and carries its geometry (--ar-ex offsets, travel vectors, camera
   framings) and each animated part's keyframes (--ar-modules-anim); this file holds the timing. */

@property --ar-modules-anim {
  syntax: "*";
  inherits: false; /* a group's keyframes never leak to its parts */
}

.ar-modules {
  --ar-modules-signal: var(--wp--preset--color--chartreuse);
  /* Oxblood is too dark for a lamp on graphite; lifted, as in #redundance. */
  --ar-modules-alarm: color-mix(in srgb, var(--wp--preset--color--oxblood) 70%, var(--wp--custom--color--text-inverse));
  /* SVG text, viewBox units, running against the drawing's scale: about 10-14 px on screen. */
  --ar-modules-label: clamp(11px, 38px - 3.5vw, 26px);
}

.ar-modules .ar-lead {
  color: var(--ar-fg);
  font-family: var(--wp--preset--font-family--display);
  font-size: var(--wp--preset--font-size--heading-s);
  font-weight: 700;
  letter-spacing: var(--wp--custom--tracking--wide);
}

/* 1. Stage: phones stack drawing, steps, clock; from 768 px the inset joins, beside the clock
      (portrait) or in its own column (landscape). */

.ar-modules__track { margin-block-start: var(--wp--preset--spacing--50); }

.ar-modules__stage {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "svg" "steps" "timer";
  gap: var(--wp--preset--spacing--40);
}

.ar-modules__svg { grid-area: svg; width: 100%; height: auto; }
.ar-modules__steps { grid-area: steps; }
.ar-modules__timer { grid-area: timer; }
.ar-modules__inset { grid-area: inset; display: none; }

/* The HUD corners (.ar-hud-frame) frame the drawing's cell, not the whole stage. */
.ar-modules__stage::before {
  position: static;
  grid-area: svg;
  margin: -0.5rem;
}

@media (min-width: 768px) {
  .ar-modules { --ar-modules-label: 12px; }
  .ar-modules__inset { display: block; }

  .ar-modules__stage {
    grid-template-columns: minmax(0, 1fr) clamp(12rem, 34%, 17rem);
    grid-template-areas: "svg svg" "steps steps" "timer inset";
  }
}

@media (min-width: 768px) and (min-aspect-ratio: 5/4) {
  .ar-modules { --ar-modules-label: 13px; }
  .ar-modules__inset { align-self: start; }
  .ar-modules__timer { align-self: end; }

  .ar-modules__stage {
    grid-template-columns: minmax(0, 1fr) clamp(12.5rem, 22%, 19rem);
    grid-template-areas: "svg inset" "steps timer";
    column-gap: clamp(1.5rem, 3vw, 3rem);
  }
}

@media (min-width: 1280px) and (min-aspect-ratio: 5/4) {
  .ar-modules { --ar-modules-label: 11px; }
}

/* 2. Drawing: outlines keep one screen width, the cable and tread scale. The bolts and the
      connector are a shade brighter, the rail a shade quieter. Static = exploded (--ar-ex). */

.ar-modules__svg :is(path, ellipse, circle) {
  fill: var(--wp--preset--color--graphite);
  stroke: var(--wp--preset--color--silver);
  stroke-width: 1.25;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

.ar-modules__svg .ar-modules__top { fill: color-mix(in srgb, var(--wp--preset--color--graphite) 74%, var(--wp--preset--color--silver)); }
.ar-modules__svg .ar-modules__side { fill: color-mix(in srgb, var(--wp--preset--color--graphite) 55%, var(--wp--preset--color--ink)); }
.ar-modules__svg .ar-modules__cut { fill: url(#ar-modules-hatch); }
.ar-modules__svg :is(.ar-modules__hollow, .ar-modules__hole, .ar-modules__key) { fill: var(--wp--preset--color--ink); }

/* Open paths that enclose an area (arc, elbow, corners, curve); single lines need no rule. */
.ar-modules__svg :is(.ar-modules__rib, .ar-modules__leader, .ar-modules__bracket, .ar-modules__cable) { fill: none; }

.ar-modules__svg :is(.ar-modules__rail :is(path, ellipse), .ar-modules__thread, .ar-modules__rib, .ar-modules__leader,
  .ar-modules__bracket, .ar-modules__cable, .ar-modules__lugs),
#ar-modules-hatch path {
  stroke: var(--wp--preset--color--steel);
}

#ar-modules-hatch path { stroke-width: 1.5; vector-effect: none; }
.ar-modules__svg .ar-modules__axis { stroke: var(--wp--preset--color--iron); stroke-dasharray: 14 4 2 4; }
.ar-modules__svg .ar-modules__cable { stroke-width: 5.5; vector-effect: none; }
.ar-modules__svg .ar-modules__lugs { stroke-width: 3.5; vector-effect: none; }
.ar-modules__svg .ar-modules__run { stroke-linecap: butt; }

.ar-modules__svg :is(.ar-modules__bolt, .ar-modules__plug, .ar-modules__socket) :is(path, ellipse) {
  stroke: var(--ar-modules-part, var(--wp--preset--color--mist));
}

.ar-modules__svg .ar-modules__bolt .ar-modules__thread { stroke: var(--ar-modules-part, var(--wp--preset--color--steel)); }
.ar-modules__svg :is(.ar-modules__led, .ar-modules__lamp, .ar-modules__dot) { fill: var(--wp--preset--color--steel); stroke: none; }
.ar-modules__svg .ar-modules__dot { fill: var(--wp--preset--color--mist); }

.ar-modules__svg text {
  fill: var(--wp--preset--color--mist);
  font-family: var(--wp--preset--font-family--display);
  font-size: var(--ar-modules-label);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.ar-modules__slide,
.ar-modules__bolt {
  translate: var(--ar-ex);
}

.ar-modules__svg :is(.ar-modules__module--new, .ar-modules__tray, .ar-modules__callout, .ar-modules__tag, .ar-modules__click) {
  display: none;
}

/* 3. Steps and clock */

.ar-modules__steps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--wp--preset--spacing--30);
  margin: 0;
  padding: 0;
  list-style: none;
}

.ar-modules__steps li {
  position: relative;
  display: grid;
  align-content: start;
  gap: 0.35rem;
  padding-block-start: 0.9rem;
  color: var(--ar-fg);
  font-family: var(--wp--preset--font-family--display);
  font-size: var(--wp--preset--font-size--x-large);
  font-weight: 700;
  line-height: var(--wp--custom--leading--snug);
  text-wrap: balance;
}

/* Track (::before) and fill (::after): the fill is the step's own progress, full when static. */
.ar-modules__steps li::before,
.ar-modules__steps li::after {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 2px;
  background-color: var(--ar-line);
  transform-origin: left center;
}

.ar-modules__steps li::after { background-color: var(--ar-line-strong); }

.ar-modules__step-no {
  color: var(--ar-fg-muted);
  font-size: var(--wp--preset--font-size--x-small);
  line-height: 1.4;
  letter-spacing: var(--wp--custom--tracking--wider);
}

.ar-modules__timer .ar-readout__value {
  color: var(--ar-modules-signal); /* the one highlighted number of the stage */
  font-size: clamp(2.25rem, 1.6rem + 2.2vw, 4rem);
  letter-spacing: 0.02em;
  white-space: nowrap;
}

/* The display face has no tabular figures: the script puts each digit in a cell one zero wide,
   so the running clock does not jitter. */
.ar-modules__digit { display: inline-block; width: 1ch; text-align: center; }

@media (max-width: 767.98px) {
  .ar-modules__steps li { font-size: var(--wp--preset--font-size--medium); }
  .ar-modules__timer { grid-template-columns: auto auto; align-items: baseline; justify-content: space-between; }
  .ar-modules__timer .ar-readout__value { font-size: var(--wp--preset--font-size--heading-xl); }
}

/* 4. Inset photo, points and cards. Ratios hold the room while the images load. */

.ar-modules__inset img,
.ar-modules__card img {
  width: 100%;
  aspect-ratio: 404 / 277;
  object-fit: cover;
  background-color: var(--wp--preset--color--carbon);
}

.ar-modules__inset figcaption { margin-block-start: 0.6rem; }
.ar-modules__inset::before { inset: -0.5rem; }
.ar-modules__more { margin-block-start: var(--wp--preset--spacing--70); }

.ar-modules__points,
.ar-modules__cards {
  display: grid;
  gap: 0 var(--wp--preset--spacing--50);
  margin: 0;
  padding: 0;
  list-style: none;
}

.ar-modules__points li,
.ar-modules__card p {
  color: var(--ar-fg-muted);
  font-size: var(--wp--preset--font-size--medium);
  text-wrap: pretty;
}

.ar-modules__points li {
  padding-block: 1rem 1.25rem;
  border-block-start: 1px solid var(--ar-line);
}

.ar-modules__cards {
  gap: var(--wp--preset--spacing--40);
  margin-block-start: var(--wp--preset--spacing--50);
}

.ar-modules__card {
  display: grid;
  grid-template-rows: auto auto 1fr;
  overflow: hidden;
  border: 1px solid var(--ar-line);
  border-radius: var(--wp--custom--corner--md);
  background-color: var(--wp--preset--color--carbon);
}

.ar-modules__card img { aspect-ratio: 16 / 9; background-color: var(--wp--preset--color--graphite); }
.ar-modules__card h3 { padding: 1.25rem 1.5rem 0; }
.ar-modules__card p { padding: 0.6rem 1.5rem 1.5rem; }

@media (min-width: 768px) {
  .ar-modules__points,
  .ar-modules__cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* 5. Motion, where a pinned stage fits. Timeline (1 s = the whole track):
        step 1  0-34 %   bolts out 3-16 %, to the tray 16-29 %; camera leans in
        step 2  34-67 %  latch 38-42 %, plug out 42-54 %; camera on the connector
        step 3  67-100 % old module out 68-78 %, new in 79-89 %, plug 89-92 %, lamp 94 %,
                         bolts home 86-95 % (2 % apart, done by 99 %) */

@media (min-height: 540px) {
  .ar-motion .ar-modules__track { height: 300vh; }

  /* The drawing's row shrinks on short screens, never grows past the drawing; the stack centres. */
  .ar-motion .ar-modules__stage {
    position: sticky;
    top: var(--wp--custom--header--height);
    height: calc(100svh - var(--wp--custom--header--height));
    grid-template-rows: minmax(0, auto);
    align-content: center;
    padding-block: clamp(1rem, 4vh, 2.5rem);
  }

  .ar-motion .ar-modules__svg { height: 100%; min-height: 0; }
  .ar-motion .ar-modules__svg text { font-size: calc(var(--ar-modules-label) / 1.25); } /* camera 1.25 */
  .ar-motion .ar-modules__slide { translate: none; }
  .ar-motion :is(.ar-modules__labels, .ar-modules__axis--bolt, .ar-modules__axis--plug) { display: none; }

  .ar-motion .ar-modules__svg :is(.ar-modules__module--new, .ar-modules__tray, .ar-modules__callout, .ar-modules__tag,
    .ar-modules__module--old .ar-modules__click) {
    display: inline;
  }

  /* Every animated part is a paused 1 s animation whose clock is the scroll position. */
  .ar-motion .ar-modules__svg * {
    animation: var(--ar-modules-anim) 1s linear both paused;
    animation-delay: calc(var(--ar-progress, 0) * -1s + var(--ar-lag, 0s));
  }

  .ar-motion .ar-modules__spin,
  .ar-motion .ar-modules__run { transform-origin: 0 0; } /* hex centre; the bend the run shrinks to */

  /* Oxblood marks the faulty module; the signal colour its replacement and the current step's part. */
  .ar-motion .ar-modules__svg .ar-modules__module--old :is(.ar-modules__lamp, .ar-modules__dot) { fill: var(--ar-modules-alarm); }
  .ar-motion .ar-modules__svg .ar-modules__module--new .ar-modules__dot { fill: var(--ar-modules-signal); }
  .ar-motion .ar-modules__svg .ar-modules__click { stroke: var(--ar-modules-signal); stroke-width: 1.75; }

  .ar-motion .ar-modules__stage[data-step="1"] .ar-modules__bolt,
  .ar-motion .ar-modules__stage[data-step="2"] :is(.ar-modules__module--old .ar-modules__plug, .ar-modules__socket) {
    --ar-modules-part: var(--ar-modules-signal);
  }

  .ar-motion .ar-modules__svg :is(path, ellipse) { transition: stroke var(--wp--custom--duration--slow) var(--ar-ease-expo); }

  /* Steps: future grey, current filling in the signal colour, finished with a mist line. */
  .ar-motion .ar-modules__steps li {
    color: var(--ar-fg-muted);
    transition: color var(--wp--custom--duration--slow) var(--ar-ease-expo);
  }

  .ar-motion .ar-modules__steps li::after {
    background-color: var(--wp--preset--color--mist);
    scale: var(--ar-fill, 0) 1;
  }

  .ar-motion .ar-modules__steps li:nth-child(1) { --ar-fill: clamp(0, var(--ar-progress, 0) / 0.34, 1); }
  .ar-motion .ar-modules__steps li:nth-child(2) { --ar-fill: clamp(0, (var(--ar-progress, 0) - 0.34) / 0.33, 1); }
  .ar-motion .ar-modules__steps li:nth-child(3) { --ar-fill: clamp(0, (var(--ar-progress, 0) - 0.67) / 0.33, 1); }

  .ar-motion .ar-modules__steps [aria-current="step"],
  .ar-motion .ar-modules__steps [aria-current="step"] .ar-modules__step-no { color: var(--ar-fg); }
  .ar-motion .ar-modules__steps [aria-current="step"]::after { background-color: var(--ar-modules-signal); }
}

/* Literal easings: Chrome ignores var() in a keyframe's animation-timing-function. Camera scale
   and translate share each easing, so the focus point holds still. */
@keyframes ar-modules-camera {
  0%, 3%, 28%, 34%, 64%, 100% { translate: var(--ar-cam); scale: var(--ar-zoom); animation-timing-function: ease-in-out; }
  14%, 16% { translate: var(--ar-cam-bolts); scale: var(--ar-zoom-bolts); animation-timing-function: ease-in-out; }
  42%, 56% { translate: var(--ar-cam-plug); scale: var(--ar-zoom-plug); animation-timing-function: ease-in-out; }
}

/* Three turns over the shank (--ar-out), a hop to the tray (--ar-hop, --ar-park), home. */
@keyframes ar-modules-bolt {
  0%, 3% { translate: 0 0; animation-timing-function: ease-in-out; }
  16% { translate: var(--ar-out); animation-timing-function: cubic-bezier(0.3, 0, 0.6, 1); }
  22% { translate: var(--ar-hop); animation-timing-function: cubic-bezier(0.2, 0.6, 0.35, 1); }
  29%, 86% { translate: var(--ar-park); animation-timing-function: ease-in-out; }
  90% { translate: var(--ar-out); animation-timing-function: ease-in-out; }
  95%, 100% { translate: 0 0; }
}

@keyframes ar-modules-spin {
  0%, 3% { rotate: 0deg; animation-timing-function: ease-in-out; }
  16% { rotate: 1080deg; animation-timing-function: cubic-bezier(0.2, 0.6, 0.35, 1); }
  29%, 90% { rotate: 1260deg; animation-timing-function: ease-in-out; }
  95%, 100% { rotate: 0deg; }
}

@keyframes ar-modules-out {
  0%, 68% { translate: 0 0; opacity: 1; animation-timing-function: cubic-bezier(0.55, 0, 0.75, 0.4); }
  72% { opacity: 1; }
  78%, 100% { translate: var(--ar-away); opacity: 0; }
}

@keyframes ar-modules-in {
  0%, 79% { translate: var(--ar-away); opacity: 0; animation-timing-function: cubic-bezier(0.33, 1, 0.68, 1); }
  83% { opacity: 1; }
  89%, 100% { translate: 0 0; opacity: 1; }
}

@keyframes ar-modules-latch {
  0%, 37%, 43%, 100% { translate: 0 0; }
  39%, 41% { translate: 0 2.6px; }
}

@keyframes ar-modules-click {
  0%, 38%, 43%, 100% { opacity: 0; }
  39.5%, 41% { opacity: 1; }
}

@keyframes ar-modules-unplug {
  0%, 42% { translate: 0 0; animation-timing-function: ease-in-out; }
  54%, 100% { translate: var(--ar-unplug); }
}

@keyframes ar-modules-replug {
  0%, 89% { translate: var(--ar-unplug); animation-timing-function: ease-in-out; }
  92%, 100% { translate: 0 0; }
}

@keyframes ar-modules-run-out {
  0%, 42% { scale: 1 1; animation-timing-function: ease-in-out; }
  54%, 100% { scale: var(--ar-run) 1; }
}

@keyframes ar-modules-run-in {
  0%, 89% { scale: var(--ar-run) 1; animation-timing-function: ease-in-out; }
  92%, 100% { scale: 1 1; }
}

@keyframes ar-modules-lamp {
  0%, 93% { fill: var(--wp--preset--color--ink); }
  94.5%, 100% { fill: var(--ar-modules-signal); }
}

@keyframes ar-modules-tray {
  0%, 19%, 96%, 100% { opacity: 0; }
  23%, 92% { opacity: 1; }
}

@keyframes ar-modules-callout {
  0%, 34%, 67%, 100% { opacity: 0; }
  37%, 64% { opacity: 1; }
}

/* The faulty module's tag sets the scene, then clears the frame as the camera leans in. */
@keyframes ar-modules-tag-old {
  0%, 3% { opacity: 1; }
  8%, 100% { opacity: 0; }
}

@keyframes ar-modules-tag-new {
  0%, 82% { opacity: 0; }
  86%, 100% { opacity: 1; }
}
