/* ========================================================== tab icons
   Each icon performs what its screen does, on a loop, at an amplitude you can
   actually read at 24px. The first pass moved things 1.6px and scaled them
   1.03x — technically animated, visually nothing. These are deliberate.

     Isolations      the line energises, surges, and is CUT — the bolt fills,
                     double-flashes, a cut stroke sweeps across, the bolt dies
     Board           the register is counted: each sheet lifts, hangs, drops
     Network control a packet leaves the hub, runs the wire, and lands on an
                     outstation, which rings out
     Reports         bars build from nothing, overshoot, settle, collapse
     Tag sheet       a tag swings on its ring and comes to rest
     Fleet           the grid is counted off, cell by cell
     Users           one figure steps up, then the one behind
     Order tags      the trolley rolls and its wheels turn
     More            three dots, a wave passing through them

   Still transform/opacity/dash only, so it stays on the compositor: a tab bar
   that animates all night must not cost the battery an AP needs.
   -------------------------------------------------------------------- */

/* Not scoped to the tab rail: the same icons appear in the More menu, and
   without transform-box the tag's swing was measured against the viewBox
   instead of its own shape — it rotated clean out of frame, leaving only the
   round dot that is meant to be the hole in the tag. */
.ic * {
  transform-box: fill-box;
  transform-origin: center;
}
.ic { overflow: visible; }

/* ============================================ Isolations: energise, then cut */
.ic-bolt .bolt-glow {
  fill: currentColor; stroke: none; opacity: 0;
  animation: bolt-charge 2.8s cubic-bezier(.3, 0, .2, 1) infinite;
}
.ic-bolt .bolt {
  animation: bolt-body 2.8s cubic-bezier(.3, 0, .2, 1) infinite;
}
/* the cut: a stroke that sweeps across the bolt and takes the power out */
.ic-bolt .cut {
  stroke-width: 2.2;
  stroke-dasharray: 24;
  stroke-dashoffset: 24;
  opacity: 0;
  animation: bolt-cut 2.8s cubic-bezier(.4, 0, .2, 1) infinite;
}

@keyframes bolt-charge {
  0%, 10%  { opacity: 0;   transform: scale(.82); }
  30%      { opacity: .35; transform: scale(1.02); }   /* charging */
  38%      { opacity: 1;   transform: scale(1.24); }   /* surge */
  44%      { opacity: .2;  transform: scale(1.02); }
  50%      { opacity: .95; transform: scale(1.16); }   /* second arc */
  58%      { opacity: 0;   transform: scale(.92); }    /* cut */
  100%     { opacity: 0;   transform: scale(.82); }
}
@keyframes bolt-body {
  0%, 10%  { opacity: .45; transform: scale(.94); }
  30%      { opacity: .9;  transform: scale(1.04); }
  38%      { opacity: 1;   transform: scale(1.22); }
  44%      { opacity: .5;  transform: scale(1.02); }
  50%      { opacity: 1;   transform: scale(1.14); }
  58%      { opacity: .3;  transform: scale(.9); }     /* de-energised */
  72%      { opacity: .3;  transform: scale(.9); }     /* held isolated */
  100%     { opacity: .45; transform: scale(.94); }
}
@keyframes bolt-cut {
  0%, 48%  { opacity: 0; stroke-dashoffset: 24; }
  52%      { opacity: 1; }
  62%      { opacity: 1; stroke-dashoffset: 0; }       /* sweeps across */
  76%      { opacity: .9; stroke-dashoffset: 0; }
  88%      { opacity: 0;  stroke-dashoffset: 0; }
  100%     { opacity: 0;  stroke-dashoffset: 24; }
}

/* ================================================ Board: counting the register */
.ic-layers .layer { animation: layer-count 2.8s cubic-bezier(.34, 1.4, .5, 1) infinite; }
.ic-layers .l1 { animation-delay: 0s; }
.ic-layers .l2 { animation-delay: .14s; }
.ic-layers .l3 { animation-delay: .28s; }

@keyframes layer-count {
  0%, 6%    { transform: translateY(0) scaleX(1); opacity: .55; }
  18%       { transform: translateY(-4.5px) scaleX(1.08); opacity: 1; }
  30%       { transform: translateY(-4.5px) scaleX(1.08); opacity: 1; }
  44%       { transform: translateY(0) scaleX(1); opacity: 1; }
  70%, 100% { transform: translateY(0) scaleX(1); opacity: .55; }
}

/* ======================== Network control: a packet runs out to each station */
.ic-nodes .wire {
  stroke-dasharray: 3 3;
  opacity: .45;
  animation: wire-live 2.8s linear infinite;
}
.ic-nodes .w2 { animation-delay: .5s; }

/* the packet itself, travelling the exact geometry of each wire */
.ic-nodes .packet {
  fill: currentColor; stroke: none; opacity: 0;
  offset-rotate: 0deg;
}
.ic-nodes .p1 {
  offset-path: path("M 8.4 10.7 L 15.6 6.8");
  animation: packet-run 2.8s cubic-bezier(.45, 0, .3, 1) infinite;
}
.ic-nodes .p2 {
  offset-path: path("M 8.4 13.3 L 15.6 17.2");
  animation: packet-run 2.8s cubic-bezier(.45, 0, .3, 1) .5s infinite;
}
.ic-nodes .node { animation: node-idle 2.8s ease-out infinite; }
.ic-nodes .n0 { animation: hub-send 2.8s cubic-bezier(.3, 1.6, .5, 1) infinite; }
.ic-nodes .n1 { animation-delay: .34s; }
.ic-nodes .n2 { animation-delay: .84s; }

/* a ring that expands out of a station as the packet lands */
.ic-nodes .ring {
  fill: none; stroke: currentColor; stroke-width: 1.5; opacity: 0;
  animation: ring-out 2.8s cubic-bezier(.2, .8, .3, 1) infinite;
}
.ic-nodes .r1 { animation-delay: .34s; }
.ic-nodes .r2 { animation-delay: .84s; }

@keyframes wire-live {
  0%   { stroke-dashoffset: 12; opacity: .3; }
  20%  { opacity: 1; }
  60%  { opacity: .3; }
  100% { stroke-dashoffset: 0; opacity: .3; }
}
@keyframes packet-run {
  0%        { offset-distance: 0%;   opacity: 0; transform: scale(.4); }
  6%        { opacity: 1;            transform: scale(1); }
  26%       { offset-distance: 100%; opacity: 1; transform: scale(1); }
  32%       { offset-distance: 100%; opacity: 0; transform: scale(1.8); }
  100%      { offset-distance: 100%; opacity: 0; transform: scale(.4); }
}
@keyframes hub-send {
  0%, 4%    { transform: scale(1);    opacity: .7; }
  10%       { transform: scale(1.45); opacity: 1; }
  22%       { transform: scale(1);    opacity: .85; }
  54%       { transform: scale(1.45); opacity: 1; }
  68%, 100% { transform: scale(1);    opacity: .7; }
}
@keyframes node-idle {
  0%, 8%    { transform: scale(1);    opacity: .55; }
  16%       { transform: scale(1.5);  opacity: 1; }
  34%, 100% { transform: scale(1);    opacity: .55; }
}
@keyframes ring-out {
  0%, 10%   { transform: scale(1);   opacity: 0; }
  16%       { transform: scale(1.1); opacity: .9; }
  38%       { transform: scale(2.6); opacity: 0; }
  100%      { transform: scale(2.6); opacity: 0; }
}

/* ===================================================== Reports: figures build */
.ic-bars .bar {
  transform-origin: bottom;
  animation: bar-build 2.8s cubic-bezier(.3, 1.5, .4, 1) infinite;
}
.ic-bars .b1 { animation-delay: 0s; }
.ic-bars .b2 { animation-delay: .14s; }
.ic-bars .b3 { animation-delay: .28s; }

@keyframes bar-build {
  0%, 5%    { transform: scaleY(.06); opacity: .4; }
  24%       { transform: scaleY(1.15); opacity: 1; }   /* overshoot */
  32%       { transform: scaleY(1); opacity: 1; }
  66%       { transform: scaleY(1); opacity: 1; }
  82%, 100% { transform: scaleY(.06); opacity: .4; }   /* collapse */
}

/* ====================================================== Tag sheet: it swings */
.ic-tag .tag-swing {
  transform-origin: 78% 22%;
  animation: tag-swing 3s cubic-bezier(.36, 0, .4, 1) infinite;
}
@keyframes tag-swing {
  0%, 8%   { transform: rotate(0deg); }
  20%      { transform: rotate(-17deg); }
  36%      { transform: rotate(12deg); }
  50%      { transform: rotate(-7deg); }
  62%      { transform: rotate(3deg); }
  74%, 100%{ transform: rotate(0deg); }
}

/* ======================================================== Fleet: counted off */
.ic-grid .cell { animation: cell-count 2.8s cubic-bezier(.3, 1.5, .4, 1) infinite; }
.ic-grid .c1 { animation-delay: 0s; }
.ic-grid .c2 { animation-delay: .12s; }
.ic-grid .c4 { animation-delay: .24s; }
.ic-grid .c3 { animation-delay: .36s; }

@keyframes cell-count {
  0%, 5%    { opacity: .35; transform: scale(.72); }
  18%       { opacity: 1;   transform: scale(1.12); }
  30%       { opacity: 1;   transform: scale(1); }
  60%, 100% { opacity: .35; transform: scale(.72); }
}

/* ================================================ Users: one, then the other */
.ic-users .who { animation: who-step 2.8s cubic-bezier(.34, 1.4, .5, 1) infinite; }
.ic-users .w-front { animation-delay: 0s; }
.ic-users .w-back { animation-delay: .3s; }

@keyframes who-step {
  0%, 6%    { transform: translateY(0) scale(1); opacity: .5; }
  20%       { transform: translateY(-3px) scale(1.12); opacity: 1; }
  38%       { transform: translateY(0) scale(1); opacity: 1; }
  68%, 100% { transform: translateY(0) scale(1); opacity: .5; }
}

/* ===================================================== Order tags: it rolls */
.ic-cart .cart { animation: cart-roll 2.8s cubic-bezier(.4, 0, .3, 1) infinite; }
.ic-cart .wheel {
  transform-origin: center;
  animation: wheel-turn 2.8s cubic-bezier(.4, 0, .3, 1) infinite;
}
@keyframes cart-roll {
  0%, 8%    { transform: translateX(-3.5px); }
  42%       { transform: translateX(3.5px); }
  76%, 100% { transform: translateX(-3.5px); }
}
@keyframes wheel-turn {
  0%, 8%    { transform: rotate(0deg); }
  42%       { transform: rotate(300deg); }
  76%, 100% { transform: rotate(0deg); }
}

/* ============================================================ More: a wave */
.ic-dots .dot { animation: dot-wave 2.2s cubic-bezier(.34, 1.5, .5, 1) infinite; }
.ic-dots .d1 { animation-delay: 0s; }
.ic-dots .d2 { animation-delay: .1s; }
.ic-dots .d3 { animation-delay: .2s; }

@keyframes dot-wave {
  0%, 14%   { transform: translateY(0) scale(1); opacity: .5; }
  28%       { transform: translateY(-4px) scale(1.5); opacity: 1; }
  46%       { transform: translateY(0) scale(1); opacity: .7; }
  70%, 100% { transform: translateY(0) scale(1); opacity: .5; }
}

/* The tab you are on performs a little faster, so motion marks where you are
   rather than competing with it. */
.tabs button.on .ic * { animation-duration: 2.2s; }
.tabs button.on .ic .packet,
.tabs button.on .ic .ring { animation-duration: 2.2s; }

@media (prefers-reduced-motion: reduce) {
  .tabs button .ic *,
  .tabs button.on .ic * { animation: none !important; transform: none; opacity: 1; }
  .ic-bolt .bolt-glow, .ic-bolt .cut, .ic-nodes .packet, .ic-nodes .ring { opacity: 0; }
  .ic-nodes .wire { stroke-dasharray: none; opacity: 1; }
}

/* The overflow menu is a list, not the tab rail. An icon caught mid-swing in
   a dropdown reads as a tilted blob rather than a tag, and motion in a menu
   you are trying to read from is noise. They sit still here. */
.tab-more .ic,
.tab-more .ic * {
  animation: none !important;
  transform: none !important;
}
.tab-more .ic .bolt-glow,
.tab-more .ic .cut,
.tab-more .ic .packet,
.tab-more .ic .ring { opacity: 0; }
.tab-more .ic .wire { stroke-dasharray: none; opacity: 1; }
.tab-more .ic .layer,
.tab-more .ic .bar,
.tab-more .ic .cell,
.tab-more .ic .who,
.tab-more .ic .dot,
.tab-more .ic .node { opacity: 1; }
