/* 30 Redundancy (#redundance): the "knock the wheels out" simulator beside the three points of
   the document. A top-down chassis (SVG) carries six wheel buttons; the script sets the
   section's data-state (ok | tank | stopped) and each wheel's aria-pressed, and every visual of
   a state lives here. Without the script the markup is the ok state: six wheels, front and rear
   axle steering. Motion sits behind .ar-motion. */

.ar-redundancy {
  --ar-redundancy-signal: var(--wp--preset--color--chartreuse);
  --ar-redundancy-alarm: var(--wp--preset--color--oxblood);
  /* Oxblood itself is too dark to outline anything on ink; lifted, it holds 5.6:1. */
  --ar-redundancy-alarm-line: color-mix(in srgb, var(--wp--preset--color--oxblood) 55%, var(--wp--custom--color--text-inverse));
  --ar-redundancy-state: var(--wp--custom--duration--slow) var(--ar-ease-expo); /* state changes, under 300 ms */
}

/* 1. Layout: the copy beside the simulator from 1024 px, above it below that */

.ar-redundancy__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--wp--preset--spacing--60);
}

@media (min-width: 1024px) {
  .ar-redundancy__grid {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    align-items: center;
    column-gap: clamp(2.5rem, 5vw, 5rem);
  }
}

/* 2. The three points, numbered like readouts */

.ar-redundancy__points {
  margin: var(--wp--preset--spacing--40) 0 0;
  padding: 0;
  list-style: none;
  counter-reset: ar-redundancy;
}

.ar-redundancy__points li {
  position: relative;
  padding-block: 1rem 1.25rem;
  padding-inline-start: 2.5rem;
  border-block-start: 1px solid var(--ar-line);
  color: var(--ar-fg-muted);
  font-size: var(--wp--preset--font-size--medium);
  text-wrap: pretty;
  counter-increment: ar-redundancy;
}

.ar-redundancy__points li::before {
  content: counter(ar-redundancy, decimal-leading-zero);
  content: counter(ar-redundancy, decimal-leading-zero) / ""; /* the list already counts */
  position: absolute;
  top: 1.25rem;
  left: 0;
  color: var(--ar-fg-muted);
  font-family: var(--wp--preset--font-family--display);
  font-size: var(--wp--preset--font-size--x-small);
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: var(--wp--custom--tracking--wider);
}

/* 3. Simulator panel: a dark screen in HUD corners. Phones stack it in source order, the readouts
      under the chassis (where a value that wraps differently cannot shift the wheels); from
      600 px the readouts stand beside the chassis. */

.ar-redundancy__sim {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--wp--preset--spacing--40);
  padding: clamp(1rem, 3vw, 2rem);
  background-color: var(--wp--preset--color--ink);
}

.ar-redundancy__sim > .ar-caption:first-child {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

/* A small tyre in the wheels' own outline: "these are the things to click". */
.ar-redundancy__sim > .ar-caption:first-child::before {
  content: "";
  flex: none;
  width: 0.6rem;
  height: 1rem;
  border: 1.5px solid var(--ar-redundancy-signal);
  border-radius: 3px;
}

.ar-redundancy__sim > .ar-caption:last-child {
  justify-self: end;
  text-align: end;
}

@media (min-width: 600px) {
  .ar-redundancy__sim > .ar-caption:first-child { grid-area: hint; }
  .ar-redundancy__sim > .ar-caption:last-child { grid-area: note; }
  .ar-redundancy__chassis { grid-area: chassis; }
  .ar-redundancy__status { grid-area: status; }

  /* The button sits under the chassis it resets and shares the foot row with the note. */
  .ar-redundancy__sim {
    grid-template-columns: clamp(14rem, 54%, 19rem) minmax(0, 1fr);
    grid-template-areas:
      "hint    hint"
      "chassis status"
      "foot    foot";
    column-gap: clamp(1.5rem, 5%, 2.5rem);
  }

  .ar-redundancy__sim > [data-reset] {
    grid-area: foot;
    justify-self: start;
  }

  .ar-redundancy__sim > .ar-caption:last-child {
    grid-area: foot;
    align-self: center;
  }
}

/* Without the script nothing can be knocked out: no hint, no reset, no pointer. */
.no-js .ar-redundancy__sim > :is(.ar-caption:first-child, [data-reset]) {
  display: none;
}

.no-js .ar-redundancy__wheel {
  pointer-events: none;
}

/* 4. Chassis. The SVG and the wheel buttons share one box in the viewBox's ratio, so one
      viewBox unit (--u, resolved in the children against this container) is the same length
      for both, and the buttons sit exactly on the drawn wheel spots at any size. */

.ar-redundancy__chassis {
  --u: calc(100cqw / 400);
  position: relative;
  justify-self: center;
  align-self: start;
  width: min(100%, 17rem);
  aspect-ratio: 400 / 640;
  container-type: inline-size;
}

@media (min-width: 600px) {
  .ar-redundancy__chassis {
    width: 100%;
  }
}

.ar-redundancy__svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.ar-redundancy__svg :is(path, rect, circle) {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.ar-redundancy__axis {
  stroke: var(--wp--preset--color--iron);
  stroke-dasharray: 14 5 2 5;
}

.ar-redundancy__chevron {
  stroke: var(--ar-fg-muted);
  stroke-width: 2;
}

.ar-redundancy__label {
  fill: var(--ar-fg-muted);
  font-family: var(--wp--preset--font-family--display);
  font-size: 18px; /* viewBox units: about 12 px on a phone's 17rem chassis */
  font-weight: 700;
  letter-spacing: var(--wp--custom--tracking--wider);
}

.ar-redundancy__svg .ar-redundancy__deck {
  fill: color-mix(in srgb, var(--wp--preset--color--graphite) 70%, transparent);
  stroke: var(--wp--preset--color--steel);
  stroke-width: 1.5;
}

.ar-redundancy__frame,
.ar-redundancy__bay {
  stroke: var(--wp--preset--color--iron);
}

.ar-redundancy__svg .ar-redundancy__beam {
  stroke: color-mix(in srgb, var(--wp--preset--color--iron) 55%, transparent);
  stroke-width: 10;
  stroke-linecap: butt;
}

.ar-redundancy__bay {
  stroke-dasharray: 4 4;
}

.ar-redundancy__svg :is(.ar-redundancy__mast, .ar-redundancy__motor, .ar-redundancy__ecu) {
  fill: var(--wp--preset--color--graphite);
  stroke: var(--wp--preset--color--silver);
  stroke-width: 1.5;
}

.ar-redundancy__lens {
  stroke: var(--wp--preset--color--silver);
  stroke-width: 1.5;
}

.ar-redundancy__shaft {
  stroke: var(--wp--preset--color--steel);
  stroke-width: 5;
}

.ar-redundancy__bus,
.ar-redundancy__link {
  stroke: color-mix(in srgb, var(--wp--preset--color--mist) 55%, transparent);
  stroke-width: 1.5;
}

/* Live parts in the signal colour: motor lamps, the controller lamp and, while the axles
   steer, the two steering racks. */
.ar-redundancy__svg :is(.ar-redundancy__led, .ar-redundancy__ecu-led, .ar-redundancy__racks circle) {
  fill: var(--ar-redundancy-signal);
  stroke: none;
}

.ar-redundancy__racks path {
  stroke: var(--ar-redundancy-signal);
  stroke-width: 3;
}

/* A knocked-out unit: motor dead, its feed cut. */
.ar-redundancy__unit.is-lost .ar-redundancy__motor {
  fill: var(--ar-redundancy-alarm);
  stroke: var(--ar-redundancy-alarm-line);
}

.ar-redundancy__svg .ar-redundancy__unit.is-lost .ar-redundancy__led {
  fill: var(--wp--preset--color--ink);
}

.ar-redundancy__unit.is-lost .ar-redundancy__link {
  stroke: var(--ar-redundancy-alarm-line);
  stroke-dasharray: 3 5;
}

/* Tank and stopped: the racks no longer steer. */
.ar-redundancy:is([data-state="tank"], [data-state="stopped"]) .ar-redundancy__racks path {
  stroke: var(--wp--preset--color--iron);
  stroke-dasharray: 6 6;
}

.ar-redundancy:is([data-state="tank"], [data-state="stopped"]) .ar-redundancy__svg .ar-redundancy__racks circle {
  fill: var(--wp--preset--color--iron);
}

/* Tank: one arrow per side, one forward and one back, around the centre: the differential turn.
   Painted from the group, which the <use> copy inherits from. */
.ar-redundancy__turn {
  fill: none;
  stroke: var(--ar-redundancy-signal);
  stroke-width: 3.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0;
}

.ar-redundancy[data-state="tank"] .ar-redundancy__turn {
  opacity: 1;
}

/* Stopped: the chassis powers down (the PŘEDEK label is HUD, not chassis: it stays legible),
   the controller lamp turns to alarm. */
.ar-redundancy[data-state="stopped"] .ar-redundancy__svg > :not(.ar-redundancy__label, .ar-redundancy__chevron, .ar-redundancy__turn) {
  opacity: 0.4;
}

.ar-redundancy[data-state="stopped"] .ar-redundancy__svg .ar-redundancy__ecu-led {
  fill: var(--ar-redundancy-alarm-line);
}

/* ...inside an alarm frame tagged STOP. */
.ar-redundancy__chassis::before,
.ar-redundancy__chassis::after {
  position: absolute;
  z-index: 1;
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
}

.ar-redundancy__chassis::after {
  content: "";
  inset: -0.5rem;
  border: 1.5px solid var(--ar-redundancy-alarm-line);
  border-radius: var(--wp--custom--corner--md);
  box-shadow:
    inset 0 0 2rem color-mix(in srgb, var(--ar-redundancy-alarm) 45%, transparent),
    0 0 1.5rem color-mix(in srgb, var(--ar-redundancy-alarm) 35%, transparent);
}

.ar-redundancy__chassis::before {
  content: "STOP";
  content: "STOP" / ""; /* the Stav readout says it in words */
  top: -0.5rem;
  left: 0.75rem;
  z-index: 2;
  padding: 0.15rem 0.5rem;
  border-radius: var(--wp--custom--corner--sm);
  background-color: var(--ar-redundancy-alarm);
  color: var(--wp--custom--color--text-inverse);
  font-family: var(--wp--preset--font-family--display);
  font-size: var(--wp--preset--font-size--x-small);
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: var(--wp--custom--tracking--wider);
  translate: 0 -50%;
}

.ar-redundancy[data-state="stopped"] .ar-redundancy__chassis::before,
.ar-redundancy[data-state="stopped"] .ar-redundancy__chassis::after {
  visibility: visible;
  opacity: 1;
}

/* 5. Wheels. Each button is the tyre: graphite, a thin signal outline and tread lugs (::before)
      while it works; oxblood and hatched once knocked out. Drawn 60 × 112 units, never under
      44 px: a tyre the minimum widens grows outwards, its inner edge (x 114 / 286) stays put. */

.ar-redundancy__wheel {
  --w: max(44px, 60 * var(--u));
  --h: max(44px, 112 * var(--u));
  --pitch: calc(10 * var(--u));
  --lug: color-mix(in srgb, var(--wp--preset--color--steel) 80%, transparent);
  position: absolute;
  top: calc(var(--cy) * var(--u) - var(--h) / 2);
  left: calc(114 * var(--u) - var(--w));
  width: var(--w);
  height: var(--h);
  overflow: hidden;
  border: 1.5px solid var(--ar-redundancy-signal);
  border-radius: calc(12 * var(--u));
  background-color: var(--wp--preset--color--graphite);
  rotate: var(--ar-steer, 0deg);
  transition:
    background-color var(--ar-hover),
    border-color var(--ar-hover);
}

.ar-redundancy__wheel:is([data-wheel="3"], [data-wheel="4"], [data-wheel="5"]) { left: calc(286 * var(--u)); }
.ar-redundancy__wheel:is([data-wheel="0"], [data-wheel="3"]) { --cy: 172; }
.ar-redundancy__wheel:is([data-wheel="1"], [data-wheel="4"]) { --cy: 332; --ar-i: 1; }
.ar-redundancy__wheel:is([data-wheel="2"], [data-wheel="5"]) { --cy: 492; --ar-i: 2; }

/* Two staggered columns of lugs, one pitch taller than the tyre so they can roll. */
.ar-redundancy__wheel::before {
  content: "";
  position: absolute;
  inset: 0 0 calc(-1 * var(--pitch));
  background-image:
    linear-gradient(var(--lug) 0 40%, transparent 0),
    linear-gradient(var(--lug) 0 40%, transparent 0);
  background-position: 12% 0, 88% calc(var(--pitch) / 2);
  background-repeat: repeat-y;
  background-size: 38% var(--pitch);
}

.ar-redundancy__wheel[aria-pressed="true"] {
  border-color: var(--ar-redundancy-alarm-line);
  background-color: var(--ar-redundancy-alarm);
}

.ar-redundancy__wheel[aria-pressed="true"]::before {
  inset: 0;
  background-image: repeating-linear-gradient(-45deg, color-mix(in srgb, var(--wp--preset--color--ink) 55%, transparent) 0 3px, transparent 0 8px);
  background-position: 0 0;
  background-repeat: repeat;
  background-size: auto;
}

@media (hover: hover) {
  .ar-redundancy__wheel:hover {
    background-color: color-mix(in srgb, var(--wp--preset--color--graphite) 82%, var(--wp--custom--color--text-inverse));
  }

  .ar-redundancy__wheel[aria-pressed="true"]:hover {
    background-color: color-mix(in srgb, var(--ar-redundancy-alarm) 85%, var(--wp--custom--color--text-inverse));
  }
}

/* Axle steering (the ok state, also before the script runs): the front pair turns one way,
   the rear pair the other. Tank and stopped keep every wheel straight. */
.ar-redundancy:not([data-state="tank"], [data-state="stopped"]) .ar-redundancy__wheel:is([data-wheel="0"], [data-wheel="3"]) {
  --ar-steer: -12deg;
}

.ar-redundancy:not([data-state="tank"], [data-state="stopped"]) .ar-redundancy__wheel:is([data-wheel="2"], [data-wheel="5"]) {
  --ar-steer: 12deg;
}

/* Stopped: the wheels still on the chassis power down with it (colours only, so a focus ring
   on them keeps its full strength). */
.ar-redundancy[data-state="stopped"] .ar-redundancy__wheel:not([aria-pressed="true"]) {
  --lug: color-mix(in srgb, var(--wp--preset--color--iron) 70%, transparent);
  border-color: var(--wp--preset--color--steel);
  background-color: var(--wp--preset--color--carbon);
}

@media (forced-colors: active) {
  .ar-redundancy__wheel[aria-pressed="true"] {
    border-style: dashed;
  }
}

/* 6. Readouts: the count leads, the two texts follow; the Stav value carries a status lamp. */

.ar-redundancy__status {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-content: start;
  gap: 1.25rem var(--wp--preset--spacing--30);
}

.ar-redundancy__status .ar-readout:last-child {
  grid-column: 1 / -1;
}

/* Beside the chassis the readouts never move: the steering value keeps room for the two lines
   of tank mode, and on the full-width panel (where every value fits its share) the three rows
   split the chassis height evenly. */
@media (min-width: 600px) {
  .ar-redundancy__status {
    grid-template-columns: minmax(0, 1fr);
  }

  .ar-redundancy__status [data-out="steering"] {
    min-height: 2lh;
  }
}

@media (min-width: 1200px) {
  .ar-redundancy__status {
    grid-template-rows: repeat(3, 1fr);
  }
}

.ar-redundancy__status .ar-readout__value {
  font-size: var(--wp--preset--font-size--x-large);
  line-height: var(--wp--custom--leading--snug);
  text-wrap: balance;
}

.ar-redundancy__status [data-out="active"] {
  font-size: var(--wp--preset--font-size--heading-l);
  line-height: var(--wp--custom--leading--tight);
  white-space: nowrap;
}

.ar-redundancy__status [data-out="state"] {
  display: flex;
  gap: 0.6rem;
}

.ar-redundancy__status [data-out="state"]::before {
  content: "";
  flex: none;
  width: 0.55rem;
  height: 0.55rem;
  margin-block-start: calc((1lh - 0.55rem) / 2);
  border-radius: 50%;
  background-color: var(--ar-redundancy-signal);
  box-shadow: 0 0 10px color-mix(in srgb, var(--ar-redundancy-signal) 60%, transparent);
}

.ar-redundancy[data-state="stopped"] [data-out="state"]::before {
  background-color: var(--ar-redundancy-alarm-line);
  box-shadow: 0 0 10px var(--ar-redundancy-alarm);
}

/* 7. Motion (only behind the gate) */

/* Entrance: the panel fades up (data-reveal), the chassis outline plots in (.ar-draw), then
   the wheels drop in, front to rear. */
.ar-motion .ar-redundancy__sim:not(.is-revealed) .ar-redundancy__wheel {
  opacity: 0;
}

.ar-motion .ar-redundancy__sim.is-revealed .ar-redundancy__wheel {
  animation: ar-redundancy-boot 450ms var(--ar-ease-expo) calc(450ms + var(--ar-i, 0) * 80ms) backwards;
}

@keyframes ar-redundancy-boot {
  from {
    opacity: 0;
    scale: 0.7;
  }
}

/* State changes: steering angle, colours, arrows, power-down, alarm. A pressed tyre gives a
   little under the pointer. */
.ar-motion .ar-redundancy__wheel {
  transition:
    rotate var(--ar-redundancy-state),
    scale var(--wp--custom--duration--fast) var(--ar-ease-expo),
    background-color var(--ar-redundancy-state),
    border-color var(--ar-redundancy-state);
}

.ar-motion .ar-redundancy__wheel:active {
  scale: 0.94;
}

.ar-motion .ar-redundancy__svg > *,
.ar-motion .ar-redundancy__chassis::before,
.ar-motion .ar-redundancy__chassis::after {
  transition:
    opacity var(--ar-redundancy-state),
    visibility var(--ar-redundancy-state);
}

/* The outline keeps its draw-in (base.css .ar-draw) next to the power-down. */
.ar-motion .ar-redundancy__svg > .ar-draw {
  transition:
    stroke-dashoffset var(--ar-dur-long) var(--ar-ease-expo) var(--ar-delay, 0ms),
    opacity var(--ar-redundancy-state);
}

.ar-motion :is(.ar-redundancy__unit, .ar-redundancy__racks) > *,
.ar-motion .ar-redundancy__ecu-led {
  transition:
    fill var(--ar-redundancy-state),
    stroke var(--ar-redundancy-state),
    opacity var(--ar-redundancy-state);
}

/* Rolling tread: a live indicator, like the live dot (Ruling 1), so it loops — on working wheels
   while the machine drives. Lugs run towards the front; in tank mode the right side runs back,
   which is what turns the machine on the spot. */
.ar-motion .ar-redundancy:not([data-state="stopped"]) .ar-redundancy__wheel:not([aria-pressed="true"])::before {
  animation: ar-redundancy-roll 0.5s linear infinite;
}

.ar-motion .ar-redundancy[data-state="tank"] .ar-redundancy__wheel:is([data-wheel="3"], [data-wheel="4"], [data-wheel="5"])::before {
  animation-direction: reverse;
}

@keyframes ar-redundancy-roll {
  to {
    translate: 0 calc(-1 * var(--pitch));
  }
}

/* Impact: a knocked-out tyre flashes white; a restored one blinks back in the signal colour. */
.ar-motion .ar-redundancy__wheel::after {
  content: "";
  position: absolute;
  inset: 0;
  background-color: var(--ar-redundancy-signal);
  opacity: 0;
  animation: ar-redundancy-flash 300ms var(--ar-ease-expo);
}

.ar-motion .ar-redundancy__wheel[aria-pressed="true"]::after {
  background-color: var(--wp--custom--color--text-inverse);
  animation-name: ar-redundancy-hit;
}

@keyframes ar-redundancy-flash {
  from {
    opacity: 0.45;
  }
}

@keyframes ar-redundancy-hit {
  from {
    opacity: 0.85;
  }
}
