@conduction/docusaurus-preset 3.33.0 → 3.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/ANIMATION_ROADMAP.md +129 -0
  2. package/MISSING_COMPONENTS.md +15 -5
  3. package/package.json +3 -2
  4. package/src/components/AgentTrace/AgentTrace.jsx +26 -5
  5. package/src/components/AgentTrace/AgentTrace.module.css +41 -2
  6. package/src/components/AgentTrace/__tests__/AgentTrace.render.test.js +108 -0
  7. package/src/components/AppMock/AppMock.jsx +14 -5
  8. package/src/components/AppMock/AppMock.module.css +1702 -0
  9. package/src/components/AppMock/__tests__/AppMock.render.test.js +329 -0
  10. package/src/components/AppMock/variants/DeciDeskMock.jsx +46 -5
  11. package/src/components/AppMock/variants/DocuDeskMock.jsx +39 -9
  12. package/src/components/AppMock/variants/DoriathMock.jsx +28 -13
  13. package/src/components/AppMock/variants/HermiqMock.jsx +35 -15
  14. package/src/components/AppMock/variants/HrmqMock.jsx +46 -28
  15. package/src/components/AppMock/variants/LarpingAppMock.jsx +36 -7
  16. package/src/components/AppMock/variants/LaunchPadBiMock.jsx +12 -5
  17. package/src/components/AppMock/variants/LaunchPadTilesMock.jsx +6 -1
  18. package/src/components/AppMock/variants/LaunchPadWidgetsMock.jsx +17 -8
  19. package/src/components/AppMock/variants/NLDesignMock.jsx +15 -4
  20. package/src/components/AppMock/variants/OpenBuildMock.jsx +20 -5
  21. package/src/components/AppMock/variants/OpenCatalogiMock.jsx +23 -4
  22. package/src/components/AppMock/variants/OpenConnectorMock.jsx +25 -3
  23. package/src/components/AppMock/variants/OpenRegisterMock.jsx +13 -2
  24. package/src/components/AppMock/variants/PipelinQMock.jsx +12 -2
  25. package/src/components/AppMock/variants/PortaliqMock.jsx +21 -9
  26. package/src/components/AppMock/variants/ProcestMock.jsx +34 -7
  27. package/src/components/AppMock/variants/ScholiqMock.jsx +12 -6
  28. package/src/components/AppMock/variants/ShillinqMock.jsx +33 -17
  29. package/src/components/AppMock/variants/SoftwareCatalogMock.jsx +15 -5
  30. package/src/components/AppMock/variants/ZaakAfhandelAppMock.jsx +19 -4
  31. package/src/components/FlowMock/FlowMock.jsx +5 -3
  32. package/src/components/FlowMock/FlowMock.module.css +36 -9
  33. package/src/components/FlowMock/__tests__/FlowMock.render.test.js +83 -0
  34. package/src/components/LeafMock/LeafMock.jsx +23 -8
  35. package/src/components/LeafMock/LeafMock.module.css +123 -0
  36. package/src/components/LeafMock/__tests__/LeafMock.render.test.js +105 -0
  37. package/src/components/MockScene/MockScene.jsx +16 -2
  38. package/src/components/MockScene/MockScene.module.css +22 -2
  39. package/src/components/MockScene/__tests__/MockScene.render.test.js +101 -0
  40. package/src/components/SidebarMock/SidebarMock.jsx +29 -2
  41. package/src/components/SidebarMock/__tests__/SidebarMock.render.test.js +115 -0
  42. package/src/components/WidgetMock/WidgetMock.jsx +35 -14
  43. package/src/components/WidgetMock/__tests__/WidgetMock.render.test.js +125 -0
  44. package/src/components/WidgetMock/variants/DocuDeskAnonymise.jsx +6 -1
@@ -30,6 +30,10 @@
30
30
  .am .figure { margin: 0; display: inline-flex; flex-direction: column; gap: var(--space-2); width: 100%; max-width: 100%; }
31
31
 
32
32
  .am .frame {
33
+ /* Shared animation timeline token. Every variant keyframe below runs
34
+ on var(--am-dur); a variant overrides it on its own body class
35
+ (e.g. `.nldesign { --am-dur: 6s; }`). The KanbanMock convention. */
36
+ --am-dur: 8s;
33
37
  width: 100%;
34
38
  max-width: 720px;
35
39
  aspect-ratio: 16 / 10;
@@ -700,3 +704,1701 @@
700
704
  .am .procest .timeline .step.todo .h { background: var(--c-cobalt-100); }
701
705
  .am .procest .timeline .step.now .h { background: var(--c-orange-knvb); }
702
706
  .am .procest .timeline .step .label { height: 3px; width: 60%; background: var(--c-cobalt-400); border-radius: 1px; }
707
+
708
+ /* ======================================================================
709
+ Variant animations
710
+ ======================================================================
711
+
712
+ Every timeline runs on var(--am-dur) (declared on `.am .frame`,
713
+ overridden per variant body class). Conventions, copied from
714
+ KanbanMock.module.css:
715
+
716
+ - Base styles are the animation's meaningful END state, so freezing
717
+ (running={false} → `.static` on the frame, or the user's
718
+ prefers-reduced-motion) is `animation: none` plus a couple of
719
+ explicit overrides.
720
+ - Loops reset via opacity swaps (fade out at ~92–98%, re-enter from
721
+ the 0% frame), never a visible rewind. 0% and 100% frames are both
722
+ hidden or identical, so per-element `animation-delay` staggers stay
723
+ seamless in steady state.
724
+ - `animation-fill-mode: both` keeps delayed elements on their hidden
725
+ 0% frame during the initial delay.
726
+ - Tokens only; no new orange is introduced by any animation. */
727
+
728
+ /* ---- Portaliq — a visitor fills the form, submits, the message
729
+ lands in the inbox. Timeline (8s): focus+fill field 1 (3–19%),
730
+ field 2 (21–37%), field 3 (39–55%), submit press (58–63%), mint
731
+ confirm sweep across the form (63–72%), inbox row arrives (74–80%),
732
+ hold, fade-reset (94–100%). ---- */
733
+
734
+ .am .portaliq .field {
735
+ position: relative;
736
+ height: 14px;
737
+ background: white;
738
+ border: 1px solid var(--c-cobalt-200);
739
+ border-radius: 3px;
740
+ overflow: hidden;
741
+ }
742
+ .am .portaliq .field.tall { height: 26px; }
743
+ .am .portaliq .fieldFill {
744
+ position: absolute;
745
+ left: 3px;
746
+ top: 4px;
747
+ height: 4px;
748
+ border-radius: 1px;
749
+ background: var(--c-cobalt-300);
750
+ transform-origin: left center;
751
+ }
752
+ .am .portaliq .field-1 .fieldFill { width: 62%; animation: amPqFill1 var(--am-dur) linear infinite both; }
753
+ .am .portaliq .field-2 .fieldFill { width: 48%; animation: amPqFill2 var(--am-dur) linear infinite both; }
754
+ .am .portaliq .field-3 .fieldFill { width: 78%; animation: amPqFill3 var(--am-dur) linear infinite both; }
755
+ .am .portaliq .field-1 { animation: amPqFocus1 var(--am-dur) linear infinite; }
756
+ .am .portaliq .field-2 { animation: amPqFocus2 var(--am-dur) linear infinite; }
757
+ .am .portaliq .field-3 { animation: amPqFocus3 var(--am-dur) linear infinite; }
758
+
759
+ @keyframes amPqFocus1 {
760
+ 0%, 3% { border-color: var(--c-cobalt-200); box-shadow: 0 0 0 0 rgba(31, 68, 156, 0); }
761
+ 6%, 17% { border-color: var(--c-blue-cobalt); box-shadow: 0 0 0 2px var(--c-cobalt-100); }
762
+ 20%, 100% { border-color: var(--c-cobalt-200); box-shadow: 0 0 0 0 rgba(31, 68, 156, 0); }
763
+ }
764
+ @keyframes amPqFocus2 {
765
+ 0%, 21% { border-color: var(--c-cobalt-200); box-shadow: 0 0 0 0 rgba(31, 68, 156, 0); }
766
+ 24%, 35% { border-color: var(--c-blue-cobalt); box-shadow: 0 0 0 2px var(--c-cobalt-100); }
767
+ 38%, 100% { border-color: var(--c-cobalt-200); box-shadow: 0 0 0 0 rgba(31, 68, 156, 0); }
768
+ }
769
+ @keyframes amPqFocus3 {
770
+ 0%, 39% { border-color: var(--c-cobalt-200); box-shadow: 0 0 0 0 rgba(31, 68, 156, 0); }
771
+ 42%, 53% { border-color: var(--c-blue-cobalt); box-shadow: 0 0 0 2px var(--c-cobalt-100); }
772
+ 56%, 100% { border-color: var(--c-cobalt-200); box-shadow: 0 0 0 0 rgba(31, 68, 156, 0); }
773
+ }
774
+ @keyframes amPqFill1 {
775
+ 0%, 8% { transform: scaleX(0); opacity: 1; }
776
+ 19%, 93% { transform: scaleX(1); opacity: 1; }
777
+ 98% { transform: scaleX(1); opacity: 0; }
778
+ 100% { transform: scaleX(0); opacity: 0; }
779
+ }
780
+ @keyframes amPqFill2 {
781
+ 0%, 26% { transform: scaleX(0); opacity: 1; }
782
+ 37%, 93% { transform: scaleX(1); opacity: 1; }
783
+ 98% { transform: scaleX(1); opacity: 0; }
784
+ 100% { transform: scaleX(0); opacity: 0; }
785
+ }
786
+ @keyframes amPqFill3 {
787
+ 0%, 44% { transform: scaleX(0); opacity: 1; }
788
+ 55%, 93% { transform: scaleX(1); opacity: 1; }
789
+ 98% { transform: scaleX(1); opacity: 0; }
790
+ 100% { transform: scaleX(0); opacity: 0; }
791
+ }
792
+
793
+ .am .portaliq .submit { animation: amPqPress var(--am-dur) ease-in-out infinite; }
794
+ @keyframes amPqPress {
795
+ 0%, 58% { transform: scale(1); }
796
+ 60% { transform: scale(0.92); }
797
+ 63%, 100% { transform: scale(1); }
798
+ }
799
+
800
+ /* Mint confirmation sweep — a soft light band crossing the form panel
801
+ right after the submit press. Hidden at rest and in static frames. */
802
+ .am .portaliq .formPanel { position: relative; overflow: hidden; }
803
+ .am .portaliq .confirmSweep {
804
+ position: absolute;
805
+ inset: 0;
806
+ background: linear-gradient(100deg, transparent 32%, var(--c-mint-300) 50%, transparent 68%);
807
+ opacity: 0;
808
+ transform: translateX(-120%);
809
+ pointer-events: none;
810
+ animation: amPqSweep var(--am-dur) linear infinite;
811
+ }
812
+ @keyframes amPqSweep {
813
+ 0%, 63% { transform: translateX(-120%); opacity: 0; }
814
+ 64% { opacity: 0.9; }
815
+ 71% { opacity: 0.9; }
816
+ 72%, 100% { transform: translateX(120%); opacity: 0; }
817
+ }
818
+
819
+ /* The arriving inbox row (its default mint avatar reads as the
820
+ delivered/confirmed state). Visible in static frames. */
821
+ .am .portaliq .newItem { animation: amPqRow var(--am-dur) ease-out infinite both; }
822
+ @keyframes amPqRow {
823
+ 0%, 74% { opacity: 0; transform: translateY(-5px); }
824
+ 80%, 93% { opacity: 1; transform: none; }
825
+ 98%, 100% { opacity: 0; transform: none; }
826
+ }
827
+
828
+ /* ---- NLDesign — a theme swatch is selected, the components retheme
829
+ in a cascade (button, then status pill), and the type scale
830
+ restretches. Timeline (6s): ring on the lavender swatch (5–10%),
831
+ button recolours (12–20%), pill recolours (14–22%), type bars
832
+ restretch (30–50%), hold, revert crossfade (84–100%). ---- */
833
+
834
+ .am .nldesign { --am-dur: 6s; }
835
+
836
+ .am .nldesign .swatch { display: inline-block; width: 22px; height: 22px; border-radius: 4px; }
837
+ .am .nldesign .swatchSel { animation: amNldSel var(--am-dur) ease-in-out infinite; }
838
+ @keyframes amNldSel {
839
+ 0%, 5% { box-shadow: 0 0 0 0 white, 0 0 0 0 rgba(31, 68, 156, 0); }
840
+ 10%, 86% { box-shadow: 0 0 0 2px white, 0 0 0 4px var(--c-blue-cobalt); }
841
+ 94%, 100% { box-shadow: 0 0 0 0 white, 0 0 0 0 rgba(31, 68, 156, 0); }
842
+ }
843
+
844
+ .am .nldesign .actions .btn:not(.ghost) { animation: amNldBtn var(--am-dur) ease-in-out infinite; }
845
+ @keyframes amNldBtn {
846
+ 0%, 12% { background-color: var(--c-blue-cobalt); }
847
+ 20%, 84% { background-color: var(--c-lavender-500); }
848
+ 92%, 100% { background-color: var(--c-blue-cobalt); }
849
+ }
850
+
851
+ .am .nldesign .statusPill:not(.beta) { animation: amNldPillBg var(--am-dur) ease-in-out infinite; }
852
+ .am .nldesign .statusPill:not(.beta) .h,
853
+ .am .nldesign .statusPill:not(.beta) .t { animation: amNldPillInk var(--am-dur) ease-in-out infinite; }
854
+ @keyframes amNldPillBg {
855
+ 0%, 14% { background-color: var(--c-mint-300); }
856
+ 22%, 84% { background-color: var(--c-lavender-300); }
857
+ 92%, 100% { background-color: var(--c-mint-300); }
858
+ }
859
+ @keyframes amNldPillInk {
860
+ 0%, 14% { background-color: var(--c-mint-500); }
861
+ 22%, 84% { background-color: var(--c-lavender-500); }
862
+ 92%, 100% { background-color: var(--c-mint-500); }
863
+ }
864
+
865
+ .am .nldesign .typeRow > * {
866
+ transform-origin: left center;
867
+ animation: amNldType var(--am-dur) ease-in-out infinite;
868
+ }
869
+ .am .nldesign .typeRow > *:nth-child(2) { animation-delay: 0.05s; }
870
+ .am .nldesign .typeRow > *:nth-child(3) { animation-delay: 0.1s; }
871
+ .am .nldesign .typeRow > *:nth-child(4) { animation-delay: 0.15s; }
872
+ .am .nldesign .typeRow > *:nth-child(5) { animation-delay: 0.2s; }
873
+ @keyframes amNldType {
874
+ 0%, 30% { transform: scaleX(1); }
875
+ 42% { transform: scaleX(1.32); }
876
+ 50%, 84% { transform: scaleX(1.18); }
877
+ 94%, 100% { transform: scaleX(1); }
878
+ }
879
+
880
+ /* ---- Scholiq — course progress bars fill in a stagger, then the
881
+ completed course's credential chip pops with an overshoot.
882
+ Timeline (6s): bars fill (3–25% + per-bar delay), chip pop
883
+ (44–57%), hold, fade-reset (91–100%). Per-bar delays are inline
884
+ (i × 250ms) so the keyframes stay shared. ---- */
885
+
886
+ .am .scholiq { --am-dur: 6s; }
887
+
888
+ .am .scholiq .progress { height: 4px; background: var(--c-cobalt-100); border-radius: 2px; }
889
+ .am .scholiq .progressFill {
890
+ height: 4px;
891
+ background: var(--c-forest-500);
892
+ border-radius: 2px;
893
+ transform-origin: left center;
894
+ animation: amSchFill var(--am-dur) cubic-bezier(0.2, 0.7, 0.3, 1) infinite both;
895
+ }
896
+ @keyframes amSchFill {
897
+ 0%, 3% { transform: scaleX(0); opacity: 1; }
898
+ 25%, 91% { transform: scaleX(1); opacity: 1; }
899
+ 97% { transform: scaleX(1); opacity: 0; }
900
+ 100% { transform: scaleX(0); opacity: 0; }
901
+ }
902
+
903
+ .am .scholiq .credChip {
904
+ display: inline-flex;
905
+ align-items: center;
906
+ gap: 3px;
907
+ padding: 2px 6px;
908
+ border-radius: 999px;
909
+ background: var(--c-forest-300);
910
+ align-self: flex-start;
911
+ transform-origin: left center;
912
+ animation: amSchChip var(--am-dur) ease-in-out infinite both;
913
+ }
914
+ .am .scholiq .credChip .credHex { width: 6px; height: 7px; clip-path: var(--hex-pointy-top); background: var(--c-forest-500); }
915
+ .am .scholiq .credChip .credBar { height: 3px; width: 22px; background: var(--c-forest-500); border-radius: 1px; }
916
+ @keyframes amSchChip {
917
+ 0%, 44% { transform: scale(0); opacity: 0; }
918
+ 52% { transform: scale(1.18); opacity: 1; }
919
+ 57%, 91% { transform: scale(1); opacity: 1; }
920
+ 97%, 100% { transform: scale(1); opacity: 0; }
921
+ }
922
+
923
+ /* ---- LaunchPad · Widgets — the dashboard assembles: widgets arrive
924
+ one by one on a 900ms stagger (inline delays), hold, fade-reset.
925
+ Timeline (10s). ---- */
926
+
927
+ .am .lpWidgets { --am-dur: 10s; }
928
+ .am .lpWidgets .w { animation: amLpwArrive var(--am-dur) ease-out infinite both; }
929
+ @keyframes amLpwArrive {
930
+ 0% { opacity: 0; transform: translateY(10px) scale(0.98); }
931
+ 4% { opacity: 1; transform: none; }
932
+ 93% { opacity: 1; transform: none; }
933
+ 98%, 100% { opacity: 0; transform: none; }
934
+ }
935
+
936
+ /* ---- LaunchPad · Tiles — the sub-grid tile is pressed and unfolds
937
+ its four sub-tiles in a stagger. Timeline (7s): press (5–11%),
938
+ cells unfold (10–20% + nth-child delay), hold, fade-reset. ---- */
939
+
940
+ .am .lpTiles { --am-dur: 7s; }
941
+ .am .lpTiles .w-subgrid { transform-origin: center; animation: amLptPress var(--am-dur) ease-in-out infinite; }
942
+ @keyframes amLptPress {
943
+ 0%, 5% { transform: scale(1); }
944
+ 8% { transform: scale(0.96); }
945
+ 11%, 100% { transform: scale(1); }
946
+ }
947
+ .am .lpTiles .w-subgrid .cell { animation: amLptCell var(--am-dur) cubic-bezier(0.2, 0.7, 0.3, 1) infinite both; }
948
+ .am .lpTiles .w-subgrid .cell:nth-child(2) { animation-delay: 0.12s; }
949
+ .am .lpTiles .w-subgrid .cell:nth-child(3) { animation-delay: 0.24s; }
950
+ .am .lpTiles .w-subgrid .cell:nth-child(4) { animation-delay: 0.36s; }
951
+ @keyframes amLptCell {
952
+ 0%, 10% { opacity: 0; transform: scale(0.4); }
953
+ 16% { opacity: 1; transform: scale(1.08); }
954
+ 20%, 92% { opacity: 1; transform: scale(1); }
955
+ 97%, 100% { opacity: 0; transform: scale(1); }
956
+ }
957
+
958
+ /* ---- LaunchPad · BI — the charts draw themselves: bars grow from
959
+ the axis in a stagger, the line draws along its path and its end
960
+ dot pops, the donut sweeps in, the KPI deltas fade up. Timeline
961
+ (9s): bars (2–16% + nth-child delay), donut (8–26%), line draw
962
+ (10–38%), dot pop (38–49%), deltas (46–54% + inline delay), hold,
963
+ fade-reset (92–100%). The line's stroke path carries
964
+ pathLength="1" so the dash arithmetic is geometry-independent
965
+ (the FlowMock run-line technique). ---- */
966
+
967
+ .am .lpBi { --am-dur: 9s; }
968
+
969
+ .am .lpBi .w-graph-bar .bar {
970
+ transform-origin: bottom;
971
+ animation: amBiBar var(--am-dur) cubic-bezier(0.2, 0.7, 0.3, 1) infinite both;
972
+ }
973
+ .am .lpBi .w-graph-bar .bar:nth-child(2) { animation-delay: 0.12s; }
974
+ .am .lpBi .w-graph-bar .bar:nth-child(3) { animation-delay: 0.24s; }
975
+ .am .lpBi .w-graph-bar .bar:nth-child(4) { animation-delay: 0.36s; }
976
+ .am .lpBi .w-graph-bar .bar:nth-child(5) { animation-delay: 0.48s; }
977
+ .am .lpBi .w-graph-bar .bar:nth-child(6) { animation-delay: 0.6s; }
978
+ @keyframes amBiBar {
979
+ 0%, 2% { transform: scaleY(0); opacity: 1; }
980
+ 16%, 92% { transform: scaleY(1); opacity: 1; }
981
+ 97% { transform: scaleY(1); opacity: 0; }
982
+ 100% { transform: scaleY(0); opacity: 0; }
983
+ }
984
+
985
+ .am .lpBi .w-graph-line .stroke {
986
+ stroke-dasharray: 1;
987
+ animation: amBiLine var(--am-dur) ease-in-out infinite both;
988
+ }
989
+ @keyframes amBiLine {
990
+ 0%, 10% { stroke-dashoffset: 1; opacity: 1; }
991
+ 38%, 92% { stroke-dashoffset: 0; opacity: 1; }
992
+ 97% { stroke-dashoffset: 0; opacity: 0; }
993
+ 100% { stroke-dashoffset: 1; opacity: 0; }
994
+ }
995
+ .am .lpBi .w-graph-line .fill { animation: amBiFill var(--am-dur) linear infinite both; }
996
+ @keyframes amBiFill {
997
+ 0%, 30% { opacity: 0; }
998
+ 44%, 92% { opacity: 1; }
999
+ 98%, 100% { opacity: 0; }
1000
+ }
1001
+ .am .lpBi .w-graph-line .dot {
1002
+ transform-box: fill-box;
1003
+ transform-origin: center;
1004
+ animation: amBiDot var(--am-dur) ease-out infinite both;
1005
+ }
1006
+ @keyframes amBiDot {
1007
+ 0%, 38% { opacity: 0; transform: scale(0); }
1008
+ 44% { opacity: 1; transform: scale(1.7); }
1009
+ 49%, 92% { opacity: 1; transform: scale(1); }
1010
+ 98%, 100% { opacity: 0; transform: scale(1); }
1011
+ }
1012
+
1013
+ .am .lpBi .donut { animation: amBiDonut var(--am-dur) ease-out infinite both; }
1014
+ @keyframes amBiDonut {
1015
+ 0%, 8% { opacity: 0; transform: rotate(-80deg) scale(0.85); }
1016
+ 26%, 92% { opacity: 1; transform: none; }
1017
+ 98%, 100% { opacity: 0; transform: none; }
1018
+ }
1019
+
1020
+ .am .lpBi .biDelta { animation: amBiDelta var(--am-dur) ease-out infinite both; }
1021
+ @keyframes amBiDelta {
1022
+ 0%, 46% { opacity: 0; transform: translateY(4px); }
1023
+ 54%, 92% { opacity: 1; transform: none; }
1024
+ 98%, 100% { opacity: 0; transform: none; }
1025
+ }
1026
+
1027
+ /* ---- PipelinQ — a deal closes: the proposal-column card collapses,
1028
+ the won card scales in with its mint bar, and the pipeline-value
1029
+ KPI widens. Timeline (7s): collapse (14–22%), won pop (17–29%),
1030
+ KPI widen (26–34%), hold, opacity-swap reset (91–100%). Static
1031
+ frames show the closed state (won card in place, proposal card
1032
+ gone). ---- */
1033
+
1034
+ .am .plq { --am-dur: 7s; }
1035
+
1036
+ .am .plq .dealGone { transform-origin: center; animation: amPlqGone var(--am-dur) ease-in-out infinite; }
1037
+ @keyframes amPlqGone {
1038
+ 0%, 14% { opacity: 1; transform: scaleY(1); }
1039
+ 22%, 91% { opacity: 0; transform: scaleY(0); }
1040
+ 97%, 100% { opacity: 1; transform: scaleY(1); }
1041
+ }
1042
+
1043
+ .am .plq .dealWon {
1044
+ border-left-color: var(--c-mint-500);
1045
+ transform-origin: center;
1046
+ animation: amPlqWon var(--am-dur) ease-out infinite both;
1047
+ }
1048
+ @keyframes amPlqWon {
1049
+ 0%, 17% { opacity: 0; transform: scale(0.5); }
1050
+ 25% { opacity: 1; transform: scale(1.1); }
1051
+ 29%, 91% { opacity: 1; transform: scale(1); }
1052
+ 97%, 100% { opacity: 0; transform: scale(1); }
1053
+ }
1054
+
1055
+ .am .plq .kpiRow .kpi:first-child .num {
1056
+ transform-origin: left center;
1057
+ animation: amPlqKpi var(--am-dur) ease-in-out infinite;
1058
+ }
1059
+ @keyframes amPlqKpi {
1060
+ 0%, 26% { transform: scaleX(1); }
1061
+ 34%, 90% { transform: scaleX(1.3); }
1062
+ 97%, 100% { transform: scaleX(1); }
1063
+ }
1064
+
1065
+ /* ======================================================================
1066
+ Wave 2 — storytelling variant animations
1067
+ ====================================================================== */
1068
+
1069
+ /* ---- DocuDesk — the anonymiser blacks out the marked (PII) words
1070
+ one by one across the open document list. Base = redacted end
1071
+ state (cobalt-900 blocks); the amDdMark keyframes replay the
1072
+ text-look before-state and the black-out, one word per slot.
1073
+ The drop-zone shares the `.zoneLive` treatment below. ---- */
1074
+
1075
+ .am .docudesk { --am-dur: 9s; }
1076
+ /* The drop-zone widget absorbs the column's remaining height so the
1077
+ frame has no dead white band under the two widgets. */
1078
+ .am .docudesk .w-upload { flex: 1; }
1079
+ .am .docudesk .words {
1080
+ flex: 1;
1081
+ display: flex;
1082
+ align-items: center;
1083
+ gap: 3px;
1084
+ min-width: 0;
1085
+ }
1086
+ .am .docudesk .word {
1087
+ height: 3px;
1088
+ background: var(--c-cobalt-300);
1089
+ border-radius: 1px;
1090
+ flex-shrink: 0;
1091
+ }
1092
+ .am .docudesk .word.mark { height: 5px; background: var(--c-cobalt-900); }
1093
+ .am .docudesk .word.mark-1 { animation: amDdMark1 var(--am-dur) linear infinite both; }
1094
+ .am .docudesk .word.mark-2 { animation: amDdMark2 var(--am-dur) linear infinite both; }
1095
+ .am .docudesk .word.mark-3 { animation: amDdMark3 var(--am-dur) linear infinite both; }
1096
+ .am .docudesk .word.mark-4 { animation: amDdMark4 var(--am-dur) linear infinite both; }
1097
+ .am .docudesk .word.mark-5 { animation: amDdMark5 var(--am-dur) linear infinite both; }
1098
+
1099
+ @keyframes amDdMark1 {
1100
+ 0%, 12% { background: var(--c-cobalt-300); transform: scaleY(0.6); }
1101
+ 15%, 93% { background: var(--c-cobalt-900); transform: scaleY(1); }
1102
+ 98%, 100% { background: var(--c-cobalt-300); transform: scaleY(0.6); }
1103
+ }
1104
+ @keyframes amDdMark2 {
1105
+ 0%, 24% { background: var(--c-cobalt-300); transform: scaleY(0.6); }
1106
+ 27%, 93% { background: var(--c-cobalt-900); transform: scaleY(1); }
1107
+ 98%, 100% { background: var(--c-cobalt-300); transform: scaleY(0.6); }
1108
+ }
1109
+ @keyframes amDdMark3 {
1110
+ 0%, 36% { background: var(--c-cobalt-300); transform: scaleY(0.6); }
1111
+ 39%, 93% { background: var(--c-cobalt-900); transform: scaleY(1); }
1112
+ 98%, 100% { background: var(--c-cobalt-300); transform: scaleY(0.6); }
1113
+ }
1114
+ @keyframes amDdMark4 {
1115
+ 0%, 48% { background: var(--c-cobalt-300); transform: scaleY(0.6); }
1116
+ 51%, 93% { background: var(--c-cobalt-900); transform: scaleY(1); }
1117
+ 98%, 100% { background: var(--c-cobalt-300); transform: scaleY(0.6); }
1118
+ }
1119
+ @keyframes amDdMark5 {
1120
+ 0%, 60% { background: var(--c-cobalt-300); transform: scaleY(0.6); }
1121
+ 63%, 93% { background: var(--c-cobalt-900); transform: scaleY(1); }
1122
+ 98%, 100% { background: var(--c-cobalt-300); transform: scaleY(0.6); }
1123
+ }
1124
+
1125
+ /* ---- Shillinq — a bank statement line slides down onto invoice
1126
+ row 3, both tick mint, the totals line and the first KPI grow.
1127
+ Base = reconciled end state (row-3 tick mint, bank line gone). ---- */
1128
+
1129
+ .am .shillinq { --am-dur: 8s; }
1130
+ .am .shillinq .kpi .ico.terra { background: var(--c-terracotta-500); }
1131
+ .am .shillinq .kpi .ico.terraSoft { background: var(--c-terracotta-300); }
1132
+ .am .shillinq .ledger { flex: 1; position: relative; }
1133
+ .am .shillinq .inv .doc {
1134
+ width: 11px; height: 13px;
1135
+ clip-path: var(--hex-pointy-top);
1136
+ background: var(--c-terracotta-300);
1137
+ flex-shrink: 0;
1138
+ }
1139
+ .am .shillinq .inv .net { height: 4px; background: var(--c-cobalt-700); border-radius: 1px; flex-shrink: 0; }
1140
+ .am .shillinq .inv .vat { height: 4px; background: var(--c-cobalt-300); border-radius: 1px; flex-shrink: 0; }
1141
+ .am .shillinq .inv .tick {
1142
+ width: 9px; height: 10px;
1143
+ clip-path: var(--hex-pointy-top);
1144
+ background: var(--c-mint-500);
1145
+ flex-shrink: 0;
1146
+ }
1147
+ .am .shillinq .inv .tick.open { background: var(--c-cobalt-200); }
1148
+ .am .shillinq .totals {
1149
+ display: flex;
1150
+ justify-content: flex-end;
1151
+ gap: 6px;
1152
+ padding-top: 4px;
1153
+ border-top: 1px solid var(--c-cobalt-100);
1154
+ }
1155
+ .am .shillinq .totNet { width: 32px; height: 6px; background: var(--c-cobalt-900); border-radius: 1px; transform-origin: right center; }
1156
+ .am .shillinq .totVat { width: 20px; height: 6px; background: var(--c-cobalt-400); border-radius: 1px; }
1157
+
1158
+ /* The travelling bank line. Hidden at rest and in static frames. */
1159
+ .am .shillinq .bankLine {
1160
+ position: absolute;
1161
+ top: 24px;
1162
+ right: 12px;
1163
+ width: 45%;
1164
+ display: flex;
1165
+ align-items: center;
1166
+ gap: 4px;
1167
+ padding: 3px 4px;
1168
+ background: var(--c-cobalt-50);
1169
+ border: 1px solid var(--c-cobalt-200);
1170
+ border-radius: 2px;
1171
+ opacity: 0;
1172
+ pointer-events: none;
1173
+ animation: amShqBank var(--am-dur) ease-in-out infinite both;
1174
+ }
1175
+ .am .shillinq .bankLine .bIco { width: 8px; height: 9px; clip-path: var(--hex-pointy-top); background: var(--c-forest-500); flex-shrink: 0; }
1176
+ .am .shillinq .bankLine .bBar { flex: 1; height: 3px; background: var(--c-cobalt-400); border-radius: 1px; }
1177
+ .am .shillinq .bankLine .bAmt { width: 18px; height: 4px; background: var(--c-cobalt-700); border-radius: 1px; flex-shrink: 0; }
1178
+
1179
+ @keyframes amShqBank {
1180
+ 0%, 6% { opacity: 0; transform: translateY(-8px); }
1181
+ 12%, 22% { opacity: 1; transform: translateY(0); }
1182
+ 36% { opacity: 1; transform: translateY(52px); }
1183
+ 42%, 100% { opacity: 0; transform: translateY(52px); }
1184
+ }
1185
+
1186
+ .am .shillinq .inv.reconciling .tick { animation: amShqTick var(--am-dur) linear infinite both; }
1187
+ @keyframes amShqTick {
1188
+ 0%, 38% { background: var(--c-cobalt-200); transform: scale(1); }
1189
+ 42% { background: var(--c-mint-500); transform: scale(1.35); }
1190
+ 46%, 93% { background: var(--c-mint-500); transform: scale(1); }
1191
+ 98%, 100% { background: var(--c-cobalt-200); transform: scale(1); }
1192
+ }
1193
+
1194
+ .am .shillinq .totNet { animation: amShqTotal var(--am-dur) ease-in-out infinite; }
1195
+ @keyframes amShqTotal {
1196
+ 0%, 44% { transform: scaleX(1); }
1197
+ 52%, 90% { transform: scaleX(1.18); }
1198
+ 97%, 100% { transform: scaleX(1); }
1199
+ }
1200
+
1201
+ /* ---- Doriath — the key turns, the mask dots unmask, the value
1202
+ wipes in, the mint countdown hairline runs out, and the entry
1203
+ auto-relocks. Base = revealed state (what static frames show). ---- */
1204
+
1205
+ .am .doriath { --am-dur: 10s; }
1206
+ .am .doriath .keyChip {
1207
+ width: 10px; height: 11px;
1208
+ clip-path: var(--hex-pointy-top);
1209
+ background: var(--c-lavender-500);
1210
+ flex-shrink: 0;
1211
+ }
1212
+ .am .doriath .maskDots { display: flex; gap: 2px; flex-shrink: 0; }
1213
+ .am .doriath .dot { width: 3px; height: 3px; border-radius: 50%; background: var(--c-cobalt-400); flex-shrink: 0; }
1214
+ .am .doriath .vaultCard { background: var(--c-cobalt-900); border-color: var(--c-cobalt-900); }
1215
+ .am .doriath .vHead { display: flex; align-items: center; gap: 5px; }
1216
+ .am .doriath .keyHex {
1217
+ width: 12px; height: 14px;
1218
+ clip-path: var(--hex-pointy-top);
1219
+ background: var(--c-lavender-300);
1220
+ flex-shrink: 0;
1221
+ animation: amDorKey var(--am-dur) ease-in-out infinite;
1222
+ }
1223
+ .am .doriath .vTitle { height: 6px; width: 45%; background: var(--c-lavender-300); border-radius: 1px; }
1224
+ .am .doriath .vMeta { height: 3px; width: 60%; background: rgba(255, 255, 255, 0.25); border-radius: 1px; }
1225
+ .am .doriath .vMetaShort { height: 3px; width: 50%; background: rgba(255, 255, 255, 0.25); border-radius: 1px; }
1226
+ .am .doriath .vSecret { position: relative; height: 10px; }
1227
+ .am .doriath .vMask {
1228
+ position: absolute;
1229
+ inset: 0;
1230
+ display: flex;
1231
+ align-items: center;
1232
+ gap: 2px;
1233
+ opacity: 0;
1234
+ animation: amDorMask var(--am-dur) linear infinite both;
1235
+ }
1236
+ .am .doriath .vMask .dot { background: rgba(255, 255, 255, 0.45); }
1237
+ .am .doriath .vValue {
1238
+ position: absolute;
1239
+ inset: 0 15% 0 0;
1240
+ background: rgba(255, 255, 255, 0.9);
1241
+ border-radius: 2px;
1242
+ transform-origin: left center;
1243
+ animation: amDorValue var(--am-dur) linear infinite both;
1244
+ }
1245
+ .am .doriath .vCountdown {
1246
+ height: 2px;
1247
+ background: var(--c-mint-500);
1248
+ border-radius: 1px;
1249
+ transform-origin: left center;
1250
+ animation: amDorCount var(--am-dur) linear infinite both;
1251
+ }
1252
+
1253
+ @keyframes amDorKey {
1254
+ 0% { transform: rotate(-35deg); }
1255
+ 10%, 82% { transform: rotate(0deg); }
1256
+ 90%, 100% { transform: rotate(-35deg); }
1257
+ }
1258
+ @keyframes amDorMask {
1259
+ 0%, 14% { opacity: 1; }
1260
+ 20%, 82% { opacity: 0; }
1261
+ 88%, 100% { opacity: 1; }
1262
+ }
1263
+ @keyframes amDorValue {
1264
+ 0%, 16% { opacity: 0; transform: scaleX(0); }
1265
+ 26%, 80% { opacity: 1; transform: scaleX(1); }
1266
+ 86%, 100% { opacity: 0; transform: scaleX(1); }
1267
+ }
1268
+ @keyframes amDorCount {
1269
+ 0%, 24% { opacity: 0; transform: scaleX(1); }
1270
+ 27% { opacity: 1; transform: scaleX(1); }
1271
+ 76% { opacity: 1; transform: scaleX(0.02); }
1272
+ 80%, 100% { opacity: 0; transform: scaleX(0.02); }
1273
+ }
1274
+
1275
+ /* ---- OpenCatalogi — a query types into the federated search bar,
1276
+ the grid dims, the three matches snap back and their pills tick.
1277
+ Base = filtered end state (non-matches dimmed, query present). ---- */
1278
+
1279
+ .am .opencatalogi { --am-dur: 8s; }
1280
+ .am .opencatalogi .col > .head {
1281
+ display: flex;
1282
+ align-items: center;
1283
+ justify-content: space-between;
1284
+ gap: 6px;
1285
+ }
1286
+ .am .opencatalogi .search {
1287
+ flex: 1;
1288
+ max-width: 38%;
1289
+ height: 14px;
1290
+ display: flex;
1291
+ align-items: center;
1292
+ gap: 3px;
1293
+ padding: 0 5px;
1294
+ background: white;
1295
+ border: 1px solid var(--c-cobalt-200);
1296
+ border-radius: 999px;
1297
+ animation: amOcFocus var(--am-dur) linear infinite;
1298
+ }
1299
+ .am .opencatalogi .search .sIco { width: 6px; height: 6px; border-radius: 50%; border: 1px solid var(--c-cobalt-400); flex-shrink: 0; }
1300
+ .am .opencatalogi .search .q {
1301
+ height: 3px;
1302
+ width: 55%;
1303
+ background: var(--c-cobalt-700);
1304
+ border-radius: 1px;
1305
+ transform-origin: left center;
1306
+ animation: amOcQuery var(--am-dur) linear infinite both;
1307
+ }
1308
+ .am .opencatalogi .card.dim { opacity: 0.38; animation: amOcDim var(--am-dur) linear infinite both; }
1309
+ .am .opencatalogi .card.match { animation: amOcMatch var(--am-dur) ease-in-out infinite; }
1310
+ .am .opencatalogi .card.match .statusPill .h { animation: amOcPill var(--am-dur) ease-in-out infinite; }
1311
+
1312
+ @keyframes amOcFocus {
1313
+ 0%, 2% { border-color: var(--c-cobalt-200); box-shadow: 0 0 0 0 rgba(31, 68, 156, 0); }
1314
+ 5%, 20% { border-color: var(--c-blue-cobalt); box-shadow: 0 0 0 2px var(--c-cobalt-100); }
1315
+ 24%, 100% { border-color: var(--c-cobalt-200); box-shadow: 0 0 0 0 rgba(31, 68, 156, 0); }
1316
+ }
1317
+ @keyframes amOcQuery {
1318
+ 0%, 4% { transform: scaleX(0); opacity: 1; }
1319
+ 18%, 93% { transform: scaleX(1); opacity: 1; }
1320
+ 98% { transform: scaleX(1); opacity: 0; }
1321
+ 100% { transform: scaleX(0); opacity: 0; }
1322
+ }
1323
+ @keyframes amOcDim {
1324
+ 0%, 20% { opacity: 1; }
1325
+ 30%, 90% { opacity: 0.38; }
1326
+ 97%, 100% { opacity: 1; }
1327
+ }
1328
+ @keyframes amOcMatch {
1329
+ 0%, 26% { transform: scale(1); }
1330
+ 32% { transform: scale(1.04); }
1331
+ 38%, 100% { transform: scale(1); }
1332
+ }
1333
+ @keyframes amOcPill {
1334
+ 0%, 32% { transform: scale(1); }
1335
+ 38% { transform: scale(1.5); }
1336
+ 44%, 100% { transform: scale(1); }
1337
+ }
1338
+
1339
+ /* ---- OpenConnector — a record dot travels the pipeline: lavender
1340
+ leg source → connector, forest leg connector → target (the mapping
1341
+ made visible), then the new run row inserts and ticks mint.
1342
+ Base = completed end state (run row present, tick mint). ---- */
1343
+
1344
+ .am .openconnector { --am-dur: 7s; }
1345
+ .am .openconnector .stage .arrow { overflow: visible; }
1346
+ .am .openconnector .travelDotA,
1347
+ .am .openconnector .travelDotB {
1348
+ position: absolute;
1349
+ top: 50%;
1350
+ left: 0;
1351
+ width: 6px; height: 6px;
1352
+ margin-top: -3px;
1353
+ border-radius: 50%;
1354
+ opacity: 0;
1355
+ pointer-events: none;
1356
+ }
1357
+ .am .openconnector .travelDotA { background: var(--c-lavender-500); animation: amOxDotA var(--am-dur) linear infinite both; }
1358
+ .am .openconnector .travelDotB { background: var(--c-forest-500); animation: amOxDotB var(--am-dur) linear infinite both; }
1359
+ .am .openconnector .stage .conn { animation: amOxConn var(--am-dur) ease-in-out infinite; }
1360
+
1361
+ @keyframes amOxDotA {
1362
+ 0%, 5% { left: 0%; opacity: 0; }
1363
+ 8% { left: 4%; opacity: 1; }
1364
+ 24% { left: 92%; opacity: 1; }
1365
+ 27%, 100% { left: 100%; opacity: 0; }
1366
+ }
1367
+ @keyframes amOxDotB {
1368
+ 0%, 30% { left: 0%; opacity: 0; }
1369
+ 33% { left: 6%; opacity: 1; }
1370
+ 47% { left: 92%; opacity: 1; }
1371
+ 50%, 100% { left: 100%; opacity: 0; }
1372
+ }
1373
+ @keyframes amOxConn {
1374
+ 0%, 24% { transform: scale(1); }
1375
+ 28% { transform: scale(1.05); }
1376
+ 32%, 100% { transform: scale(1); }
1377
+ }
1378
+
1379
+ .am .openconnector .newRun { animation: amOxRun var(--am-dur) ease-out infinite both; }
1380
+ @keyframes amOxRun {
1381
+ 0%, 52% { opacity: 0; transform: translateY(-5px); }
1382
+ 58%, 93% { opacity: 1; transform: none; }
1383
+ 98%, 100% { opacity: 0; transform: none; }
1384
+ }
1385
+ .am .openconnector .newRun .runTick {
1386
+ width: 10px; height: 11px;
1387
+ clip-path: var(--hex-pointy-top);
1388
+ background: var(--c-mint-500);
1389
+ flex-shrink: 0;
1390
+ animation: amOxTick var(--am-dur) ease-in-out infinite both;
1391
+ }
1392
+ @keyframes amOxTick {
1393
+ 0%, 58% { opacity: 0; transform: scale(0.5); }
1394
+ 63% { opacity: 1; transform: scale(1.3); }
1395
+ 67%, 93% { opacity: 1; transform: scale(1); }
1396
+ 98%, 100% { opacity: 0; transform: scale(1); }
1397
+ }
1398
+
1399
+ /* ---- Procest — the case advances one stage. Ghost hexes overlaid
1400
+ on steps 2+3 replay the before-state (step 2 orange-active, step 3
1401
+ to-do) and fade to reveal the advanced base; the advanced case's
1402
+ row re-sorts to the top of the list. Base = advanced end state. ---- */
1403
+
1404
+ .am .procest { --am-dur: 7s; }
1405
+ .am .procest .timeline .step .ghost {
1406
+ position: absolute;
1407
+ top: 0;
1408
+ left: 50%;
1409
+ margin-left: -9px;
1410
+ width: 18px; height: 21px;
1411
+ clip-path: var(--hex-pointy-top);
1412
+ opacity: 0;
1413
+ pointer-events: none;
1414
+ animation: amPcGhost var(--am-dur) linear infinite both;
1415
+ }
1416
+ .am .procest .timeline .step .ghost.ghostNow { background: var(--c-orange-knvb); }
1417
+ .am .procest .timeline .step .ghost.ghostTodo { background: var(--c-cobalt-100); }
1418
+ @keyframes amPcGhost {
1419
+ 0%, 30% { opacity: 1; }
1420
+ 40%, 92% { opacity: 0; }
1421
+ 97%, 100% { opacity: 1; }
1422
+ }
1423
+ .am .procest .stack .sortUp { animation: amPcSortUp var(--am-dur) ease-in-out infinite both; }
1424
+ .am .procest .stack .sortDown { animation: amPcSortDown var(--am-dur) ease-in-out infinite both; }
1425
+ @keyframes amPcSortUp {
1426
+ 0% { opacity: 0; transform: translateY(28px); }
1427
+ 4%, 48% { opacity: 1; transform: translateY(28px); }
1428
+ 60%, 92% { opacity: 1; transform: none; }
1429
+ 97% { opacity: 0; transform: none; }
1430
+ 100% { opacity: 0; transform: translateY(28px); }
1431
+ }
1432
+ @keyframes amPcSortDown {
1433
+ 0% { opacity: 0; transform: translateY(-28px); }
1434
+ 4%, 48% { opacity: 1; transform: translateY(-28px); }
1435
+ 60%, 92% { opacity: 1; transform: none; }
1436
+ 97% { opacity: 0; transform: none; }
1437
+ 100% { opacity: 0; transform: translateY(-28px); }
1438
+ }
1439
+
1440
+ /* ---- OpenRegister — a new object row lands in the "Objects by
1441
+ Register" table, the first KPI widens, the right-rail statistics
1442
+ repaint in a stagger. Base = landed end state. ---- */
1443
+
1444
+ .am .openregister { --am-dur: 7s; }
1445
+ .am .openregister .newObj { animation: amOrLand var(--am-dur) ease-out infinite both; }
1446
+ @keyframes amOrLand {
1447
+ 0%, 44% { opacity: 0; transform: translateY(-5px); }
1448
+ 51%, 93% { opacity: 1; transform: none; }
1449
+ 98%, 100% { opacity: 0; transform: none; }
1450
+ }
1451
+ .am .openregister .detail > .row { animation: amOrRail var(--am-dur) linear infinite; }
1452
+ .am .openregister .detail > .row:nth-child(2) { animation-delay: calc(var(--am-dur) * 0.015); }
1453
+ .am .openregister .detail > .row:nth-child(3) { animation-delay: calc(var(--am-dur) * 0.03); }
1454
+ .am .openregister .detail > .row:nth-child(4) { animation-delay: calc(var(--am-dur) * 0.045); }
1455
+ .am .openregister .detail > .row:nth-child(6) { animation-delay: calc(var(--am-dur) * 0.06); }
1456
+ .am .openregister .detail > .row:nth-child(7) { animation-delay: calc(var(--am-dur) * 0.075); }
1457
+ .am .openregister .detail > .row:nth-child(8) { animation-delay: calc(var(--am-dur) * 0.09); }
1458
+ .am .openregister .detail > .row:nth-child(9) { animation-delay: calc(var(--am-dur) * 0.105); }
1459
+ .am .openregister .detail > .row:nth-child(10) { animation-delay: calc(var(--am-dur) * 0.12); }
1460
+ .am .openregister .detail > .row:nth-child(11) { animation-delay: calc(var(--am-dur) * 0.135); }
1461
+ .am .openregister .detail > .row:nth-child(12) { animation-delay: calc(var(--am-dur) * 0.15); }
1462
+ @keyframes amOrRail {
1463
+ 0%, 56% { opacity: 1; }
1464
+ 60% { opacity: 0.25; }
1465
+ 66%, 100% { opacity: 1; }
1466
+ }
1467
+
1468
+ /* Shared KPI-widen pulse — the .kpiGrow cell's number stretches as a
1469
+ count absorbs the new arrival (OpenRegister, OpenBuild, Shillinq). */
1470
+ .am .kpiGrow .num {
1471
+ transform-origin: left center;
1472
+ animation: amKpiGrow var(--am-dur) ease-in-out infinite;
1473
+ }
1474
+ @keyframes amKpiGrow {
1475
+ 0%, 50% { transform: scaleX(1); }
1476
+ 58%, 88% { transform: scaleX(1.25); }
1477
+ 96%, 100% { transform: scaleX(1); }
1478
+ }
1479
+
1480
+ /* ======================================================================
1481
+ Wave 4 — content reworks, animated
1482
+ ====================================================================== */
1483
+
1484
+ /* ---- DeciDesk — the vote tally fills, the "for" bar crosses the
1485
+ quorum line (which ticks mint), and the decision pill flips
1486
+ pending → adopted. Base = adopted end state. ---- */
1487
+
1488
+ .am .decidesk { --am-dur: 8s; }
1489
+ .am .decidesk .tallyRow { display: flex; align-items: center; gap: 6px; }
1490
+ .am .decidesk .tallyRow .tLabel { width: 22px; height: 3px; background: var(--c-cobalt-400); border-radius: 1px; flex-shrink: 0; }
1491
+ .am .decidesk .tallyRow .track {
1492
+ flex: 1;
1493
+ height: 6px;
1494
+ background: var(--c-cobalt-100);
1495
+ border-radius: 2px;
1496
+ position: relative;
1497
+ }
1498
+ .am .decidesk .tallyRow .fill {
1499
+ height: 6px;
1500
+ border-radius: 2px;
1501
+ transform-origin: left center;
1502
+ animation: amDkFill var(--am-dur) cubic-bezier(0.2, 0.7, 0.3, 1) infinite both;
1503
+ }
1504
+ .am .decidesk .tallyRow.for .fill { background: var(--c-mint-500); }
1505
+ .am .decidesk .tallyRow.against .fill { background: var(--c-cobalt-400); animation-delay: calc(var(--am-dur) * 0.04); }
1506
+ .am .decidesk .tallyRow.abstain .fill { background: var(--c-cobalt-200); animation-delay: calc(var(--am-dur) * 0.08); }
1507
+ @keyframes amDkFill {
1508
+ 0%, 8% { transform: scaleX(0); opacity: 1; }
1509
+ 30%, 93% { transform: scaleX(1); opacity: 1; }
1510
+ 98% { transform: scaleX(1); opacity: 0; }
1511
+ 100% { transform: scaleX(0); opacity: 0; }
1512
+ }
1513
+ .am .decidesk .tallyRow .quorum {
1514
+ position: absolute;
1515
+ left: 55%;
1516
+ top: -2px;
1517
+ width: 2px;
1518
+ height: 10px;
1519
+ border-radius: 1px;
1520
+ background: var(--c-mint-500);
1521
+ animation: amDkQuorum var(--am-dur) linear infinite both;
1522
+ }
1523
+ @keyframes amDkQuorum {
1524
+ 0%, 22% { background: var(--c-cobalt-400); transform: scaleY(1); }
1525
+ 26% { background: var(--c-mint-500); transform: scaleY(1.4); }
1526
+ 30%, 93% { background: var(--c-mint-500); transform: scaleY(1); }
1527
+ 98%, 100% { background: var(--c-cobalt-400); transform: scaleY(1); }
1528
+ }
1529
+ .am .decidesk .decisionRow .dIco {
1530
+ width: 11px; height: 13px;
1531
+ clip-path: var(--hex-pointy-top);
1532
+ background: var(--c-lavender-300);
1533
+ flex-shrink: 0;
1534
+ }
1535
+ /* Pending → adopted flip. The pill rides the shared beta (coral +
1536
+ orange) styling transiently as the pending phase, landing mint. */
1537
+ .am .decidesk .adoptFlip { animation: amDkPill var(--am-dur) linear infinite both; }
1538
+ .am .decidesk .adoptFlip .h { animation: amDkPillH var(--am-dur) linear infinite both; }
1539
+ .am .decidesk .adoptFlip .t { animation: amDkPillT var(--am-dur) linear infinite both; }
1540
+ @keyframes amDkPill {
1541
+ 0% { background: var(--c-coral-300); opacity: 0; }
1542
+ 6%, 38% { background: var(--c-coral-300); opacity: 1; }
1543
+ 44%, 92% { background: var(--c-mint-300); opacity: 1; }
1544
+ 98% { background: var(--c-mint-300); opacity: 0; }
1545
+ 100% { background: var(--c-coral-300); opacity: 0; }
1546
+ }
1547
+ @keyframes amDkPillH {
1548
+ 0%, 38% { background: var(--c-orange-knvb); transform: scale(1); }
1549
+ 44% { background: var(--c-mint-500); transform: scale(1.4); }
1550
+ 50%, 100% { background: var(--c-mint-500); transform: scale(1); }
1551
+ }
1552
+ @keyframes amDkPillT {
1553
+ 0%, 38% { background: var(--c-coral-500); }
1554
+ 44%, 100% { background: var(--c-mint-500); }
1555
+ }
1556
+
1557
+ /* ---- HRMQ — the week's hour bars fill, the sheet is submitted, the
1558
+ approval pip ticks mint, and the payroll counter widens.
1559
+ Base = approved end state. ---- */
1560
+
1561
+ .am .hrmq { --am-dur: 8s; }
1562
+ .am .hrmq .week {
1563
+ flex-shrink: 0;
1564
+ height: 72px;
1565
+ display: flex;
1566
+ align-items: stretch;
1567
+ gap: 6px;
1568
+ padding: 2px 4px 0;
1569
+ }
1570
+ .am .hrmq .dayCol {
1571
+ flex: 1;
1572
+ display: flex;
1573
+ flex-direction: column;
1574
+ align-items: center;
1575
+ justify-content: flex-end;
1576
+ gap: 3px;
1577
+ }
1578
+ .am .hrmq .dayBar {
1579
+ width: 70%;
1580
+ background: var(--c-mint-300);
1581
+ border-radius: 2px 2px 0 0;
1582
+ transform-origin: bottom center;
1583
+ animation: amHrBar var(--am-dur) cubic-bezier(0.2, 0.7, 0.3, 1) infinite both;
1584
+ }
1585
+ .am .hrmq .dayCol:nth-child(2) .dayBar { animation-delay: calc(var(--am-dur) * 0.03); }
1586
+ .am .hrmq .dayCol:nth-child(3) .dayBar { animation-delay: calc(var(--am-dur) * 0.06); }
1587
+ .am .hrmq .dayCol:nth-child(4) .dayBar { animation-delay: calc(var(--am-dur) * 0.09); }
1588
+ .am .hrmq .dayCol:nth-child(5) .dayBar { animation-delay: calc(var(--am-dur) * 0.12); }
1589
+ @keyframes amHrBar {
1590
+ 0%, 4% { transform: scaleY(0); opacity: 1; }
1591
+ 22%, 92% { transform: scaleY(1); opacity: 1; }
1592
+ 97% { transform: scaleY(1); opacity: 0; }
1593
+ 100% { transform: scaleY(0); opacity: 0; }
1594
+ }
1595
+ .am .hrmq .dayLabel { width: 60%; height: 2px; background: var(--c-cobalt-200); border-radius: 1px; }
1596
+ .am .hrmq .sheetFoot { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
1597
+ .am .hrmq .sheetSum { width: 30%; height: 5px; background: var(--c-cobalt-700); border-radius: 1px; }
1598
+ /* The submit button lives outside an .actions row, so it carries its
1599
+ own button paint. */
1600
+ .am .hrmq .submitBtn {
1601
+ width: 44px;
1602
+ height: 14px;
1603
+ border-radius: 3px;
1604
+ background: var(--c-blue-cobalt);
1605
+ animation: amHrSubmit var(--am-dur) ease-in-out infinite;
1606
+ }
1607
+ @keyframes amHrSubmit {
1608
+ 0%, 38% { transform: scale(1); }
1609
+ 41% { transform: scale(0.9); }
1610
+ 44%, 100% { transform: scale(1); }
1611
+ }
1612
+ .am .hrmq .approvePip,
1613
+ .am .hrmq .donePip {
1614
+ width: 8px; height: 8px;
1615
+ border-radius: 50%;
1616
+ background: var(--c-mint-500);
1617
+ flex-shrink: 0;
1618
+ }
1619
+ .am .hrmq .donePip { background: var(--c-mint-300); }
1620
+ .am .hrmq .approvePip { animation: amHrApprove var(--am-dur) linear infinite both; }
1621
+ @keyframes amHrApprove {
1622
+ 0%, 50% { background: var(--c-cobalt-200); transform: scale(1); }
1623
+ 55% { background: var(--c-mint-500); transform: scale(1.4); }
1624
+ 60%, 93% { background: var(--c-mint-500); transform: scale(1); }
1625
+ 98%, 100% { background: var(--c-cobalt-200); transform: scale(1); }
1626
+ }
1627
+ .am .hrmq .payroll {
1628
+ display: flex;
1629
+ flex-direction: column;
1630
+ gap: 3px;
1631
+ padding-top: 5px;
1632
+ border-top: 1px solid var(--c-cobalt-100);
1633
+ }
1634
+ .am .hrmq .payroll .pLabel { width: 40%; height: 3px; background: var(--c-cobalt-400); border-radius: 1px; }
1635
+ .am .hrmq .payroll .pNum {
1636
+ width: 34%; height: 8px;
1637
+ background: var(--c-cobalt-900);
1638
+ border-radius: 1px;
1639
+ transform-origin: left center;
1640
+ animation: amHrPay var(--am-dur) ease-in-out infinite;
1641
+ }
1642
+ @keyframes amHrPay {
1643
+ 0%, 62% { transform: scaleX(1); }
1644
+ 70%, 90% { transform: scaleX(1.3); }
1645
+ 97%, 100% { transform: scaleX(1); }
1646
+ }
1647
+
1648
+ /* ---- LarpingApp — the XP ripple: the second character card lifts,
1649
+ an XP hex token rises to the timeline's active stage, the stage
1650
+ absorbs it with a pulse, and every card's text rows grow in a
1651
+ stagger. Base = settled (post-XP) end state. ---- */
1652
+
1653
+ .am .larping { --am-dur: 8s; }
1654
+ .am .larping .col { position: relative; }
1655
+ .am .larping .card.xpSource { animation: amLrpLift var(--am-dur) ease-in-out infinite; }
1656
+ @keyframes amLrpLift {
1657
+ 0%, 4% { transform: none; box-shadow: none; }
1658
+ 10%, 26% { transform: translateY(-3px); box-shadow: 0 6px 14px -6px rgba(0, 0, 0, 0.25); }
1659
+ 34%, 100% { transform: none; box-shadow: none; }
1660
+ }
1661
+ .am .larping .xpToken {
1662
+ position: absolute;
1663
+ left: 48%;
1664
+ top: 52%;
1665
+ width: 10px; height: 11px;
1666
+ clip-path: var(--hex-pointy-top);
1667
+ background: var(--c-mint-500);
1668
+ opacity: 0;
1669
+ pointer-events: none;
1670
+ animation: amLrpToken var(--am-dur) ease-in-out infinite both;
1671
+ }
1672
+ @keyframes amLrpToken {
1673
+ 0%, 10% { left: 48%; top: 52%; opacity: 0; transform: scale(0.6); }
1674
+ 14% { left: 48%; top: 48%; opacity: 1; transform: scale(1); }
1675
+ 34% { left: 31%; top: 9%; opacity: 1; transform: scale(1); }
1676
+ 38%, 100% { left: 31%; top: 7%; opacity: 0; transform: scale(0.4); }
1677
+ }
1678
+ .am .larping .timeline .step.now .h { animation: amLrpStage var(--am-dur) ease-in-out infinite; }
1679
+ @keyframes amLrpStage {
1680
+ 0%, 34% { transform: scale(1); }
1681
+ 39% { transform: scale(1.25); }
1682
+ 44%, 100% { transform: scale(1); }
1683
+ }
1684
+ .am .larping .card .row {
1685
+ transform-origin: left center;
1686
+ animation: amLrpRow var(--am-dur) ease-in-out infinite;
1687
+ }
1688
+ .am .larping .card:nth-child(2) .row { animation-delay: calc(var(--am-dur) * 0.02); }
1689
+ .am .larping .card:nth-child(3) .row { animation-delay: calc(var(--am-dur) * 0.04); }
1690
+ .am .larping .card:nth-child(4) .row { animation-delay: calc(var(--am-dur) * 0.06); }
1691
+ .am .larping .card:nth-child(5) .row { animation-delay: calc(var(--am-dur) * 0.08); }
1692
+ .am .larping .card:nth-child(6) .row { animation-delay: calc(var(--am-dur) * 0.1); }
1693
+ @keyframes amLrpRow {
1694
+ 0%, 46% { transform: scaleX(0.82); }
1695
+ 58%, 100% { transform: scaleX(1); }
1696
+ }
1697
+
1698
+ /* ---- SoftwareCatalog — the CVE scan: a band sweeps down the app
1699
+ list, row 4's pip flips red as it passes, and the CVE chart bar
1700
+ surges in vermillion (red family — the chart keeps its single
1701
+ KNVB-orange accent). Base = post-scan end state. ---- */
1702
+
1703
+ .am .swc { --am-dur: 8s; }
1704
+ .am .swc .scanPanel { position: relative; overflow: hidden; }
1705
+ .am .swc .scanBand {
1706
+ position: absolute;
1707
+ left: 0;
1708
+ right: 0;
1709
+ top: 0;
1710
+ height: 12px;
1711
+ background: linear-gradient(180deg, transparent 0%, var(--c-cobalt-100) 50%, transparent 100%);
1712
+ opacity: 0;
1713
+ pointer-events: none;
1714
+ animation: amSwcScan var(--am-dur) linear infinite both;
1715
+ }
1716
+ @keyframes amSwcScan {
1717
+ 0%, 6% { transform: translateY(-12px); opacity: 0; }
1718
+ 10% { transform: translateY(0); opacity: 0.9; }
1719
+ 44% { transform: translateY(88px); opacity: 0.9; }
1720
+ 50%, 100% { transform: translateY(100px); opacity: 0; }
1721
+ }
1722
+ .am .swc .item.cveHit .pip { animation: amSwcPip var(--am-dur) linear infinite both; }
1723
+ @keyframes amSwcPip {
1724
+ 0%, 28% { background: var(--c-cobalt-200); transform: scale(1); }
1725
+ 33% { background: var(--c-red-vermillion); transform: scale(1.4); }
1726
+ 38%, 93% { background: var(--c-red-vermillion); transform: scale(1); }
1727
+ 98%, 100% { background: var(--c-cobalt-200); transform: scale(1); }
1728
+ }
1729
+ .am .swc .bar.cve {
1730
+ background: var(--c-red-vermillion);
1731
+ transform-origin: bottom center;
1732
+ animation: amSwcBar var(--am-dur) ease-in-out infinite both;
1733
+ }
1734
+ @keyframes amSwcBar {
1735
+ 0%, 36% { transform: scaleY(0.45); }
1736
+ 48% { transform: scaleY(1.08); }
1737
+ 54%, 93% { transform: scaleY(1); }
1738
+ 98%, 100% { transform: scaleY(0.45); }
1739
+ }
1740
+
1741
+ /* ---- ZaakAfhandelApp — a citizen submission travels up into the
1742
+ werkvoorraad and gains its stage hex + assignee avatar; the late
1743
+ row's red pip pulses once as the SLA reminder. Base = assigned
1744
+ end state. ---- */
1745
+
1746
+ .am .zaak { --am-dur: 8s; }
1747
+ .am .zaak .col { position: relative; }
1748
+ .am .zaak .zkGhost {
1749
+ position: absolute;
1750
+ left: 28%;
1751
+ top: 76%;
1752
+ width: 40%;
1753
+ display: flex;
1754
+ align-items: center;
1755
+ gap: 4px;
1756
+ padding: 3px 4px;
1757
+ background: white;
1758
+ border: 1px solid var(--c-cobalt-200);
1759
+ border-radius: 2px;
1760
+ opacity: 0;
1761
+ pointer-events: none;
1762
+ animation: amZkGhost var(--am-dur) ease-in-out infinite both;
1763
+ }
1764
+ .am .zaak .zkGhost .src { width: 14px; height: 3px; background: var(--c-cobalt-400); border-radius: 1px; flex-shrink: 0; }
1765
+ .am .zaak .zkGhost .gBar { flex: 1; height: 3px; background: var(--c-cobalt-700); border-radius: 1px; }
1766
+ @keyframes amZkGhost {
1767
+ 0%, 8% { top: 76%; opacity: 0; }
1768
+ 13% { top: 74%; opacity: 1; }
1769
+ 36% { top: 27%; opacity: 1; }
1770
+ 42%, 100% { top: 25%; opacity: 0; }
1771
+ }
1772
+ .am .zaak .zkNew .stage { animation: amZkStage var(--am-dur) linear infinite both; }
1773
+ @keyframes amZkStage {
1774
+ 0%, 42% { background: var(--c-cobalt-100); transform: scale(1); }
1775
+ 47% { background: var(--c-lavender-300); transform: scale(1.3); }
1776
+ 52%, 100% { background: var(--c-lavender-300); transform: scale(1); }
1777
+ }
1778
+ .am .zaak .zkNew .av { animation: amZkAv var(--am-dur) linear infinite both; }
1779
+ @keyframes amZkAv {
1780
+ 0%, 44% { opacity: 0.25; }
1781
+ 52%, 100% { opacity: 1; }
1782
+ }
1783
+ .am .zaak .zkNew .l1 {
1784
+ transform-origin: left center;
1785
+ animation: amZkLine var(--am-dur) ease-out infinite both;
1786
+ }
1787
+ @keyframes amZkLine {
1788
+ 0%, 40% { transform: scaleX(0.55); }
1789
+ 52%, 100% { transform: scaleX(1); }
1790
+ }
1791
+ .am .zaak .zkSent { animation: amZkSent var(--am-dur) linear infinite; }
1792
+ @keyframes amZkSent {
1793
+ 0%, 10% { opacity: 1; }
1794
+ 16%, 40% { opacity: 0.35; }
1795
+ 50%, 100% { opacity: 1; }
1796
+ }
1797
+ .am .zaak .item.late .stage { animation: amZkLate var(--am-dur) ease-in-out infinite; }
1798
+ @keyframes amZkLate {
1799
+ 0%, 60% { transform: scale(1); }
1800
+ 64% { transform: scale(1.35); }
1801
+ 68%, 100% { transform: scale(1); }
1802
+ }
1803
+
1804
+ /* ---- Hermiq — the conversation plays: the user asks, the typing
1805
+ indicator blinks, the agent answers, the tool chips light L→R,
1806
+ the approval chip (the variant's single orange while pending)
1807
+ ticks mint, the tool result lands, the user follows up.
1808
+ Base = approved end state (all chips lit, approval mint). ---- */
1809
+
1810
+ .am .hermiq { --am-dur: 10s; }
1811
+ .am .hermiq .nav .item .ico.round { border-radius: 50%; }
1812
+ .am .hermiq .convo { flex: 1; gap: 8px; justify-content: flex-end; }
1813
+ .am .hermiq .bubble { flex-shrink: 0; }
1814
+ .am .hermiq .bubble.user {
1815
+ align-self: flex-end;
1816
+ width: 42%;
1817
+ height: 12px;
1818
+ border-radius: 8px 2px 8px 8px;
1819
+ background: var(--c-workspaceblue-300);
1820
+ }
1821
+ .am .hermiq .bubble.user.narrow { width: 34%; }
1822
+ .am .hermiq .bubble.agent {
1823
+ align-self: flex-start;
1824
+ width: 58%;
1825
+ height: 18px;
1826
+ border-radius: 2px 8px 8px 8px;
1827
+ background: var(--c-cobalt-50);
1828
+ border: 1px solid var(--c-cobalt-100);
1829
+ }
1830
+ .am .hermiq .bubble.agent.tall { width: 64%; height: 24px; }
1831
+ .am .hermiq .typing {
1832
+ align-self: flex-start;
1833
+ display: flex;
1834
+ align-items: center;
1835
+ gap: 2px;
1836
+ padding: 3px 6px;
1837
+ background: var(--c-cobalt-50);
1838
+ border: 1px solid var(--c-cobalt-100);
1839
+ border-radius: 2px 8px 8px 8px;
1840
+ opacity: 0;
1841
+ animation: amHqTyping var(--am-dur) linear infinite both;
1842
+ }
1843
+ .am .hermiq .typing .tDot {
1844
+ width: 3px; height: 3px;
1845
+ border-radius: 50%;
1846
+ background: var(--c-cobalt-400);
1847
+ animation: amHqDot 0.9s ease-in-out infinite;
1848
+ }
1849
+ .am .hermiq .typing .tDot:nth-child(2) { animation-delay: 0.2s; }
1850
+ .am .hermiq .typing .tDot:nth-child(3) { animation-delay: 0.4s; }
1851
+ @keyframes amHqTyping {
1852
+ 0%, 7% { opacity: 0; }
1853
+ 10%, 20% { opacity: 1; }
1854
+ 23%, 100% { opacity: 0; }
1855
+ }
1856
+ @keyframes amHqDot {
1857
+ 0%, 100% { opacity: 0.35; transform: translateY(0); }
1858
+ 50% { opacity: 1; transform: translateY(-1px); }
1859
+ }
1860
+ .am .hermiq .chips { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
1861
+ .am .hermiq .chip { width: 34px; height: 9px; border-radius: 999px; background: var(--c-cobalt-300); }
1862
+ .am .hermiq .chip.chip3 { width: 26px; }
1863
+ .am .hermiq .bubble.turn1 { animation: amHqTurn1 var(--am-dur) ease-out infinite both; }
1864
+ .am .hermiq .bubble.turn2 { animation: amHqTurn2 var(--am-dur) ease-out infinite both; }
1865
+ .am .hermiq .bubble.turn3 { animation: amHqTurn3 var(--am-dur) ease-out infinite both; }
1866
+ .am .hermiq .bubble.turn4 { animation: amHqTurn4 var(--am-dur) ease-out infinite both; }
1867
+ @keyframes amHqTurn1 {
1868
+ 0%, 2% { opacity: 0; transform: translateY(4px); }
1869
+ 6%, 93% { opacity: 1; transform: none; }
1870
+ 98%, 100% { opacity: 0; transform: none; }
1871
+ }
1872
+ @keyframes amHqTurn2 {
1873
+ 0%, 22% { opacity: 0; transform: translateY(4px); }
1874
+ 27%, 93% { opacity: 1; transform: none; }
1875
+ 98%, 100% { opacity: 0; transform: none; }
1876
+ }
1877
+ @keyframes amHqTurn3 {
1878
+ 0%, 62% { opacity: 0; transform: translateY(4px); }
1879
+ 68%, 93% { opacity: 1; transform: none; }
1880
+ 98%, 100% { opacity: 0; transform: none; }
1881
+ }
1882
+ @keyframes amHqTurn4 {
1883
+ 0%, 74% { opacity: 0; transform: translateY(4px); }
1884
+ 79%, 93% { opacity: 1; transform: none; }
1885
+ 98%, 100% { opacity: 0; transform: none; }
1886
+ }
1887
+ .am .hermiq .chips .chip1 { animation: amHqChip1 var(--am-dur) ease-out infinite both; }
1888
+ @keyframes amHqChip1 {
1889
+ 0%, 30% { opacity: 0; transform: scale(0.7); }
1890
+ 34%, 93% { opacity: 1; transform: scale(1); }
1891
+ 98%, 100% { opacity: 0; transform: scale(1); }
1892
+ }
1893
+ .am .hermiq .chip.chip2 { animation: amHqChip2 var(--am-dur) linear infinite both; }
1894
+ @keyframes amHqChip2 {
1895
+ 0%, 36% { background: var(--c-cobalt-100); }
1896
+ 40%, 93% { background: var(--c-cobalt-300); }
1897
+ 98%, 100% { background: var(--c-cobalt-100); }
1898
+ }
1899
+ .am .hermiq .chip.chip3 { animation: amHqChip3 var(--am-dur) linear infinite both; }
1900
+ @keyframes amHqChip3 {
1901
+ 0%, 42% { background: var(--c-cobalt-100); }
1902
+ 46%, 93% { background: var(--c-cobalt-300); }
1903
+ 98%, 100% { background: var(--c-cobalt-100); }
1904
+ }
1905
+ /* Approval chip — appears orange (pending, via the shared beta pill
1906
+ tokens), holds for the human moment, ticks mint on approval. */
1907
+ .am .hermiq .approveChip { animation: amHqAppr var(--am-dur) linear infinite both; }
1908
+ .am .hermiq .approveChip .h { animation: amHqApprH var(--am-dur) linear infinite both; }
1909
+ .am .hermiq .approveChip .t { animation: amHqApprT var(--am-dur) linear infinite both; }
1910
+ @keyframes amHqAppr {
1911
+ 0%, 46% { background: var(--c-coral-300); opacity: 0; }
1912
+ 50%, 58% { background: var(--c-coral-300); opacity: 1; }
1913
+ 62%, 93% { background: var(--c-mint-300); opacity: 1; }
1914
+ 98% { background: var(--c-mint-300); opacity: 0; }
1915
+ 100% { background: var(--c-coral-300); opacity: 0; }
1916
+ }
1917
+ @keyframes amHqApprH {
1918
+ 0%, 58% { background: var(--c-orange-knvb); transform: scale(1); }
1919
+ 62% { background: var(--c-mint-500); transform: scale(1.4); }
1920
+ 67%, 100% { background: var(--c-mint-500); transform: scale(1); }
1921
+ }
1922
+ @keyframes amHqApprT {
1923
+ 0%, 58% { background: var(--c-coral-500); }
1924
+ 62%, 100% { background: var(--c-mint-500); }
1925
+ }
1926
+ .am .hermiq .promptRow { align-items: center; }
1927
+ .am .hermiq .promptField {
1928
+ flex: 1;
1929
+ height: 16px;
1930
+ background: white;
1931
+ border: 1px solid var(--c-cobalt-200);
1932
+ border-radius: 8px;
1933
+ }
1934
+ .am .hermiq .sendBtn { width: 28px; animation: amHqSend var(--am-dur) ease-in-out infinite; }
1935
+ @keyframes amHqSend {
1936
+ 0% { transform: scale(1); }
1937
+ 1.5% { transform: scale(0.88); }
1938
+ 4%, 100% { transform: scale(1); }
1939
+ }
1940
+
1941
+ /* ---- OpenBuild — the top template row highlights, a ghost chip
1942
+ travels into the virtual-apps list, the new app row lands, the
1943
+ first KPI widens, the published KPI's hex pulses mint.
1944
+ Base = published end state. ---- */
1945
+
1946
+ .am .openbuild { --am-dur: 8s; }
1947
+ .am .openbuild .col { position: relative; }
1948
+ .am .openbuild .col .kpiRow { display: flex; gap: 6px; }
1949
+ .am .openbuild .col .panelRow { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; flex: 1; min-height: 0; }
1950
+ .am .openbuild .tplSource { animation: amObTpl var(--am-dur) linear infinite; }
1951
+ @keyframes amObTpl {
1952
+ 0%, 6% { background: transparent; }
1953
+ 10%, 22% { background: var(--c-cobalt-50); }
1954
+ 28%, 100% { background: transparent; }
1955
+ }
1956
+ .am .openbuild .buildGhost {
1957
+ position: absolute;
1958
+ left: 58%;
1959
+ top: 42%;
1960
+ width: 26px;
1961
+ height: 8px;
1962
+ border-radius: 2px;
1963
+ background: var(--c-lavender-300);
1964
+ opacity: 0;
1965
+ pointer-events: none;
1966
+ animation: amObGhost var(--am-dur) ease-in-out infinite both;
1967
+ }
1968
+ @keyframes amObGhost {
1969
+ 0%, 14% { left: 58%; top: 42%; opacity: 0; }
1970
+ 18% { left: 56%; top: 42%; opacity: 1; }
1971
+ 38% { left: 10%; top: 38%; opacity: 1; }
1972
+ 44%, 100% { left: 8%; top: 38%; opacity: 0; }
1973
+ }
1974
+ .am .openbuild .newApp { animation: amObLand var(--am-dur) ease-out infinite both; }
1975
+ @keyframes amObLand {
1976
+ 0%, 42% { opacity: 0; transform: translateY(-5px); }
1977
+ 49%, 93% { opacity: 1; transform: none; }
1978
+ 98%, 100% { opacity: 0; transform: none; }
1979
+ }
1980
+ .am .openbuild .publishedKpi .ico { animation: amObPublish var(--am-dur) ease-in-out infinite; }
1981
+ @keyframes amObPublish {
1982
+ 0%, 64% { background: var(--c-forest-300); transform: scale(1); }
1983
+ 70% { background: var(--c-mint-500); transform: scale(1.25); }
1984
+ 76%, 84% { background: var(--c-mint-500); transform: scale(1); }
1985
+ 92%, 100% { background: var(--c-forest-300); transform: scale(1); }
1986
+ }
1987
+
1988
+ /* ======================================================================
1989
+ Wave 5 — WidgetMock list-refresh primitive, anonymise dropzone,
1990
+ SidebarMock open/underline/stagger
1991
+ ====================================================================== */
1992
+
1993
+ /* Shared list-refresh — WidgetMock puts `.wmLive` (this module) on
1994
+ its frame for every list-shaped variant. A fresh row slides in at
1995
+ the top, the bottom row clips out, and the unread badge bumps.
1996
+ Transforms + opacity only, so the tile's height never jumps. */
1997
+
1998
+ .am .wmLive { --am-dur: 7s; position: relative; }
1999
+ .am .wmLive .w .list > *:first-child {
2000
+ transform-origin: top center;
2001
+ animation: amWmNew var(--am-dur) ease-out infinite both;
2002
+ }
2003
+ @keyframes amWmNew {
2004
+ 0%, 8% { opacity: 0; transform: translateY(-6px) scaleY(0.5); }
2005
+ 16%, 90% { opacity: 1; transform: none; }
2006
+ 96%, 100% { opacity: 0; transform: translateY(-6px) scaleY(0.5); }
2007
+ }
2008
+ .am .wmLive .w .list > *:last-child {
2009
+ transform-origin: bottom center;
2010
+ animation: amWmOld var(--am-dur) ease-in infinite both;
2011
+ }
2012
+ @keyframes amWmOld {
2013
+ 0%, 16% { opacity: 1; transform: none; }
2014
+ 26%, 88% { opacity: 0; transform: translateY(4px) scaleY(0.4); }
2015
+ 94%, 100% { opacity: 1; transform: none; }
2016
+ }
2017
+ /* Unread badge — pinned to the tile's top-right; bumps as the fresh
2018
+ row lands. Mint on the cobalt-900 dashboard surface. */
2019
+ .am .wmBadge {
2020
+ position: absolute;
2021
+ top: 8px;
2022
+ right: 8px;
2023
+ width: 14px;
2024
+ height: 8px;
2025
+ border-radius: 999px;
2026
+ background: var(--c-mint-500);
2027
+ z-index: 1;
2028
+ animation: amWmBadge var(--am-dur) ease-in-out infinite;
2029
+ }
2030
+ @keyframes amWmBadge {
2031
+ 0%, 12% { transform: scale(1); }
2032
+ 17% { transform: scale(1.45); }
2033
+ 24%, 100% { transform: scale(1); }
2034
+ }
2035
+
2036
+ /* Anonymise dropzone — marching-ants dashes, a file hex drops in,
2037
+ the zone flashes mint as the redacted copy is confirmed. Applied
2038
+ by the docudesk-anonymise widget variant and the DocuDesk app
2039
+ mock's own drop-zone (`.zoneLive` on the .w-upload block). */
2040
+
2041
+ .am .zoneLive { --am-dur: 5s; }
2042
+ .am .zoneLive .zone {
2043
+ position: relative;
2044
+ overflow: hidden;
2045
+ border-style: solid;
2046
+ border-color: transparent;
2047
+ background-image:
2048
+ repeating-linear-gradient(90deg, var(--c-cobalt-300) 0 4px, transparent 4px 8px),
2049
+ repeating-linear-gradient(90deg, var(--c-cobalt-300) 0 4px, transparent 4px 8px),
2050
+ repeating-linear-gradient(0deg, var(--c-cobalt-300) 0 4px, transparent 4px 8px),
2051
+ repeating-linear-gradient(0deg, var(--c-cobalt-300) 0 4px, transparent 4px 8px);
2052
+ background-size: 100% 1px, 100% 1px, 1px 100%, 1px 100%;
2053
+ background-position: 0 0, 0 100%, 0 0, 100% 0;
2054
+ background-repeat: no-repeat;
2055
+ animation:
2056
+ amZoneAnts 0.9s linear infinite,
2057
+ amZoneFlash var(--am-dur) ease-in-out infinite;
2058
+ }
2059
+ @keyframes amZoneAnts {
2060
+ to { background-position: 8px 0, -8px 100%, 0 -8px, 100% 8px; }
2061
+ }
2062
+ @keyframes amZoneFlash {
2063
+ 0%, 52% { background-color: var(--c-cobalt-50); }
2064
+ 58%, 66% { background-color: var(--c-mint-300); }
2065
+ 74%, 100% { background-color: var(--c-cobalt-50); }
2066
+ }
2067
+ .am .zoneLive .zoneFile {
2068
+ position: absolute;
2069
+ left: 50%;
2070
+ top: 50%;
2071
+ width: 12px;
2072
+ height: 14px;
2073
+ margin: -7px 0 0 -6px;
2074
+ clip-path: var(--hex-pointy-top);
2075
+ background: var(--c-terracotta-300);
2076
+ opacity: 0;
2077
+ pointer-events: none;
2078
+ animation: amZoneFile var(--am-dur) ease-in infinite both;
2079
+ }
2080
+ @keyframes amZoneFile {
2081
+ 0%, 26% { opacity: 0; transform: translateY(-26px); }
2082
+ 32% { opacity: 1; transform: translateY(-20px); }
2083
+ 48% { opacity: 1; transform: translateY(0); }
2084
+ 56%, 100% { opacity: 0; transform: translateY(0); }
2085
+ }
2086
+
2087
+ /* SidebarMock — the panel slides in from the right, the head wipes,
2088
+ the active-tab underline travels in from the neighbouring tab
2089
+ (positioned by --sb-ix / --sb-n from the component), and the body
2090
+ rows land in a stagger. Base = opened, settled panel. */
2091
+
2092
+ .am .sbLive { --am-dur: 7s; animation: amSbPanel var(--am-dur) ease-out infinite both; }
2093
+ @keyframes amSbPanel {
2094
+ 0% { opacity: 0; transform: translateX(14px); }
2095
+ 7%, 94% { opacity: 1; transform: none; }
2096
+ 99%, 100% { opacity: 0; transform: translateX(14px); }
2097
+ }
2098
+ .am .sbLive .sb-head .title {
2099
+ transform-origin: left center;
2100
+ animation: amSbTitle var(--am-dur) ease-out infinite both;
2101
+ }
2102
+ @keyframes amSbTitle {
2103
+ 0%, 8% { transform: scaleX(0); }
2104
+ 16%, 100% { transform: scaleX(1); }
2105
+ }
2106
+ .am .sbLive .sb-head .desc {
2107
+ transform-origin: left center;
2108
+ animation: amSbDesc var(--am-dur) ease-out infinite both;
2109
+ }
2110
+ @keyframes amSbDesc {
2111
+ 0%, 12% { transform: scaleX(0); }
2112
+ 22%, 100% { transform: scaleX(1); }
2113
+ }
2114
+ .am .sbLive .sb-tabs { position: relative; }
2115
+ /* The travelling underline replaces the static active border. */
2116
+ .am .sbLive .sb-tab.active { border-bottom-color: transparent; }
2117
+ .am .sbLive .sb-underline {
2118
+ position: absolute;
2119
+ bottom: -1px;
2120
+ height: 2px;
2121
+ border-radius: 1px;
2122
+ background: var(--c-blue-cobalt);
2123
+ left: calc(10px + (100% - 20px) * var(--sb-ix, 1) / var(--sb-n, 4));
2124
+ width: calc((100% - 20px) / var(--sb-n, 4));
2125
+ animation: amSbUnderline var(--am-dur) cubic-bezier(0.2, 0.7, 0.3, 1) infinite both;
2126
+ }
2127
+ @keyframes amSbUnderline {
2128
+ 0%, 18% { transform: translateX(var(--sb-from, -100%)); }
2129
+ 30%, 100% { transform: translateX(0); }
2130
+ }
2131
+ .am .sbLive .sb-body > * { animation: amSbRow var(--am-dur) ease-out infinite both; }
2132
+ .am .sbLive .sb-body > *:nth-child(2) { animation-delay: calc(var(--am-dur) * 0.018); }
2133
+ .am .sbLive .sb-body > *:nth-child(3) { animation-delay: calc(var(--am-dur) * 0.036); }
2134
+ .am .sbLive .sb-body > *:nth-child(4) { animation-delay: calc(var(--am-dur) * 0.054); }
2135
+ .am .sbLive .sb-body > *:nth-child(5) { animation-delay: calc(var(--am-dur) * 0.072); }
2136
+ .am .sbLive .sb-body > *:nth-child(6) { animation-delay: calc(var(--am-dur) * 0.09); }
2137
+ .am .sbLive .sb-body > *:nth-child(7) { animation-delay: calc(var(--am-dur) * 0.108); }
2138
+ .am .sbLive .sb-body > *:nth-child(8) { animation-delay: calc(var(--am-dur) * 0.126); }
2139
+ .am .sbLive .sb-body > *:nth-child(9) { animation-delay: calc(var(--am-dur) * 0.144); }
2140
+ .am .sbLive .sb-body > *:nth-child(10) { animation-delay: calc(var(--am-dur) * 0.162); }
2141
+ @keyframes amSbRow {
2142
+ 0%, 20% { opacity: 0; transform: translateY(4px); }
2143
+ 28%, 100% { opacity: 1; transform: none; }
2144
+ }
2145
+
2146
+ /* ======================================================================
2147
+ Static frames — running={false} adds `.static` next to `.am .frame`;
2148
+ the media query below mirrors it for prefers-reduced-motion. Selectors
2149
+ repeat the animated ones with `.static` inserted so they always win
2150
+ on specificity. Base styles are the meaningful end state, so beyond
2151
+ `animation: none` only a few explicit overrides are needed.
2152
+ ====================================================================== */
2153
+
2154
+ .am .static .portaliq .field-1,
2155
+ .am .static .portaliq .field-2,
2156
+ .am .static .portaliq .field-3,
2157
+ .am .static .portaliq .field-1 .fieldFill,
2158
+ .am .static .portaliq .field-2 .fieldFill,
2159
+ .am .static .portaliq .field-3 .fieldFill,
2160
+ .am .static .portaliq .submit,
2161
+ .am .static .portaliq .confirmSweep,
2162
+ .am .static .portaliq .newItem,
2163
+ .am .static .nldesign .swatchSel,
2164
+ .am .static .nldesign .actions .btn:not(.ghost),
2165
+ .am .static .nldesign .statusPill:not(.beta),
2166
+ .am .static .nldesign .statusPill:not(.beta) .h,
2167
+ .am .static .nldesign .statusPill:not(.beta) .t,
2168
+ .am .static .nldesign .typeRow > *,
2169
+ .am .static .scholiq .progressFill,
2170
+ .am .static .scholiq .credChip,
2171
+ .am .static .lpWidgets .w,
2172
+ .am .static .lpTiles .w-subgrid,
2173
+ .am .static .lpTiles .w-subgrid .cell,
2174
+ .am .static .lpBi .w-graph-bar .bar,
2175
+ .am .static .lpBi .w-graph-line .stroke,
2176
+ .am .static .lpBi .w-graph-line .fill,
2177
+ .am .static .lpBi .w-graph-line .dot,
2178
+ .am .static .lpBi .donut,
2179
+ .am .static .lpBi .biDelta,
2180
+ .am .static .plq .dealGone,
2181
+ .am .static .plq .dealWon,
2182
+ .am .static .plq .kpiRow .kpi:first-child .num {
2183
+ animation: none;
2184
+ }
2185
+ .am .static .lpBi .w-graph-line .stroke { stroke-dasharray: none; stroke-dashoffset: 0; }
2186
+ .am .static .plq .dealGone { display: none; }
2187
+
2188
+ @media (prefers-reduced-motion: reduce) {
2189
+ .am .portaliq .field-1,
2190
+ .am .portaliq .field-2,
2191
+ .am .portaliq .field-3,
2192
+ .am .portaliq .field-1 .fieldFill,
2193
+ .am .portaliq .field-2 .fieldFill,
2194
+ .am .portaliq .field-3 .fieldFill,
2195
+ .am .portaliq .submit,
2196
+ .am .portaliq .confirmSweep,
2197
+ .am .portaliq .newItem,
2198
+ .am .nldesign .swatchSel,
2199
+ .am .nldesign .actions .btn:not(.ghost),
2200
+ .am .nldesign .statusPill:not(.beta),
2201
+ .am .nldesign .statusPill:not(.beta) .h,
2202
+ .am .nldesign .statusPill:not(.beta) .t,
2203
+ .am .nldesign .typeRow > *,
2204
+ .am .scholiq .progressFill,
2205
+ .am .scholiq .credChip,
2206
+ .am .lpWidgets .w,
2207
+ .am .lpTiles .w-subgrid,
2208
+ .am .lpTiles .w-subgrid .cell,
2209
+ .am .lpBi .w-graph-bar .bar,
2210
+ .am .lpBi .w-graph-line .stroke,
2211
+ .am .lpBi .w-graph-line .fill,
2212
+ .am .lpBi .w-graph-line .dot,
2213
+ .am .lpBi .donut,
2214
+ .am .lpBi .biDelta,
2215
+ .am .plq .dealGone,
2216
+ .am .plq .dealWon,
2217
+ .am .plq .kpiRow .kpi:first-child .num {
2218
+ animation: none;
2219
+ }
2220
+ .am .lpBi .w-graph-line .stroke { stroke-dasharray: none; stroke-dashoffset: 0; }
2221
+ .am .plq .dealGone { display: none; }
2222
+ }
2223
+
2224
+ /* ======================================================================
2225
+ Static frames — waves 2, 4 and 5. Same convention as the block
2226
+ above: `.static` on the frame (AppMock), on the WidgetMock frame
2227
+ (`.wmLive.static`), or on the SidebarMock panel (`.sbLive.static`)
2228
+ freezes every keyframe onto its base — the meaningful end state.
2229
+ Transient travellers (ghosts, dots, sweeps, the typing indicator)
2230
+ have `opacity: 0` bases, so they simply stay hidden.
2231
+ ====================================================================== */
2232
+
2233
+ .am .static .docudesk .word.mark-1,
2234
+ .am .static .docudesk .word.mark-2,
2235
+ .am .static .docudesk .word.mark-3,
2236
+ .am .static .docudesk .word.mark-4,
2237
+ .am .static .docudesk .word.mark-5,
2238
+ .am .static .shillinq .bankLine,
2239
+ .am .static .shillinq .inv.reconciling .tick,
2240
+ .am .static .shillinq .totNet,
2241
+ .am .static .doriath .keyHex,
2242
+ .am .static .doriath .vMask,
2243
+ .am .static .doriath .vValue,
2244
+ .am .static .doriath .vCountdown,
2245
+ .am .static .opencatalogi .search,
2246
+ .am .static .opencatalogi .search .q,
2247
+ .am .static .opencatalogi .card.dim,
2248
+ .am .static .opencatalogi .card.match,
2249
+ .am .static .opencatalogi .card.match .statusPill .h,
2250
+ .am .static .openconnector .travelDotA,
2251
+ .am .static .openconnector .travelDotB,
2252
+ .am .static .openconnector .stage .conn,
2253
+ .am .static .openconnector .newRun,
2254
+ .am .static .openconnector .newRun .runTick,
2255
+ .am .static .procest .timeline .step .ghost,
2256
+ .am .static .procest .stack .sortUp,
2257
+ .am .static .procest .stack .sortDown,
2258
+ .am .static .openregister .newObj,
2259
+ .am .static .openregister .detail > .row,
2260
+ .am .static .kpiGrow .num,
2261
+ .am .static .decidesk .tallyRow .fill,
2262
+ .am .static .decidesk .tallyRow .quorum,
2263
+ .am .static .decidesk .adoptFlip,
2264
+ .am .static .decidesk .adoptFlip .h,
2265
+ .am .static .decidesk .adoptFlip .t,
2266
+ .am .static .hrmq .dayBar,
2267
+ .am .static .hrmq .submitBtn,
2268
+ .am .static .hrmq .approvePip,
2269
+ .am .static .hrmq .payroll .pNum,
2270
+ .am .static .larping .card.xpSource,
2271
+ .am .static .larping .xpToken,
2272
+ .am .static .larping .timeline .step.now .h,
2273
+ .am .static .larping .card .row,
2274
+ .am .static .swc .scanBand,
2275
+ .am .static .swc .item.cveHit .pip,
2276
+ .am .static .swc .bar.cve,
2277
+ .am .static .zaak .zkGhost,
2278
+ .am .static .zaak .zkNew .stage,
2279
+ .am .static .zaak .zkNew .av,
2280
+ .am .static .zaak .zkNew .l1,
2281
+ .am .static .zaak .zkSent,
2282
+ .am .static .zaak .item.late .stage,
2283
+ .am .static .hermiq .bubble,
2284
+ .am .static .hermiq .typing,
2285
+ .am .static .hermiq .typing .tDot,
2286
+ .am .static .hermiq .chips .chip1,
2287
+ .am .static .hermiq .chip.chip2,
2288
+ .am .static .hermiq .chip.chip3,
2289
+ .am .static .hermiq .approveChip,
2290
+ .am .static .hermiq .approveChip .h,
2291
+ .am .static .hermiq .approveChip .t,
2292
+ .am .static .hermiq .sendBtn,
2293
+ .am .static .openbuild .tplSource,
2294
+ .am .static .openbuild .buildGhost,
2295
+ .am .static .openbuild .newApp,
2296
+ .am .static .openbuild .publishedKpi .ico,
2297
+ .am .wmLive.static .w .list > *:first-child,
2298
+ .am .wmLive.static .w .list > *:last-child,
2299
+ .am .wmLive.static .wmBadge,
2300
+ .am .static .wmBadge,
2301
+ .am .static .zoneLive .zone,
2302
+ .am .zoneLive.static .zone,
2303
+ .am .static .zoneLive .zoneFile,
2304
+ .am .zoneLive.static .zoneFile,
2305
+ .am .sbLive.static,
2306
+ .am .static .sbLive,
2307
+ .am .sbLive.static .sb-head .title,
2308
+ .am .static .sbLive .sb-head .title,
2309
+ .am .sbLive.static .sb-head .desc,
2310
+ .am .static .sbLive .sb-head .desc,
2311
+ .am .sbLive.static .sb-underline,
2312
+ .am .static .sbLive .sb-underline,
2313
+ .am .sbLive.static .sb-body > *,
2314
+ .am .static .sbLive .sb-body > * {
2315
+ animation: none;
2316
+ }
2317
+ .am .static .zoneLive .zone,
2318
+ .am .zoneLive.static .zone {
2319
+ border: 1px dashed var(--c-cobalt-300);
2320
+ background-image: none;
2321
+ }
2322
+
2323
+ @media (prefers-reduced-motion: reduce) {
2324
+ .am .docudesk .word.mark-1,
2325
+ .am .docudesk .word.mark-2,
2326
+ .am .docudesk .word.mark-3,
2327
+ .am .docudesk .word.mark-4,
2328
+ .am .docudesk .word.mark-5,
2329
+ .am .shillinq .bankLine,
2330
+ .am .shillinq .inv.reconciling .tick,
2331
+ .am .shillinq .totNet,
2332
+ .am .doriath .keyHex,
2333
+ .am .doriath .vMask,
2334
+ .am .doriath .vValue,
2335
+ .am .doriath .vCountdown,
2336
+ .am .opencatalogi .search,
2337
+ .am .opencatalogi .search .q,
2338
+ .am .opencatalogi .card.dim,
2339
+ .am .opencatalogi .card.match,
2340
+ .am .opencatalogi .card.match .statusPill .h,
2341
+ .am .openconnector .travelDotA,
2342
+ .am .openconnector .travelDotB,
2343
+ .am .openconnector .stage .conn,
2344
+ .am .openconnector .newRun,
2345
+ .am .openconnector .newRun .runTick,
2346
+ .am .procest .timeline .step .ghost,
2347
+ .am .procest .stack .sortUp,
2348
+ .am .procest .stack .sortDown,
2349
+ .am .openregister .newObj,
2350
+ .am .openregister .detail > .row,
2351
+ .am .kpiGrow .num,
2352
+ .am .decidesk .tallyRow .fill,
2353
+ .am .decidesk .tallyRow .quorum,
2354
+ .am .decidesk .adoptFlip,
2355
+ .am .decidesk .adoptFlip .h,
2356
+ .am .decidesk .adoptFlip .t,
2357
+ .am .hrmq .dayBar,
2358
+ .am .hrmq .submitBtn,
2359
+ .am .hrmq .approvePip,
2360
+ .am .hrmq .payroll .pNum,
2361
+ .am .larping .card.xpSource,
2362
+ .am .larping .xpToken,
2363
+ .am .larping .timeline .step.now .h,
2364
+ .am .larping .card .row,
2365
+ .am .swc .scanBand,
2366
+ .am .swc .item.cveHit .pip,
2367
+ .am .swc .bar.cve,
2368
+ .am .zaak .zkGhost,
2369
+ .am .zaak .zkNew .stage,
2370
+ .am .zaak .zkNew .av,
2371
+ .am .zaak .zkNew .l1,
2372
+ .am .zaak .zkSent,
2373
+ .am .zaak .item.late .stage,
2374
+ .am .hermiq .bubble,
2375
+ .am .hermiq .typing,
2376
+ .am .hermiq .typing .tDot,
2377
+ .am .hermiq .chips .chip1,
2378
+ .am .hermiq .chip.chip2,
2379
+ .am .hermiq .chip.chip3,
2380
+ .am .hermiq .approveChip,
2381
+ .am .hermiq .approveChip .h,
2382
+ .am .hermiq .approveChip .t,
2383
+ .am .hermiq .sendBtn,
2384
+ .am .openbuild .tplSource,
2385
+ .am .openbuild .buildGhost,
2386
+ .am .openbuild .newApp,
2387
+ .am .openbuild .publishedKpi .ico,
2388
+ .am .wmLive .w .list > *:first-child,
2389
+ .am .wmLive .w .list > *:last-child,
2390
+ .am .wmBadge,
2391
+ .am .zoneLive .zone,
2392
+ .am .zoneLive .zoneFile,
2393
+ .am .sbLive,
2394
+ .am .sbLive .sb-head .title,
2395
+ .am .sbLive .sb-head .desc,
2396
+ .am .sbLive .sb-underline,
2397
+ .am .sbLive .sb-body > * {
2398
+ animation: none;
2399
+ }
2400
+ .am .zoneLive .zone {
2401
+ border: 1px dashed var(--c-cobalt-300);
2402
+ background-image: none;
2403
+ }
2404
+ }