/* ============================================================
   Animated article illustrations
   ------------------------------------------------------------
   Pure CSS and SVG. No video, no library, no extra request: the
   whole point of the site is that pages are light, and a 2 MB
   explainer video would contradict that.

   Every animation respects prefers-reduced-motion: the diagram
   still communicates when motion is off, it just stops moving.
   ============================================================ */
.fig{margin:34px 0; padding:26px; background:var(--card); border:1px solid var(--rule);
  border-radius:var(--radius-lg);}
.fig figcaption{font-size:13px; color:var(--ink-faint); margin-top:16px; line-height:1.5;}
.fig svg{width:100%; height:auto; display:block;}

/* --- 1. One entry filling many boxes --- */
.fig-fill .src{fill:var(--accent-tint); stroke:var(--accent); stroke-width:1.5;}
.fig-fill .box{fill:var(--paper-2); stroke:var(--rule-strong); stroke-width:1.2;}
.fig-fill .ink{fill:var(--accent); opacity:0;}
.fig-fill .flow{stroke:var(--accent); stroke-width:1.6; fill:none; stroke-dasharray:4 4; opacity:.45;
  stroke-dashoffset:0; animation:flowdash 1.4s linear infinite;}
@keyframes flowdash{to{stroke-dashoffset:-16;}}
.fig-fill .ink{animation:inkin 4s ease-in-out infinite;}
.fig-fill .ink.d1{animation-delay:.35s;} .fig-fill .ink.d2{animation-delay:.7s;}
.fig-fill .ink.d3{animation-delay:1.05s;} .fig-fill .ink.d4{animation-delay:1.4s;}
@keyframes inkin{0%,8%{opacity:0;transform:translateY(3px);}22%,72%{opacity:1;transform:none;}92%,100%{opacity:0;}}

/* --- 2. Statement rows reconciling --- */
.fig-recon .row{opacity:.25; animation:rowcheck 5s ease-in-out infinite;}
.fig-recon .row.r1{animation-delay:.2s;} .fig-recon .row.r2{animation-delay:.7s;}
.fig-recon .row.r3{animation-delay:1.2s;} .fig-recon .row.r4{animation-delay:1.7s;}
.fig-recon .row.bad{animation-name:rowbad; animation-delay:2.2s;}
@keyframes rowcheck{0%,4%{opacity:.25;}14%,80%{opacity:1;}94%,100%{opacity:.25;}}
@keyframes rowbad{0%,4%{opacity:.25;}14%,80%{opacity:1;}94%,100%{opacity:.25;}}
.fig-recon .tick{stroke:#1D6A4F; stroke-width:2; fill:none; stroke-linecap:round;
  stroke-dasharray:14; stroke-dashoffset:14; animation:draw 5s ease-in-out infinite;}
.fig-recon .tick.r1{animation-delay:.4s;} .fig-recon .tick.r2{animation-delay:.9s;}
.fig-recon .tick.r3{animation-delay:1.4s;} .fig-recon .tick.r4{animation-delay:1.9s;}
@keyframes draw{0%,6%{stroke-dashoffset:14;}18%,80%{stroke-dashoffset:0;}94%,100%{stroke-dashoffset:14;}}
.fig-recon .flag{fill:#A03328; opacity:0; animation:flagin 5s ease-in-out infinite; animation-delay:2.4s;}
@keyframes flagin{0%,6%{opacity:0;}18%,80%{opacity:1;}94%,100%{opacity:0;}}

/* --- 3. Nothing leaves the device --- */
.fig-local .device{fill:var(--card); stroke:var(--accent); stroke-width:2;}
.fig-local .cloud{fill:none; stroke:var(--rule-strong); stroke-width:1.6; stroke-dasharray:5 4;}
.fig-local .doc{fill:var(--accent-tint); stroke:var(--accent); stroke-width:1.3;
  animation:bob 3.4s ease-in-out infinite;}
@keyframes bob{0%,100%{transform:translateY(0);}50%{transform:translateY(-4px);}}
.fig-local .blocked{stroke:#A03328; stroke-width:2.4; stroke-linecap:round;
  stroke-dasharray:40; stroke-dashoffset:40; animation:draw2 3.4s ease-in-out infinite;}
@keyframes draw2{0%,20%{stroke-dashoffset:40;}45%,85%{stroke-dashoffset:0;}100%{stroke-dashoffset:40;}}

/* --- 4. Batch: one row becomes one document --- */
.fig-batch .rowline{fill:var(--paper-2); stroke:var(--rule-strong); stroke-width:1;}
.fig-batch .outdoc{fill:var(--card); stroke:var(--accent); stroke-width:1.4; opacity:0;
  animation:popin 4.2s ease-in-out infinite;}
.fig-batch .outdoc.o1{animation-delay:.3s;} .fig-batch .outdoc.o2{animation-delay:.75s;}
.fig-batch .outdoc.o3{animation-delay:1.2s;}
@keyframes popin{0%,6%{opacity:0;transform:translateX(-8px) scale(.96);}
  22%,78%{opacity:1;transform:none;}92%,100%{opacity:0;}}

@media (prefers-reduced-motion: reduce){
  .fig * { animation: none !important; }
  .fig-fill .ink, .fig-batch .outdoc, .fig-recon .flag { opacity:1 !important; transform:none !important; }
  .fig-recon .row { opacity:1 !important; }
  .fig-recon .tick, .fig-local .blocked { stroke-dashoffset:0 !important; }
}

/* --- 5. One job feeding several permits --- */
.fig-stack .job{fill:var(--accent-tint); stroke:var(--accent); stroke-width:1.5;}
.fig-stack .feed{stroke:var(--accent); stroke-width:1.5; fill:none; stroke-dasharray:4 4;
  opacity:.45; animation:flowdash 1.6s linear infinite;}
.fig-stack .permit rect{fill:var(--card); stroke:var(--rule-strong); stroke-width:1.2;}
.fig-stack .permit{opacity:0; animation:popin 4.6s ease-in-out infinite;}
.fig-stack .permit.p1{animation-delay:.3s;} .fig-stack .permit.p2{animation-delay:.7s;}
.fig-stack .permit.p3{animation-delay:1.1s;} .fig-stack .permit.p4{animation-delay:1.5s;}
@media (prefers-reduced-motion: reduce){ .fig-stack .permit{opacity:1 !important; transform:none !important;} }

/* --- 6. One set splitting into named sheets --- */
.fig-sheets .set{fill:var(--accent-tint); stroke:var(--accent); stroke-width:1.5;}
.fig-sheets .feed{stroke:var(--accent); stroke-width:1.4; fill:none; stroke-dasharray:4 4;
  opacity:.45; animation:flowdash 1.6s linear infinite;}
.fig-sheets .sh rect{fill:var(--card); stroke:var(--rule-strong); stroke-width:1.2;}
.fig-sheets .sh{opacity:0; animation:popin 5s ease-in-out infinite;}
.fig-sheets .s1{animation-delay:.2s;} .fig-sheets .s2{animation-delay:.55s;}
.fig-sheets .s3{animation-delay:.9s;} .fig-sheets .s4{animation-delay:1.25s;}
.fig-sheets .s5{animation-delay:1.6s;}
@media (prefers-reduced-motion: reduce){ .fig-sheets .sh{opacity:1 !important; transform:none !important;} }

/* --- 7. One calibration feeding every measurement --- */
.fig-scale .dim{stroke:var(--accent); stroke-width:2;}
.fig-scale .tick{stroke:var(--accent); stroke-width:2;}
.fig-scale .feed{stroke:var(--accent); stroke-width:1.4; fill:none; stroke-dasharray:4 4;
  opacity:.5; animation:flowdash 1.6s linear infinite;}
.fig-scale .scalebox{fill:var(--accent-tint); stroke:var(--accent); stroke-width:1.5;}
.fig-scale .res rect{fill:var(--card); stroke:var(--rule-strong); stroke-width:1.2;}
.fig-scale .res{opacity:0; animation:popin 4.4s ease-in-out infinite;}
.fig-scale .r1{animation-delay:.3s;} .fig-scale .r2{animation-delay:.7s;} .fig-scale .r3{animation-delay:1.1s;}
@media (prefers-reduced-motion: reduce){ .fig-scale .res{opacity:1 !important; transform:none !important;} }
