/* ============================================================================
   AS-BUILT — DETAIL FIGURES, motion (pairs with figs-detail.js)
   ----------------------------------------------------------------------------
   How it works. Each moving part carries one fd-* class. The rules OUTSIDE the
   media query only CONFIGURE it — which keyframes (--an), how long (--t), what
   easing (--ez) — and set transform-box/origin. None of them starts anything.

   Exactly ONE rule, inside prefers-reduced-motion:no-preference, turns motion
   on, and only when the <svg class="fig"> has .play, sits in a hovered
   .dframe, or is in the enlarged .dv-fig. Everywhere else — thumbnails at
   rest, print, reduced motion — the figure shows its resting state, which is
   drawn as the final state. Per-element stagger comes from an inline --d.

   Anything that exists only in motion (scan bars, packets, pulses, reticles)
   has opacity="0" as an SVG attribute, so it is hidden even if this file
   never loads. Loops are 5–12 s, eased, no flashing.
   ========================================================================== */

/* ---- transform boxes ---- */
.fd .fd-fb{transform-box:fill-box;transform-origin:center}
.fd .fd-wa-bar,.fd .fd-rp-bar,.fd .fd-pr-flame{transform-box:fill-box;transform-origin:50% 100%}
.fd .fd-pr-bar{transform-box:fill-box;transform-origin:0 50%}
.fd .fd-so-hole{transform-box:fill-box;transform-origin:50% 0}
/* these rotate/scale about a hinge given inline in viewBox units */
.fd .fd-cs-ga,.fd .fd-cs-gb,.fd .fd-bmp-hand,.fd .fd-cf-orn,.fd .fd-cf-vec{transform-box:view-box}
/* the bloom grows out of the basin's south-west corner (its own box, so a parent translate is safe) */
.fd .fd-hb-bloom{transform-box:fill-box;transform-origin:3% 88%}

/* ---- configuration (inert on its own) ---- */
/* shared */
.fd .fd-pop{--an:fd-pop;--t:10s;--ez:ease-out}
.fd .fd-mvA{--an:fd-mvA;--t:10s;--ez:ease-in-out}
.fd .fd-mv2{--an:fd-mv2;--t:3.2s;--ez:linear}
.fd .fd-drop{--an:fd-drop;--t:10s;--ez:ease-in}
.fd .fd-flow{--an:fd-dash;--t:1.2s;--ez:linear}
/* 01 loop */
.fd .fd-lp-tok{--an:fd-lp-tok;--t:12s;--ez:linear}
.fd .fd-lp-mk{--an:fd-lp-mk;--t:12s;--ez:ease-in-out}
/* 02 asbestos */
.fd .fd-ab-scan{--an:fd-ab-scan;--t:10s;--ez:linear}
.fd .fd-ab-leg{--an:fd-ab-leg;--t:10s;--ez:ease-out}
/* 03 ccvi */
.fd .fd-cc-grid{--an:fd-cc-grid;--t:12s;--ez:linear}
.fd .fd-cc-ck{--an:fd-cc-ck;--t:12s;--ez:ease-out}
/* 04 canso */
.fd .fd-cs-ship{--an:fd-cs-ship;--t:12s;--ez:ease-in-out}
.fd .fd-cs-ga{--an:fd-cs-ga;--t:12s;--ez:ease-in-out}
.fd .fd-cs-gb{--an:fd-cs-gb;--t:12s;--ez:ease-in-out}
/* 05 criva */
.fd .fd-cr-sweep{--an:fd-cr-sweep;--t:10s;--ez:ease-in-out}
.fd .fd-cr-calm{--an:fd-cr-calm;--t:10s;--ez:ease-in-out}
.fd .fd-cr-risk{--an:fd-cr-risk;--t:10s;--ez:ease-out}
/* 06 micap */
.fd .fd-mc-ret{--an:fd-mc-ret;--t:9s;--ez:ease-in-out}
/* 07 waste */
.fd .fd-wa-bar{--an:fd-wa-bar;--t:10s;--ez:ease-out}
.fd .fd-wa-val{--an:fd-wa-val;--t:10s;--ez:ease-out}
/* 08 bmp */
.fd .fd-bmp-hand{--an:fd-bmp-hand;--t:12s;--ez:linear}
.fd .fd-bmp-node{--an:fd-bmp-node;--t:12s;--ez:ease-out}
/* 09 cmms */
.fd-cmms .fd-mvA{--t:8s}
.fd .fd-cm-h{--an:fd-cm-h;--t:8s;--ez:ease-in-out}
/* 10 dfrp */
.fd .fd-df-own{--an:fd-df-own;--t:10s;--ez:ease-in-out}
.fd .fd-df-doc{--an:fd-df-doc;--t:10s;--ez:ease-out}
/* 11 screen */
.fd .fd-sc-pulse{--an:fd-sc-pulse;--t:5s;--ez:ease-out}
.fd-screen .fd-pop{--t:5s}
/* 13 ai */
.fd .fd-ai-q{--an:fd-ai-q;--t:10s;--ez:ease-in-out}
.fd .fd-ai-ok{--an:fd-ai-ok;--t:10s;--ez:ease-out}
/* 14 smap */
.fd .fd-sm-sat{--an:fd-sm-sat;--t:10s;--ez:linear}
/* 15 hab */
.fd .fd-hb-bloom{--an:fd-hb-bloom;--t:11s;--ez:ease-in-out}
.fd .fd-hb-mk{--an:fd-hb-mk;--t:11s;--ez:ease-in-out}
/* 16 agri */
.fd .fd-ag-v{--an:fd-ag-v;--t:12s;--ez:ease-out}
.fd .fd-ag-trace{--an:fd-ag-trace;--t:12s;--ez:linear}
.fd .fd-ag-fill{--an:fd-ag-fill;--t:12s;--ez:ease-out}
.fd .fd-ag-c{--an:fd-ag-c;--t:12s;--ez:ease-out}
/* 17 soil */
.fd .fd-so-aug{--an:fd-so-aug;--t:12s;--ez:ease-in-out}
.fd .fd-so-hole{--an:fd-so-hole;--t:12s;--ez:ease-in-out}
.fd .fd-so-core{--an:fd-so-core;--t:12s;--ez:ease-out}
/* 18 conflation */
.fd .fd-cf-orn{--an:fd-cf-orn;--t:10s;--ez:ease-in-out}
.fd .fd-cf-vec{--an:fd-cf-vec;--t:10s;--ez:ease-in-out}
.fd .fd-cf-bnd{--an:fd-cf-bnd;--t:10s;--ez:ease-in-out}
.fd .fd-cf-flag{--an:fd-cf-flag;--t:10s;--ez:ease-out}
/* 19 prescott */
.fd-prescott .fd-drop{--t:5s}
.fd .fd-pr-flame{--an:fd-pr-flame;--t:1.8s;--ez:ease-in-out}
.fd .fd-pr-smoke{--an:fd-pr-smoke;--t:4s;--ez:linear}
.fd .fd-pr-bar{--an:fd-pr-bar;--t:10s;--ez:ease-out}
/* 20 rpdata */
.fd-rpdata .fd-mvA{--t:9s}
.fd .fd-rp-bar{--an:fd-rp-bar;--t:9s;--ez:ease-out}
.fd .fd-rp-tag{--an:fd-rp-tag;--t:9s;--ez:ease-out}

/* ---- the one switch ---- */
@media (prefers-reduced-motion:no-preference){
  :is(.fig.play,.dframe:hover .fig,.dv-fig .fig) [class*="fd-"]{
    animation:var(--an) var(--t,10s) var(--ez,ease-in-out) var(--d,0s) infinite backwards}

  /* shared */
  @keyframes fd-pop{0%{opacity:0;transform:scale(.3)}4%{opacity:1;transform:scale(1.25)}8%{transform:scale(1)}82%{opacity:1;transform:scale(1)}92%,100%{opacity:0;transform:scale(1)}}
  @keyframes fd-mvA{0%{opacity:0;transform:translate(0,0)}4%{opacity:1}26%{opacity:1;transform:translate(var(--dx),var(--dy))}30%,100%{opacity:0;transform:translate(var(--dx),var(--dy))}}
  @keyframes fd-mv2{0%{opacity:0;transform:translate(0,0)}8%{opacity:1}48%{transform:translate(var(--mx),var(--my))}84%{opacity:1;transform:translate(var(--dx),var(--dy))}92%,100%{opacity:0;transform:translate(var(--dx),var(--dy))}}
  @keyframes fd-drop{0%{opacity:0;transform:translateY(0)}4%{opacity:1}18%{opacity:1;transform:translateY(var(--dy))}22%,100%{opacity:0;transform:translateY(var(--dy))}}
  @keyframes fd-dash{to{stroke-dashoffset:-16}}

  /* 01 loop — token round the loop; the condition marker decays, then jumps back at reassessment */
  @keyframes fd-lp-tok{0%{transform:translate(0,0)}6%{transform:translate(0,-46px)}8.6%{transform:translate(14px,-60px)}45.6%{transform:translate(298px,-60px)}48.2%{transform:translate(312px,-46px)}56%{transform:translate(312px,14px)}58.6%{transform:translate(298px,28px)}95.6%{transform:translate(14px,28px)}98.2%{transform:translate(0,14px)}100%{transform:translate(0,0)}}
  @keyframes fd-lp-mk{0%{transform:translateX(0)}84%,88%{transform:translateX(-156px)}96%,100%{transform:translateX(0)}}

  /* 02 asbestos — the scan bar crosses the section; each keynote pops as it is reached */
  @keyframes fd-ab-scan{0%{opacity:0;transform:translateX(0)}5%{opacity:1}60%{opacity:1;transform:translateX(180px)}66%,100%{opacity:0;transform:translateX(180px)}}
  @keyframes fd-ab-leg{0%{opacity:.3}4%,82%{opacity:1}92%,100%{opacity:.3}}

  /* 03 ccvi — the national grid fills one row at a time, then the go-live check draws */
  @keyframes fd-cc-grid{0%,12%{clip-path:inset(0 0 100% 0);opacity:1;animation-timing-function:steps(20,end)}56%,90%{clip-path:inset(0 0 0 0);opacity:1}100%{clip-path:inset(0 0 0 0);opacity:0}}
  @keyframes fd-cc-ck{0%,58%{stroke-dashoffset:1}66%,100%{stroke-dashoffset:0}}

  /* 04 canso — upstream gate open, ship in, gates swap, ship out */
  @keyframes fd-cs-ship{0%{opacity:0;transform:translateX(-120px)}8%{opacity:1}30%,58%{transform:translateX(0)}88%{opacity:1;transform:translateX(130px)}94%,100%{opacity:0;transform:translateX(130px)}}
  @keyframes fd-cs-ga{0%,26%{transform:rotate(var(--r))}33%,92%{transform:rotate(0deg)}100%{transform:rotate(var(--r))}}
  @keyframes fd-cs-gb{0%,54%{transform:rotate(0deg)}61%,86%{transform:rotate(var(--r))}93%,100%{transform:rotate(0deg)}}

  /* 05 criva — evidence in, a sweep across the portfolio, the at-risk sites surface */
  @keyframes fd-cr-sweep{0%{opacity:0;transform:translateX(0)}8%{opacity:1}42%{opacity:1;transform:translateX(204px)}46%,100%{opacity:0;transform:translateX(204px)}}
  @keyframes fd-cr-calm{0%,40%{opacity:1}52%,92%{opacity:.3}100%{opacity:1}}
  @keyframes fd-cr-risk{0%,44%{opacity:0;transform:scale(.4)}50%{opacity:1;transform:scale(1.2)}54%{transform:scale(1)}92%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(1)}}

  /* 06 micap — the inspection reticle walks deck › pile › fender */
  @keyframes fd-mc-ret{0%{opacity:0;transform:translate(0,0)}5%{opacity:1}28%{transform:translate(0,0)}36%,60%{transform:translate(10px,63px)}68%,90%{opacity:1;transform:translate(130px,19px)}96%,100%{opacity:0;transform:translate(130px,19px)}}

  /* 07 waste — items drop into the bins, the two diversion bars rise past 75% */
  @keyframes fd-wa-bar{0%,24%{transform:scaleY(0)}44%{transform:scaleY(1)}92%{opacity:1;transform:scaleY(1)}100%{opacity:0;transform:scaleY(1)}}
  @keyframes fd-wa-val{0%,42%{opacity:0}48%,92%{opacity:1}100%{opacity:0}}

  /* 08 bmp — the year hand sweeps the five phases; each lights as it is reached */
  @keyframes fd-bmp-hand{from{transform:rotate(72deg)}to{transform:rotate(432deg)}}
  @keyframes fd-bmp-node{0%{opacity:0;transform:scale(.4)}3%{opacity:1;transform:scale(1.4)}6%{transform:scale(1)}18%{opacity:1}22%,100%{opacity:0;transform:scale(1)}}

  /* 09 cmms — packets into SAP, then the hierarchy lights top to bottom */
  @keyframes fd-cm-h{0%,20%{fill:var(--ink-2)}26%{fill:var(--red)}40%,100%{fill:var(--ink-2)}}

  /* 10 dfrp — each document lands and the polygon moves a third of the way to the truth */
  @keyframes fd-df-own{0%,8%{d:path("M40 58L180 46L198 150L58 162Z")}16%,24%{d:path("M46 63.3L175.3 52.7L192.7 146.7L64 158Z")}33%,41%{d:path("M52 68.7L170.7 59.3L187.3 143.3L70 154Z")}50%,92%{d:path("M58 74L166 66L182 140L76 150Z")}100%{d:path("M40 58L180 46L198 150L58 162Z")}}
  @keyframes fd-df-doc{0%{opacity:0;transform:translateX(24px)}6%{opacity:1;transform:translateX(0)}60%{opacity:1}68%,100%{opacity:0;transform:translateX(0)}}

  /* 11 screen — the buffer pulse; hits pop when it reaches them */
  @keyframes fd-sc-pulse{0%{opacity:0;transform:scale(.05)}6%{opacity:.9}50%{opacity:.9;transform:scale(1)}64%,100%{opacity:0;transform:scale(1.06)}}

  /* 13 ai — in through the door, into the model, out to a bin; some turn answerable */
  @keyframes fd-ai-q{0%{opacity:0;transform:translate(var(--sx),var(--sy))}6%{opacity:1}28%,40%{transform:translate(var(--mx),var(--my))}56%{transform:translate(0,0)}88%{opacity:1;transform:translate(0,0)}96%,100%{opacity:0;transform:translate(0,0)}}
  @keyframes fd-ai-ok{0%,52%{opacity:0}58%,88%{opacity:1}96%,100%{opacity:0}}

  /* 14 smap — the pass; samples ring as the footprint crosses them */
  @keyframes fd-sm-sat{0%{opacity:0;transform:translateX(-150px)}6%{opacity:1}90%{opacity:1;transform:translateX(150px)}96%,100%{opacity:0;transform:translateX(150px)}}

  /* 15 hab — Sep 14 › Oct 12: the bloom spreads across the basin */
  @keyframes fd-hb-bloom{0%{opacity:.2;transform:scale(.12)}70%,90%{opacity:1;transform:scale(1)}98%{opacity:0;transform:scale(1)}100%{opacity:0;transform:scale(.12)}}
  @keyframes fd-hb-mk{0%{transform:translateX(-222px)}70%,90%{transform:translateX(0)}98%,100%{transform:translateX(-222px)}}

  /* 16 agri — seven clicks trace it; then one click selects, one confirms */
  @keyframes fd-ag-v{0%{opacity:0;transform:scale(.3)}3%{opacity:1;transform:scale(1.3)}6%{transform:scale(1)}38%{opacity:1}46%,92%{opacity:.4;transform:scale(1)}100%{opacity:0;transform:scale(1)}}
  @keyframes fd-ag-trace{0%{opacity:1;stroke-dashoffset:1}28%{stroke-dashoffset:0}40%{opacity:1;stroke-dashoffset:0}48%,100%{opacity:0;stroke-dashoffset:0}}
  @keyframes fd-ag-fill{0%,68%{opacity:0}74%,94%{opacity:1}100%{opacity:0}}
  @keyframes fd-ag-c{0%,66%{opacity:0;transform:scale(.3)}69%{opacity:1;transform:scale(1.3)}72%{transform:scale(1)}94%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(1)}}

  /* 17 soil — drill down, lift, lay the core out */
  @keyframes fd-so-aug{0%{transform:translateY(-124px)}42%,54%{transform:translateY(0)}70%,100%{transform:translateY(-124px)}}
  @keyframes fd-so-hole{0%{opacity:1;transform:scaleY(0)}42%{transform:scaleY(1)}86%{opacity:1;transform:scaleY(1)}96%{opacity:0;transform:scaleY(1)}100%{opacity:0;transform:scaleY(0)}}
  @keyframes fd-so-core{0%,62%{opacity:0;transform:translateX(-10px)}68%,90%{opacity:1;transform:translateX(0)}97%,100%{opacity:0;transform:translateX(0)}}

  /* 18 conflation — the provincial network snaps on; the boundary draws; the stale segment flags */
  @keyframes fd-cf-orn{0%,8%{transform:translate(10px,7px) rotate(-2.5deg)}36%,90%{transform:translate(0,0) rotate(0deg)}100%{transform:translate(10px,7px) rotate(-2.5deg)}}
  @keyframes fd-cf-vec{0%,8%{opacity:1;transform:scale(1)}34%{opacity:1;transform:scale(0)}38%,90%{opacity:0;transform:scale(0)}96%{opacity:0;transform:scale(1)}100%{opacity:1;transform:scale(1)}}
  @keyframes fd-cf-bnd{0%,40%{stroke-dashoffset:1}62%,94%{stroke-dashoffset:0}100%{stroke-dashoffset:1}}
  @keyframes fd-cf-flag{0%,62%{opacity:0}68%,92%{opacity:1}100%{opacity:0}}

  /* 19 prescott — waste in, a low flame, and the two waste streams against what the unit needs */
  @keyframes fd-pr-flame{0%,100%{transform:scaleY(1)}50%{transform:scaleY(.86)}}
  @keyframes fd-pr-smoke{0%{opacity:0;transform:translateY(8px)}30%{opacity:.4}100%{opacity:0;transform:translateY(-12px)}}
  @keyframes fd-pr-bar{0%,16%{transform:scaleX(0)}44%{transform:scaleX(1)}92%{opacity:1;transform:scaleX(1)}100%{opacity:0;transform:scaleX(1)}}

  /* 20 rpdata — three systems feed the app, the report refreshes, the asks go out */
  @keyframes fd-rp-bar{0%,26%{transform:scaleY(.15)}40%,92%{transform:scaleY(1)}100%{transform:scaleY(.15)}}
  @keyframes fd-rp-tag{0%,44%{opacity:0;transform:translateX(-8px)}50%,90%{opacity:1;transform:translateX(0)}97%,100%{opacity:0;transform:translateX(0)}}
}
