/* Body MechaniX — motion layer
   Loaded after styles.css. Every rule here is gated so the site is fully
   static (final states) when JS is absent or the visitor prefers reduced
   motion: html.mx-motion is added by an inline head script only when
   (prefers-reduced-motion: reduce) is false. Focus-first: animations run
   once, travel short distances, and settle. */

/* ---------- Scroll reveal (auto-wired by motion.js) ---------- */
html.mx-motion .mx-r {
  opacity: 0;
  transform: translateY(14px);
}
html.mx-motion .mx-r.is-in {
  opacity: 1;
  transform: none;
  transition:
    opacity 0.55s ease var(--mxd, 0s),
    transform 0.55s cubic-bezier(0.22, 0.9, 0.3, 1) var(--mxd, 0s);
}

/* ---------- Work order: intake fill + stamp slam ---------- */
html.mx-motion .workorder__head,
html.mx-motion .workorder__row {
  opacity: 0;
}
html.mx-motion .workorder.is-played .workorder__head,
html.mx-motion .workorder.is-played .workorder__row {
  animation: mxWoRow 0.5s cubic-bezier(0.22, 0.9, 0.3, 1) var(--mxd, 0s) both;
}
html.mx-motion .workorder__stamp {
  opacity: 0;
}
html.mx-motion .workorder.is-played .workorder__stamp {
  animation: mxStamp 0.45s cubic-bezier(0.2, 1.35, 0.4, 1) var(--mxd, 1.4s) both;
}
@keyframes mxWoRow {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
@keyframes mxStamp {
  0%   { opacity: 0;    transform: rotate(-14deg) scale(2.3); }
  65%  { opacity: 0.95; transform: rotate(-5deg)  scale(0.94); }
  100% { opacity: 0.85; transform: rotate(-6deg)  scale(1); }
}

/* ---------- CTA band: phone underline draw ---------- */
.cta-band .phone-big { position: relative; }
.cta-band .phone-big::after {
  content: "";
  position: absolute;
  left: 6%;
  right: 6%;
  bottom: -2px;
  height: 3px;
  border-radius: 2px;
  background: var(--signal);
  transform: scaleX(1);
  transform-origin: 0 50%;
}
html.mx-motion .cta-band .phone-big::after {
  transform: scaleX(0);
  transition: transform 0.6s cubic-bezier(0.22, 0.9, 0.3, 1) 0.25s;
}
html.mx-motion .cta-band .phone-big.is-in::after {
  transform: scaleX(1);
}

/* ---------- FAQ micro-motion ---------- */
.faq summary::after { transition: transform 0.22s ease; }
.faq details[open] summary::after {
  content: "+";
  transform: rotate(45deg);
}
html.mx-motion .faq details[open] > p {
  animation: mxFaqIn 0.28s ease both;
}
@keyframes mxFaqIn {
  from { opacity: 0; transform: translateY(-4px); }
}

/* ---------- Service card arrow nudge ---------- */
.svc-card__go { transition: transform 0.18s ease; }
.svc-card:hover .svc-card__go { transform: translateX(4px); }

/* =====================================================================
   DIAGNOSTIC PANEL — animated hip fault-trace (homepage #difference)
   Resting/default state = end of the sequence (leg lifted, range
   restored) so no-JS and reduced-motion visitors see the finished
   diagram. html.mx-motion + :not(.is-played) rewinds it; .is-played
   runs the timeline:
     0.15s  pain pulses at the knee, SYMPTOM label
     1.20s  fault pulse travels up the femur to the hip
     2.00s  hip ping + ROOT CAUSE label
     2.35s  locked range arc (40°)
     2.90s  leg swings up, restored arc draws to 110°
     4.10s  RESTORED label + RANGE RESTORED stamp
   ===================================================================== */
.diffgrid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 44px;
  align-items: center;
  margin-bottom: 44px;
}
.diffgrid .section-head { margin-bottom: 0; }

.diagpanel {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 18px 40px -24px rgba(27, 42, 56, 0.35);
  overflow: hidden;
}
.diagpanel__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: var(--ink);
  color: var(--dark-text);
  padding: 10px 18px;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.diagpanel__head b { color: var(--signal); }
.diagpanel__replay {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dark-text);
  background: transparent;
  border: 1px solid #47617a;
  border-radius: 4px;
  padding: 4px 10px;
  cursor: pointer;
}
.diagpanel__replay:hover { border-color: var(--signal); color: #fff; }
html:not(.mx-motion) .diagpanel__replay { display: none; }
.diagpanel svg { display: block; width: 100%; height: auto; }

/* --- static drawing styles --- */
.diag-grid line { stroke: var(--line); stroke-width: 1; opacity: 0.45; }
.diag-register { stroke: var(--steel); stroke-width: 1; opacity: 0.55; }
.diag-ground { stroke: var(--steel); stroke-width: 1.5; stroke-dasharray: 5 6; opacity: 0.55; }
.diag-bone {
  stroke: var(--ink);
  stroke-width: 5;
  stroke-linecap: round;
  fill: none;
}
.diag-bone--rear { stroke: #8ba0b3; stroke-width: 4.5; }
.diag-outline { fill: none; stroke: var(--ink); stroke-width: 3; }

/* Lifelike bone rendering (FIG-HIP-01 prototype, from Trail Guide reference).
   Warm ivory fill + ink contour + sparse steel cross-contour hatching —
   anatomical bone shapes translated into the panel's blueprint palette. */
.diag-bonefill { fill: #efe7dd; stroke: var(--ink); stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; }
.diag-bonefill--rear { fill: #e4e9ed; stroke: #7f94a6; stroke-width: 1.2; }
.diag-vertebra { fill: #efe7dd; stroke: var(--ink); stroke-width: 1.3; stroke-linejoin: round; }
.diag-hatch { fill: none; stroke: var(--steel); stroke-width: 0.6; opacity: 0.4; stroke-linecap: round; }
.diag-socket { fill: none; stroke: var(--ink); stroke-width: 1.4; opacity: 0.5; stroke-linecap: round; }
.diag-foramen { stroke: var(--ink); stroke-width: 1.1; opacity: 0.85; }
.diag-plate { fill: #e6ecf0; stroke: var(--ink); stroke-width: 2; }
.diag-joint { fill: #fff; stroke: var(--ink); stroke-width: 2.5; }
.diag-joint--rear { stroke: #8ba0b3; stroke-width: 2; }
.diag-pin { fill: var(--ink); }
.diag-pin--hip { fill: var(--signal); }
.diag-label {
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  fill: var(--steel);
}
.diag-leader { stroke: var(--steel); stroke-width: 1; fill: none; }
.diag-title-block rect { fill: #fff; stroke: var(--line); }
.diag-title-block text { font-family: var(--font-mono); fill: var(--steel); letter-spacing: 0.06em; }

/* --- animated parts: geometry + resting pose --- */
.mx-thigh {
  transform-box: view-box;
  transform-origin: 205px 158px;
  transform: rotate(110deg);
}
.mx-shin {
  transform-box: view-box;
  transform-origin: 205px 228px;
  transform: rotate(-70deg);
}
.mx-pulse, .mx-fault, .mx-ping, .mx-symptom { opacity: 0; } /* transient */
.mx-fault {
  stroke: var(--signal);
  stroke-width: 4;
  stroke-linecap: round;
  stroke-dasharray: 1 2; /* gap > pathLength so the round cap never dots the endpoint */
  stroke-dashoffset: 1;
}
.mx-pulse { fill: none; stroke: var(--signal); stroke-width: 2.5; transform-box: fill-box; transform-origin: center; }
.mx-ping { fill: none; stroke: var(--signal); stroke-width: 2.5; transform-box: fill-box; transform-origin: center; }
.mx-arc-locked {
  stroke: var(--steel);
  stroke-width: 2.5;
  stroke-dasharray: 5 5;
  fill: none;
  opacity: 0.45;
}
.mx-label-locked { opacity: 0.5; }
.mx-arc-restored {
  stroke: var(--signal);
  stroke-width: 3.5;
  stroke-linecap: round;
  fill: none;
  stroke-dasharray: 1 2;
  stroke-dashoffset: 0;
}
.mx-arrowhead { fill: var(--signal); }
.mx-label-restored { fill: var(--signal-dark); font-weight: 600; }
.mx-rootcause, .mx-label-restored, .mx-arrowhead, .mx-stamp { opacity: 1; }
.mx-stamp {
  transform-box: fill-box;
  transform-origin: center;
  transform: rotate(-8deg);
  opacity: 0.9;
}
.mx-stamp rect { fill: none; stroke: var(--signal-dark); stroke-width: 2.5; }
.mx-stamp text {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.16em;
  fill: var(--signal-dark);
}

/* --- rewound state (motion on, not yet played) --- */
html.mx-motion .diagpanel:not(.is-played) .mx-thigh { transform: rotate(0deg); }
html.mx-motion .diagpanel:not(.is-played) .mx-shin { transform: rotate(0deg); }
html.mx-motion .diagpanel:not(.is-played) .mx-arc-locked,
html.mx-motion .diagpanel:not(.is-played) .mx-label-locked,
html.mx-motion .diagpanel:not(.is-played) .mx-rootcause,
html.mx-motion .diagpanel:not(.is-played) .mx-label-restored,
html.mx-motion .diagpanel:not(.is-played) .mx-arrowhead,
html.mx-motion .diagpanel:not(.is-played) .mx-stamp { opacity: 0; }
html.mx-motion .diagpanel:not(.is-played) .mx-arc-restored { stroke-dashoffset: 1; }

/* --- timeline --- */
html.mx-motion .diagpanel.is-played .mx-pulse--1 { animation: mxPulse 0.7s ease-out 0.15s both; }
html.mx-motion .diagpanel.is-played .mx-pulse--2 { animation: mxPulse 0.7s ease-out 0.65s both; }
html.mx-motion .diagpanel.is-played .mx-symptom {
  animation: mxFadeIn 0.35s ease 0.25s both, mxFadeOut 0.45s ease 2.9s forwards;
}
html.mx-motion .diagpanel.is-played .mx-fault {
  animation: mxTrace 0.7s ease-in 1.2s both, mxFadeOut 0.4s ease 2.3s forwards;
}
html.mx-motion .diagpanel.is-played .mx-ping { animation: mxPing 0.6s ease-out 1.95s both; }
html.mx-motion .diagpanel.is-played .mx-rootcause { animation: mxFadeIn 0.4s ease 2.05s both; }
html.mx-motion .diagpanel.is-played .mx-arc-locked {
  animation: mxFadeIn 0.35s ease 2.35s both, mxDim 0.5s ease 3.3s forwards;
}
html.mx-motion .diagpanel.is-played .mx-label-locked {
  animation: mxFadeIn 0.35s ease 2.4s both, mxDimHalf 0.5s ease 3.3s forwards;
}
html.mx-motion .diagpanel.is-played .mx-thigh {
  animation: mxThigh 1.15s cubic-bezier(0.55, 0.05, 0.25, 1) 2.9s both;
}
html.mx-motion .diagpanel.is-played .mx-shin {
  animation: mxShin 1.15s cubic-bezier(0.55, 0.05, 0.25, 1) 2.9s both;
}
html.mx-motion .diagpanel.is-played .mx-arc-restored {
  animation: mxTrace 1.15s cubic-bezier(0.55, 0.05, 0.25, 1) 2.9s both;
}
html.mx-motion .diagpanel.is-played .mx-arrowhead { animation: mxFadeIn 0.3s ease 4.0s both; }
html.mx-motion .diagpanel.is-played .mx-label-restored { animation: mxPop 0.4s cubic-bezier(0.2, 1.35, 0.4, 1) 4.1s both; }
html.mx-motion .diagpanel.is-played .mx-stamp { animation: mxStampSvg 0.42s cubic-bezier(0.2, 1.35, 0.4, 1) 4.35s both; }

@keyframes mxFadeIn  { from { opacity: 0; } to { opacity: 1; } }
@keyframes mxFadeOut { to { opacity: 0; } }
@keyframes mxDim     { from { opacity: 1; } to { opacity: 0.45; } }
@keyframes mxDimHalf { from { opacity: 1; } to { opacity: 0.5; } }
@keyframes mxTrace   { from { stroke-dashoffset: 1; opacity: 1; } to { stroke-dashoffset: 0; opacity: 1; } }
@keyframes mxPulse {
  0%   { opacity: 0.9; transform: scale(0.4); }
  100% { opacity: 0;   transform: scale(2.1); }
}
@keyframes mxPing {
  0%   { opacity: 0.9; transform: scale(1); }
  100% { opacity: 0;   transform: scale(2.4); }
}
@keyframes mxThigh { from { transform: rotate(0deg); } to { transform: rotate(110deg); } }
@keyframes mxShin  { from { transform: rotate(0deg); } to { transform: rotate(-70deg); } }
@keyframes mxPop {
  0%   { opacity: 0; transform: translateY(4px); }
  100% { opacity: 1; transform: none; }
}
@keyframes mxStampSvg {
  0%   { opacity: 0;    transform: rotate(-16deg) scale(2.2); }
  65%  { opacity: 0.95; transform: rotate(-7deg)  scale(0.95); }
  100% { opacity: 0.9;  transform: rotate(-8deg)  scale(1); }
}

/* =====================================================================
   PROCESS STEP ICONS — gauge / torque wrench / maintenance check
   (homepage "How it works"). Resting state = final pose.
   ===================================================================== */
.step__icon {
  display: block;
  width: 46px;
  height: 46px;
  margin-bottom: 14px;
  color: var(--ink);
}
.step__icon svg { width: 100%; height: 100%; overflow: visible; }
.icon-stroke { stroke: currentColor; stroke-width: 3; stroke-linecap: round; fill: none; }
.icon-signal { stroke: var(--signal); }

.mx-needle {
  transform-box: view-box;
  transform-origin: 24px 30px;
  transform: rotate(52deg);
}
html.mx-motion .steps:not(.is-played) .mx-needle { transform: rotate(-65deg); }
html.mx-motion .steps.is-played .mx-needle {
  animation: mxNeedle 0.9s cubic-bezier(0.3, 1.4, 0.45, 1) var(--mxd, 0.2s) both;
}
@keyframes mxNeedle {
  from { transform: rotate(-65deg); }
  to   { transform: rotate(52deg); }
}

.mx-wrench { transform-box: view-box; transform-origin: 30px 18px; }
html.mx-motion .steps.is-played .mx-wrench {
  animation: mxWrench 1.1s ease-in-out var(--mxd, 0.2s) both;
}
@keyframes mxWrench {
  0%, 100% { transform: rotate(0deg); }
  28%      { transform: rotate(-32deg); }
  62%      { transform: rotate(14deg); }
  84%      { transform: rotate(-5deg); }
}

.mx-ring, .mx-check { stroke-dasharray: 1 2; stroke-dashoffset: 0; }
html.mx-motion .steps:not(.is-played) .mx-ring,
html.mx-motion .steps:not(.is-played) .mx-check { stroke-dashoffset: 1; }
html.mx-motion .steps:not(.is-played) .mx-ringhead { opacity: 0; }
html.mx-motion .steps.is-played .mx-ring {
  animation: mxTrace 0.8s ease-in-out var(--mxd, 0.2s) both;
}
html.mx-motion .steps.is-played .mx-ringhead {
  animation: mxFadeIn 0.25s ease calc(var(--mxd, 0.2s) + 0.65s) both;
}
html.mx-motion .steps.is-played .mx-check {
  animation: mxTrace 0.45s ease calc(var(--mxd, 0.2s) + 0.75s) both;
}
.mx-ringhead { fill: currentColor; }

/* =====================================================================
   REFERRAL MAP — anatomy-engine diagram (kneaded.html #engine)
   Same architecture as the hip panel: resting state = end of sequence.
   Timeline:
     0.15s  complaint pulses at the temple, COMPLAINT label
     1.10s  engine search traces complaint back to the source
     1.95s  trigger point X pops + ping, SOURCE label
     2.65s  matched referral pattern draws source → temple (search fades)
     3.50s  arrowhead lands, REFERRAL MATCHED stamp
   ===================================================================== */
.knd-pulse, .knd-ping, .knd-search { opacity: 0; } /* transient */
.knd-pulse { fill: none; stroke: var(--signal); stroke-width: 2.5; transform-box: fill-box; transform-origin: center; }
.knd-ping { fill: none; stroke: var(--signal); stroke-width: 2.5; transform-box: fill-box; transform-origin: center; }
.knd-search {
  fill: none;
  stroke: var(--steel);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-dasharray: 1 2;
  stroke-dashoffset: 1;
}
.knd-x { transform-box: fill-box; transform-origin: center; }
.knd-ring { fill: none; stroke: var(--steel); stroke-width: 1.5; stroke-dasharray: 4 4; }
.knd-mark { fill: none; stroke: var(--signal-dark); stroke-width: 3.5; stroke-linecap: round; }
.knd-match {
  fill: none;
  stroke: var(--signal);
  stroke-width: 3.5;
  stroke-linecap: round;
  stroke-dasharray: 1 2;
  stroke-dashoffset: 0;
}
.knd-arrowhead { fill: var(--signal); }
.knd-stamp {
  transform-box: fill-box;
  transform-origin: center;
  transform: rotate(-8deg);
  opacity: 0.9;
}
.knd-stamp rect { fill: none; stroke: var(--signal-dark); stroke-width: 2.5; }
.knd-stamp text {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  fill: var(--signal-dark);
}

html.mx-motion .diagpanel--knd:not(.is-played) .knd-x,
html.mx-motion .diagpanel--knd:not(.is-played) .knd-complaint,
html.mx-motion .diagpanel--knd:not(.is-played) .knd-source,
html.mx-motion .diagpanel--knd:not(.is-played) .knd-arrowhead,
html.mx-motion .diagpanel--knd:not(.is-played) .knd-stamp { opacity: 0; }
html.mx-motion .diagpanel--knd:not(.is-played) .knd-match { stroke-dashoffset: 1; }

html.mx-motion .diagpanel--knd.is-played .knd-pulse--1 { animation: mxPulse 0.7s ease-out 0.15s both; }
html.mx-motion .diagpanel--knd.is-played .knd-pulse--2 { animation: mxPulse 0.7s ease-out 0.65s both; }
html.mx-motion .diagpanel--knd.is-played .knd-complaint { animation: mxFadeIn 0.35s ease 0.25s both; }
html.mx-motion .diagpanel--knd.is-played .knd-search {
  animation: mxTrace 0.8s ease-in 1.1s both, mxFadeOut 0.45s ease 2.7s forwards;
}
html.mx-motion .diagpanel--knd.is-played .knd-x { animation: mxXIn 0.4s cubic-bezier(0.2, 1.35, 0.4, 1) 1.95s both; }
html.mx-motion .diagpanel--knd.is-played .knd-ping { animation: mxPing 0.6s ease-out 2.0s both; }
html.mx-motion .diagpanel--knd.is-played .knd-source { animation: mxFadeIn 0.4s ease 2.2s both; }
html.mx-motion .diagpanel--knd.is-played .knd-match { animation: mxTrace 0.9s cubic-bezier(0.55, 0.05, 0.25, 1) 2.65s both; }
html.mx-motion .diagpanel--knd.is-played .knd-arrowhead { animation: mxFadeIn 0.3s ease 3.5s both; }
html.mx-motion .diagpanel--knd.is-played .knd-stamp { animation: mxStampSvg 0.42s cubic-bezier(0.2, 1.35, 0.4, 1) 3.8s both; }

@keyframes mxXIn {
  0%   { opacity: 0; transform: scale(1.9); }
  100% { opacity: 1; transform: scale(1); }
}

/* ---------- Responsive ---------- */
@media (max-width: 900px) {
  .diffgrid { grid-template-columns: 1fr; gap: 36px; }
}

/* ---------- Safety net: mid-session reduced-motion toggle ---------- */
@media (prefers-reduced-motion: reduce) {
  html.mx-motion * {
    animation-duration: 0.01ms !important;
    animation-delay: 0s !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
  }
}
